Get variable value with a string in scheme - scheme

How can we get variable value with a string in scheme language as we can achieve this in Common Lisp:
> (defvar s 3)
> S
> (symbol-value (intern "S"))
> 3
I am accessing a parameter of parent function from the closure.
EDIT: I have found this solution, but I can't use eval because it evaluates at top level. Searching for alternatives.
(eval (string->symbol "s"))
EDIT 2: I have found that Common lisp code also try to find symbol in global space. So this question is basically for both Lisps(Common Lisp, Scheme).

Don't do that!
Variables are for when you know the variable at compile time. In that case it is never a string. You can still reason about strings in compile time but your code also needs to have a relation with the name for it to be interesting. When you use eval or other forms that evaluate structure and compile/run data in runtime you are probably not doing it right (but not always. I've in my 20 year career used eval intentionally in production code twice)
If you want to store values you use a data structure. An assoc would mimic a dynamic environment. You can also use a hash with a level indicator if the size is harmless.

You can't do what you want to do and in fact it is a confused thing to want to do.
Here's why what you are trying to do is confused. Consider how a Lisp system for which it was possible to do what you wanted would work. In particular consider something like this:
(define (foo a name)
(let ([b 10])
(display (get-value name))
(* a b)))
Where get-value is meant to be how you get the binding of whatever something is.
So, if I call (foo 10 "b") it should print 10 and return 100.
But wait: b is a compile-time constant in this code. Any compiler worth its salt is going to immediately turn this into
(define (foo a name)
(display (get-value name))
(* a 10))
And now there is no binding of b.
So there are two options here: what you want to work works and it is impossible to ever write a reasonable compiler for Scheme, or what you want to work doesn't work, and it is.

Related

More macro woes

I am still having some troubles with this concept. The key paragraph in the r7rs standard is:
"Identifiers that appear in the template but are not pattern
variables or the identifier ellipsis are inserted into the output as literal identifiers. If a literal identifier is inserted as a
free identifier then it refers to the binding of that identifier
within whose scope the instance of syntax-rules appears.
If a literal identifier is inserted as a bound identifier then
it is in effect renamed to prevent inadvertent captures of
free identifiers."
By "bound identifier" am I right that it means any argument to a lambda, a top-level define or a syntax definition ie. define-syntax, let-syntax or let-rec-syntax? (I think I could handle internal defines with a trick at compile time converting them to lambdas.)
By "free identifier" does it mean any other identifier that presumably is defined beforehand with a "bound identifier" expression?
I wonder about the output of code like this:
(define x 42)
(define-syntax double syntax-rules ()
((_) ((lambda () (+ x x)))))
(set! x 3)
(double)
Should the result be 84 or 6?
What about this:
(define x 42)
(define-syntax double syntax-rules ()
((_) ((lambda () (+ x x)))))
(define (proc)
(define x 3)
(double))
(proc)
Am I right to suppose that since define-syntax occurs at top-level, all its free references refer to top-level variables that may or may not exist at the point of definition. So to avoid collisions with local variables at the point of use, we should rename the outputted free reference, say append a '%' to the name (and disallow the user to create symbols with % in them). As well as duplicate the reference to the top-level variable, this time with the % added.
If a macro is defined in some form of nested scope (with let-syntax or let-rec-syntax) this is even trickier if it refers to scoped variables. When there is a use of the macro it will have to expand these references to their form at point of definition of the macro rather than point of use. So I'm guessing the best way is expand it naturally and scan the result for lambdas, if it finds one, rename its arguments at point of definition, as the r7rs suggests. But what about references internal to this lambda, should we change these as well? This seems obvious but was not explicitly stated in the standard.
Also I'm still not sure whether it is best to have a separate expansion phase separate from the compiler, or to interweave expanding macros with compiling code.
Thanks, and excuse me if I've missed something obviously, relatively new to this.
Steve
In your first example, properly written:
(define x 42)
(define-syntax double
(syntax-rules ()
( (_) ((lambda () (+ x x))) ) ))
(set! x 3)
(double)
the only possibility is 6 as there is only one variable called x.
In your second example, properly written:
(define x 42)
(define-syntax double
(syntax-rules ()
((_) ((lambda () (+ x x))) )))
(define (proc)
(define x 3)
(double))
(proc)
the hygienic nature of the Scheme macro system prevents capture of the unrelated local x, so the result is 84.
In general, identifiers (like your x) within syntax-rules refer to what they lexically refer to (the global x in your case). And that binding will be preserved because of hygiene. Because of hygiene you do not have to worry about unintended capture.
Thanks, I think I understand... I still wonder how in certain advanced circumstances hygiene is achieved, eg. the following:
(define (myproc x)
(let-syntax ((double (syntax-rules ()
((double) (+ x x)))))
((lambda (x) (double)) 3)))
(myproc 42)
The site comes up with 84 rather than 6. I wonder how this (correct) referential transparency is achieved just by renaming. The transformer output does not bind new variables, yet still when it expands on line 4, we have to find a way to get to the desired x rather than the most recent.
The best way I can think of is simply rename every time a lambda argument or definition shadows another, ie. keep appending %1, %2 etc... macro outputs will have their exact versions named (eg. x%1) while references to identifiers simply have their unadorned name x and the correct variable is found at compile time.
Thanks, I hope for any clarification.
Steve

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.

What is the semantic difference between defining a name with and without parentheses?

(Though this is indeed simple question, I find sometimes it is common mistakes that I made when writing Scheme program as a beginner.)
I encountered some confusion about the define special form. A situation is like below:
(define num1
2)
(define (num2)
2)
I find it occurs quite often that I call num2 without the parentheses and program fails. I usually end up spending hours to find the cause.
By reading the r5rs, I realized that definition without parenthesis, e.g. num1, is a variable; while definition with parenthesis, e.g. num2, is a function without formal parameters.
However, I am still blurred about the difference between a "variable" and "function".
From a emacs lisp background, I can only relate above difference to similar idea as in emacs lisp:
In Emacs Lisp, a symbol can have a value attached to it just as it can
have a function definition attached to it.
[here]
Question: Is this a correct way of understanding the difference between enclosed and non-enclosed definitions in scheme?
There is no difference between a value and a function in Scheme. A function is just a value that can be used in a particular way - it can be called (as opposed to other kinds of value, such as numbers, which cannot be called, but can be e.g. added, which a function cannot).
The parentheses are just a syntactic shortcut - they're a faster, more readable (to experts) way of writing out the definition of the name as a variable containing a function:
(define (num)
2)
;is exactly the same as
(define num
(lambda () 2) )
The second of these should make it more visually obvious that the value being assigned to num is not a number.
If you wanted the function to take arguments, they would either go within the parentheses (after num, e.g. (num x y) in the first form, or within lambda's parentheses (e.g. (lambda (x y)... in the second.
Most tutorials for the total beginner actually don't introduce the first form for several exercises, in order to drive home the point that it isn't separate and doesn't really provide any true functionality on its own. It's just a shorthand to reduce the amount of repetition in your program's text.
In Scheme, all functions are values; variables hold any one value.
In Scheme, unlike Common Lisp and Emacs Lisp, there are no different namespaces for functions and other values. So the statement you quoted is not true for Scheme. In Scheme a symbol is associated with at most one value and that value may or may not be a function.
As to the difference between a non-function value and a nullary function returning that value: In your example the only difference is that, as you know, num2 must be applied to get the numeric value and num1 does not have to be and in fact can't be applied.
In general the difference between (define foo bar) and (define (foo) bar) is that the former evaluated bar right now and foo then refers to the value that bar has been evaluated to, whereas in the latter case bar is evaluated each time that (foo) is used. So if the expression foo is costly to calculate, that cost is paid when (and each time) you call the function, not at the definition. And, perhaps more importantly, if the expression has side effects (like, for example, printing something) those effects happen each time the function is called. Side effects are the primary reason you'd define a function without parameters.
Even though #sepp2k has answered the question, I will make it more clearer with example:
1 ]=> (define foo1 (display 23))
23
;Value: foo1
1 ]=> foo1
;Unspecified return value
Notice in the first one, foo1 is evaluated on the spot (hence it prints) and evaluated value is assigned to name foo1. It doesn't evaluate again and again
1 ]=> (define (foo2) (display 23))
;Value: foo2
1 ]=> foo2
;Value 11: #[compound-procedure 11 foo2]
1 ]=> (foo2)
23
;Unspecified return value
Just foo2 will return another procedure (which is (display 23)). Doing (foo2) actually evaluates it. And each time on being called, it re-evaluates again
1 ]=> (foo1)
;The object #!unspecific is not applicable.
foo1 is a name that refers a value. So Applying foo1 doesn't make sense as in this case that value is not a procedure.
So I hope things are clearer. In short, in your former case it is a name that refers to value returned by evaluating expression. In latter case, each time it is evaluated.

