How to obtain my function definition in MIT Scheme? - scheme

In JavaScript, I can retrieve the "source code" definition of a function, for example:
​function alert_Hi() {
alert("Hi");
}
alert(alert_Hi);
will return exactly what I typed. http://jsfiddle.net/DuCqJ/
How can I do this in MIT Scheme?
I remember seeing something that returns #compound-procedure or something, but what I really want is the "source code".

You might try pp
(define (display-hi) (display "Hi"))
(pp display-hi) =>
(named-lambda (display-hi)
(display "Hi"))
MIT-Scheme debugging aids

JavaScript is fully interpreted, so it has full function definitions lying around even after you've defined them. Scheme is not actually fully interpreted; it compiles functions (and a few other constructs, I think) down to a non-readable representation and throws away the initial code.
You could probably get it to store the initial textual representation of a function at runtime using some macro tricks, but I'm inclined to believe that this would be more trouble than it's worth.
If you don't mind me asking, why do you need the textual representation of a defined function at runtime?

Related

How to determine if a variable exists in Chicken Scheme?

Is there a way in Chicken Scheme to determine at run-time if a variable is currently defined?
(let ((var 1))
(print (is-defined? var)) ; #t
(print (is-defined? var)) ; #f
EDIT: XY problem.
I'm writing a macro that generates code. This generated code must call the macro in mutual recursion - having the macro simply call itself won't work. When the macro is recursively called, I need it to behave differently than when it is called initially. I would use a nested function, but uh....it's a macro.
Rough example:
(defmacro m (nested)
(if nested
BACKQUOTE(print "is nested")
BACKQUOTE(m #t)
(yes, I know scheme doesn't use defmacro, but I'm coming from Common Lisp. Also I can't seem to put backquotes in here without it all going to hell.)
I don't want the INITIAL call of the macro to take an extra argument that only has meaning when called recursively. I want it to know by some other means.
Can I get the generated code to call a macro that is nested within the first macro and doesn't exist at the call site, maybe? For example, generating code that calls (,other-macro) instead of (macro)?
But that shouldn't work, because a macro isn't a first-class object like a function is...
When you write recursive macros I get the impression that you have an macro expansion (m a b ...) that turns into a (m-helper a (b ...)) that might turn into (let (a ...) (m b ...)). That is not directly recursive since you are turning code into code that just happens to contain a macro.
With destructuring-bind you really only need to keep track of two variables. One for car and one for cdr and with an implicit renaming macro the stuff not coming from the form is renamed and thus hygenic:
(define-syntax destructuring-bind
(ir-macro-transformer
(lambda (form inject compare?)
(define (parse-structure structure expression optional? body)
;;actual magic happens here. Returns list structure with a mix of parts from structure as well as introduced variables and globals
)
(match form
[(structure expression) . body ]
`(let ((tmp ,expression))
,(parse-structure structure 'tmp #f body))))))
To check if something from input is the same symbol you use the supplied compare? procedure. eg. (compare? expression '&optional).
There's no way to do that in general, because Scheme is lexically scoped. It doesn't make much sense to ask if a variable is defined if an referencing an undefined variable is an error.
For toplevel/global variables, you can use the symbol-utils egg but it is probably not going to work as you expect, considering that global variables inside modules are also rewritten to be something else.
Perhaps if you can say what you're really trying to do, I can help you with an alternate solution.

Scheme let syntax error

(define (rec base height)
(let ((product (* base height))(half 0.5))
(let ((sum (* product half)))
(display "Area is")
(display sum))))
let: expected only one expression after the name-defining sequence, but found one extra part in: (display sum)
I am having the error as above, I don't know which part goes wrong
In full Scheme, this is allowed. However, you are probably using one of the teaching variants of Scheme (such as Intermediate Student or Advanced Student) that Racket provides, which disallows functions with more than one expression.
I'd say you can work around it by using begin, but Intermediate Student doesn't provide begin either (Advanced Student appears to, which helps). If you're using Intermediate Student, I guess you're just not meant to use multiple expressions, and that's that. :-)
The beginning and intermediate student languages really aren't a good fit for programs that use I/O. If your teacher is assigning problems that require you to use one of these languages and also require you to print something out, that would be a somewhat inappropriate assignment.
For the record, I certainly make mistakes like this myself....

How to capture the return value of `string-search-forward` in Scheme?

I want to write a procedure (function) that checks if a string contains another string. I read the documentation of string library from http://sicp.ai.mit.edu/Fall-2004/manuals/scheme-7.5.5/doc/scheme_7.html
According from to them,
Pattern must be a string. Searches
string for the rightmost occurrence of
the substring pattern. If successful,
the index to the right of the last
character of the matched substring is
returned; otherwise, #f is returned.
This seemed odd to me, cause the return value is either integer or boolean, so what should I compare my return value with?
I tried
(define (case-one str)
(if (= #f (string-search-forward "me" str))
#t
#f))
DrScheme don't like it,
expand: unbound identifier in module in: string-search-forward
Thanks,
string-search-forward is not a standardized Scheme procedure; it is an extension peculiar to the MIT-Scheme implementation (that's why your link goes to the "MIT Scheme Reference Manual.") To see only those procedures that are guaranteed, look at the R5RS document.
In Scheme, #f is the only value that means "false," anything else when used in a conditional expression will mean "true." There is therefore no point in "comparing" it to anything. In cases like string-search-forward that returns mixed types, you usually capture the return value in a variable to test it, then use it if it's non-false:
(let ((result (string-search-forward "me" str)))
(if result
(munge result) ; Execute when S-S-F is successful (result is the index.)
(error "hurf") ; Execute when S-S-F fails (result has the value #f.)
))
A more advanced tactic is to use cond with a => clause which is in a sense a shorthand for the above:
(cond ((string-search-forward "me" str) => munge)
(else (error "hurf")))
Such a form (<test> => <expression>) means that if <test> is a true value, then <expression> is evaluated, which has to be a one-argument procedure; this procedure is called with the value of <test> as an argument.
Scheme has a very small standard library, which is both a blessing (you can make small scheme implementations to embed in an application or device, you can learn the language quickly) and a curse (it's missing a lot of useful functions). string-search-forward is a non-standard function of MIT Scheme, it's not present in DrScheme.
Many library additions are available in the form of SRFIs. An SRFI is a community-adopted extension to the base language — think of it as an optional part of a Scheme implementation. DrScheme (or at least its successor Racket) implements many SRFIs.
DrScheme has a number of string functions as part of SRFI 13. Amongst the string searching functions, there is string-contains, which is similar except that it takes its arguments in the opposite order.
(require srfi/13)
(define (case-one str)
(integer? (string-contains str "me")))
You'll notice that the two implementations used a different argument order (indicating that they were developed independently), yet use the same return value. This illustrates that it's quite natural in Scheme to have a function return different types depending on what it's conveying. In particular, it's fairly common to have a function return a useful piece of information if it can do its job, or #f if it can't do its job. That way, the function naturally combines doing its job (here, returning the index of the substring) with checking whether the job is doable (here, testing whether the substring occurs).
Error message seems a little odd (I don't have drscheme installed unfortunately so can't investigate too much).
Are you sure str is a string?
Additionally = is for integer comparisons only, you can use false? instead.
As for the return value of string-search-forward having mixed types, scheme has the mindset that if any useful value can be returned it should be returned, so this means different return types are common for functions.
Try using srfi-13's string-index: http://docs.racket-lang.org/srfi-std/srfi-13.html#Searching The documentation you are looking at isn't specifically for PLT. and probably corresponds to some other version of Scheme.

Specifics of call/cc

This is related to What is call/cc?, but I didn't want to hijack this question for my own purposes, and some of its arguments like the analogy to setjmp/longjmp evade me.
I think I have a sufficient idea about what a continuation is, I think of it as a snapshot of the current call stack. I don't want to go into the discussion why this might be interesting or what you can do with continuations. My question is more specifically, why do I have to provide a function argument to call/cc? Why doesn't call/cc just return the current continuation, so I could do whatever I please with it (store it, call it, you name it)? In a link from this other question (http://community.schemewiki.org/?call-with-current-continuation-for-C-programmers), it talks about "Essentially it's just a clean way to get the continuation to you and keep out of the way of subsequent jumps back to the saved point.", but I'm not getting it. It seems unnecessarily complicated.
If you use a construct like Jay shows, then you can grab the continuation, but in a way, the value that is grabbed is already spoiled because you're already inside that continuation. In contrast, call/cc can be used to grab the continuation that is still pending outside of the current expression. For example, one of the simplest uses of continuations is to implement a kind of an abort:
(call/cc (lambda (abort)
(+ 1 2 (abort 9))))
You cannot do that with the operation you describe. If you try it:
(define (get-cc) (call/cc values))
(let ([abort (get-cc)]) (+ 1 2 (abort 9)))
then you get an error about applying 9 as a procedure. This happens because abort jumps back to the let with the new value of 9 -- which means that you're now doing a second round of the same addition expression, except that now abort is bound to 9...
Two additional related notes:
For a nice an practical introduction to continuations, see PLAI.
call/cc is a little complex in that it takes in a function -- a conceptually easier to use construct is let/cc which you can find in some implementations like PLT Scheme. The above example becomes (let/cc abort (+ 1 2 (abort 9))).
That would be less versatile. If you want that behavior, you can just do:
(call/cc (lambda (x) x))
You could take a look at the example usages of continuations in "Darrell Ferguson and Dwight Deugo. "Call with Current Continuation Patterns". 8th Conference on Pattern Languages of Programs. September 2001." (http://library.readscheme.org/page6.html) and try to rewrite them using a call/cc-return, defined as above.
I suggest starting by asking yourself: what does it mean to be a first-class continuation?
The continuation of an expression essentially consists of two pieces of data: first, the closure (i.e., environment) of that expression; and second, a representation of what should be done with the result of the expression. A language with first-class continuations, then, is one which has data structures encapsulating these parts, and which treats these data structures just as it would any other.
call/cc is a particularly elegant way to realise this idea: the current continuation is packaged up as a procedure which encapsulates what-is-to-be-done-with-the-expression as what the procedure does when applied to the expression; to represent the continuation this way simply means that the closure of this procedure contains the environment at the site it was invoked.
You could imagine realising the idea of first-class continuations in other ways. They wouldn't be call/cc, and it's hard for me to imagine how such a representation could be simpler.
On a parting note, consider the implementation of let/cc that Eli mentioned, which I prefer to call bind/cc:
(define-syntax bind/cc
(syntax-rules ()
((bind/cc var . body)
(call/cc (lambda (var) . body)))))
And as an exercise, how would you implement call/cc based on bind/cc?
Against common SO netiquette I'm answering my own question, but more as the editor than the provider of the answer.
After a while I started a similar question over at LtU. After all, these are the guys that ponder language design all day long, aren't they, and one of the answers finally kicked in with me. Now things mentioned here, e.g. by Eli or in the original question, make much more sense to me. It's all about what gets included in the continuation, and where the applied continuation sets in.
One of the posters at LtU wrote:
"You can see exactly how call/cc allows you to "keep out of the way." With em or get/cc you need to do some kind of test to determine if you have a back-jump or just the initial call. Basically, call/cc keeps the use of the continuation out of the continuation, whereas with get/cc or em, the continuation contains its use and so (usually) you need to add a test to the beginning of the continuation (i.e. immediately following get/cc / em) to separate the "using the continuation parts" from the "rest of the continuation" parts."
That drove it home for me.
Thank you guys anyway!

looking up the text of a procedure in scheme

The ipython python shell has a wonderful feature, whereby you can type:
foo??
and see the text of function foo.
Does scheme (in particular, MIT scheme), have anything like this?
I want to be able to say
(define (foo x) (* x x))
and later view (or even operate on) the list (* x x).
Is there a way to do this?
Not by default in any Scheme I know. What you can do is define a macro that does what "define" does and in addition stores the body of the function in a hash table or an alist or whatever. That will only work on code that you control, of course.
There's no reliable, portable way to do this.
The general structure of a Scheme function is (define (<name> <arg1> <arg2> ... ) <expr1> <expr2> ... <exprn>). Extending Mark Probst's suggestion, you could define a macro that defines a quoted version of the function, which you could then apply cddr to to get a list of the function's expressions.

Resources