Why can't I define an "or-function" in scheme?

I have found this question about the special function "or" in scheme:
Joe Hacker states loudly that there is no reason or in Scheme needs to be special -- it can just be defined by the programmer, like this:
(define (or x y)
(if x
#t
y))
Is Joe right?
I can't figure out why it shouldn't be possible to do that.
Could some scheme-expert please explain if this works, and if no: why not?
It's because this version of or evaluates all of its arguments (since it's a function), while the standard Scheme or (which is not a function but special syntax) doesn't. Try running (or #t (exit)) at the Scheme REPL and then try the same with your or function.
The behavior of the standard or is sometimes called short-circuited: it evaluates only those arguments that it needs to. This is very common for the binary boolean operator (or and and) across programming languages. The fact that or looks like a function call is a feature of Scheme/Lisp syntax, but looks deceive.
Whether it works or not depends on what you want it to do. It certainly works in the sense that for two given boolean values it will return the expected resulted. However it will not be functionally equivalent to regular or because it does not short-circuit, i.e. given your definition (or #t (/ 0 0)) will cause an error because you're dividing 0 by 0 while using regular or it would just return #t and not try to evaluate (/ 0 0) at all.

In Scheme the purpose of (let ((cdr cdr))

I've been studying Scheme recently and come across a function that is defined in the following way:
(define remove!
(let ((null? null?)
(cdr cdr)
(eq? eq?))
(lambda ... function that uses null?, cdr, eq? ...)
What is the purpose of binding null? to null? or cdr to cdr, when these are built in functions that are available in a function definition without a let block?
In plain R5RS Scheme, there is no module system -- only the toplevel. Furthermore, the mentality is that everything can be modified, so you can "customize" the language any way you want. But without a module system this does not work well. For example, I write
(define (sub1 x) (- x 1))
in a library which you load -- and now you can redefine -:
(define - +) ; either this
(set! - +) ; or this
and now you unintentionally broke my library which relied on sub1 decrementing its input by one, and as a result your windows go up when you drag them down, or whatever.
The only way around this, which is used by several libraries, is to "grab" the relevant definition of the subtraction function, before someone can modify it:
(define sub1 (let ((- -)) (lambda (x) (- x 1))))
Now things will work "more fine", since you cannot modify the meaning of my sub1 function by changing -. (Except... if you modify it before you load my library...)
Anyway, as a result of this (and if you know that the - is the original one when the library is loaded), some compilers will detect this and see that the - call is always going to be the actual subtraction function, and therefore they will inline calls to it (and inlining a call to - can eventually result in assembly code for subtracting two numbers, so this is a big speed boost). But like I said in the above comment, this is more coincidental to the actual reason above.
Finally, R6RS (and several scheme implementations before that) has fixed this and added a library system, so there's no use for this trick: the sub1 code is safe as long as other code in its library is not redefining - in some way, and the compiler can safely optimize code based on this. No need for clever tricks.
That's a speed optimization. Local variable access is usually faster than global variables.

Resources