How do I dereference a scheme symbol? - scheme

Old C/C++ programmer, and I'm just starting to learn/play with scheme so my wording may not be correct but...
Let's say I do:
(define x 42)
(define y (quote x))
now using y how do I get to the 42?
I'm thinking of this as equivalent (in C terms) to:
int x=42;
int* y=&x;
Am I thinking about this wrong? If not what would be the scheme equivalent to *y?

Okay so to answer my question with the input from the above comments...
Symbols are not pointers, but can sort of be used like pointers.
The specific answer of how to get at the 42 is to use
(eval y)
or in guile (which is what I'm working with)
(eval y (interaction-environment))
see #ex nihilo's comment for why this works.
I found the guile version at How do I evaluate a symbol returned from a function in Scheme?
What symbols are is entries in the symbol table. A variable (itself an entry in the symbol table) which is bound to a symbol thus refers to another entry in the symbol table (analagous to pointers in this regard). However the referred to symbol need not exist at the time it is bound to the variable, but may be defined later because the linkage is not resolved until the symbol is evaluated. Thus
scheme#(guile-user)> (define z 'r)
scheme#(guile-user)> z
$1 = r
scheme#(guile-user)> (eval z (interaction-environment))
ERROR: In procedure memoize-variable-access!:
ERROR: Unbound variable: r
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
scheme#(guile-user) [1]> ,q
scheme#(guile-user)> (define r #t)
scheme#(guile-user)> (eval z (interaction-environment))
$2 = #t
Not sure what I would ever use the later fact for but interesting none the less.
Thank you to all who helped me wrap my head around this one.

Related

Why is x not bound in (define lambda (lambda (x) x))?

I tried to evaluate this: (define lambda (lambda (x) x)). MIT Scheme 11.2 gives an error: ;Unbound variable: x. Chez Scheme 9.5 also gives an error: Exception: variable x is not bound. Why is x not bound? I thought that define would evaluate (lambda (x) x) into an anonymous function, and then define lambda to be that anonymous function. Where does x get involved?
I don't get any errors in Racket 7.2 and Guile 3.0.1.
This isn't valid Scheme code:
(define lambda (lambda (x) x))
R7RS seems pretty clear about forbidding this in Section 5.4 about syntax definitions:
However, it is an error for a definition to define an identifier whose binding has to be known in order to determine the meaning of the definition itself, or of any preceding definition that belongs to the same group of internal definitions.
In the posted code the identifer lambda is being redefined, but the binding of lambda itself must be known in order to determine the meaning of the new definition; the above language forbids this.
R6RS has some similar language in Chapter 10 about the expansion process, but the R6RS language is more tightly coupled to the technical details of the expansion process. I'm pretty sure that it applies in the same way to this case, but not 100% sure.
A definition in the sequence of forms must not define any identifier whose binding is used to determine the meaning of the undeferred portions of the definition or any definition that precedes it in the sequence of forms.
OP notes the error message Exception: variable x is not bound and asks: "Where does x get involved?"
Granting that (define lambda (lambda (x) x)) is malformed and thus not valid Scheme, it isn't too meaningful to try to explain such behaviors. Yet it seems that this sort of behavior can be triggered by attempting to redefine other syntactic keywords in similar fashion. Consider:
> (define if (if x y z))
Exception: variable z is not bound
It seems obvious here that z is unbound, so the error doesn't seem unreasonable. But now:
> (define if (if #t 1 2))
Exception: variable if is not bound
Even if is unbound in the right-hand expression of the define form! If we assume that something similar is happening in (define lambda (lambda (x) x)) then lambda is unbound in the right-hand expression, and if that is the case, then (lambda (x) x) is not evaluated as a special form, but as an ordinary procedure call. The order of evaluation for arguments in a procedure call is unspecified, so it is perfectly reasonable that x could be reported as unbound before lambda in this case. We can get rid of the appearances of unbound xs to see if lambda is being bound:
> (define lambda (lambda))
Exception: variable lambda is not bound
> (define lambda lambda)
Exception: variable lambda is not bound
So it seems that the problem here is that attempting to redefine a syntactic keyword using an expression that relies on that keyword for its meaning can cause the binding for the syntactic keyword to become inaccessible.
In any case, take this last bit with a grain of salt because in the end this sort of redefinition is not valid code, and no particular behavior should be expected of it.

Can a program contain unbound variables if they will not be evaluated?

Consider the following program, where foo and bar have not been defined.
(define (f)
foo)
(if #t
(display "Hello!")
bar)
Is this a valid Scheme program? Are Scheme programs allowed to have unbound variables as long as those variables are never evaluated?
No:
"It is a syntax violation to reference an unbound variable" (r6rs report 9.1)
"It is an error to reference an unbound variable." (r7rs report 4.1.1)
The question code may be evaluated by a Scheme implementation, but is not a Scheme program,
and if included in a program the implementation should signal an error:
$ scheme
> (if #t (display "Hello!") bar)
Hello!
> (top-level-program (import (rnrs))
(if #t (display "Hello!") bar))
Exception: attempt to reference unbound identifier bar
>
Notes
(top-level-program ) is a Chez Scheme extension, and can be used to enter a Scheme program interactively.
Extracts from r6rs report related to the meanings of Scheme program, variable, and unbound
(italic emphasis in original, bold added):
5.1 Programs and libraries
A Scheme program consists of a top-level program together with a set of libraries
5.2 Variables, keywords, and regions
... An identifier that names a location is called a variable and is said to be bound to that location ...
Every mention of an identifier refers to the binding of the identifier that establishes the innermost
of the regions containing the use. ...
If there is no binding for the identifier, it is said to be unbound.
9.1. Primitive expression types / Variable references
An expression consisting of a variable (section 5.2) is a variable reference ...
It is a syntax violation to reference an unbound variable.
5.5. Syntax violations
... implementations must detect violations of the syntax. A syntax violation is an error with respect to
the syntax of library bodies, top-level bodies ...
If a top-level or library form in a program is not syntactically correct, then ...
execution of that top-level program or library must not be allowed to begin.
So a Scheme program can contain an unbound variable, but a standard-compliant implementation must not start evaluating
the program, even if evaluation of the variable could never be attempted.
No, but yes, but no...
Interpreting the terms Scheme program, unbound, and variable as used in recent
Scheme reports, it seems that the answer is no (see my other answer for references).
But this depends on one more assumption about the sample code - that if has its usual meaning
as the syntactic keyword described in the language defining reports.
Because identifiers in Scheme programs can shadow keywords, this is a valid
Scheme program in which bar appears to be unbound:
(import (rnrs))
(let-syntax ([if (syntax-rules ()
[(if e1 e2 _) (if e1 e2)])])
(if #t
(display "Hello!")
bar))
So:
$ scheme
> (top-level-program (import (rnrs))
(let-syntax ([if (syntax-rules ()
[(if e1 e2 _) (if e1 e2)])])
(if #t
(display "Hello!")
bar)
(if #f
(display "Hello!")
bar)))
Hello!
>

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 do I evaluate a symbol returned from a function in Scheme?

I'm refamiliarizing myself with Scheme and I've hit a problem that is probably reflecting a fundamental misunderstanding on my part.
Say I do the following in Scheme (using Guile in this case but it's the same in Chicken):
> (define x 5)
> x
5
> (string->symbol "x")
x
> (+ 5 (string->symbol "x"))
<unnamed port>:45:0: In procedure #<procedure 1b84960 at <current input>:45:0 ()>:
<unnamed port>:45:0: In procedure +: Wrong type: x
> (symbol? (string->symbol "x"))
#t
> (+ 5 x) ; here x is dereferenced to its value 5
10
> (+ 5 'x) ; here x is not dereferenced
<unnamed port>:47:0: In procedure #<procedure 1c7ba60 at <current input>:47:0 ()>:
<unnamed port>:47:0: In procedure +: Wrong type: x
I understand that string->symbol is returning a symbol, x, which is effectively quoted. However, I cannot figure out how to use the symbol returned by string->symbol in any later context. How can I have Scheme evaluate that symbol?
To give a background on why I want to do this, it's that I'm writing a C program with embedded Guile. I would like to be able to be able to access symbols defined in Guile by name from C, using for example scm_from_*_symbol or scm_string_to_symbol. The reasons these functions aren't working the way I thought they would is related to my core question above. Perhaps there's a better way to do what I want to do with Guile, but that's a different question. Right now I'm interested in the fundamental question above.
What you want is to evaluate the symbol (not to "dereference" it). I think this is what you meant:
(define x 5)
(+ 5 (eval 'x (interaction-environment)))
=> 10
Take a look at the documentation for further details.
You should read the chapter fly-evaluation of the Guile documentation.
You want eval and probably interaction-environment
I recommend reading the famous SICP and Queinnec's Lisp In Small Pieces
Symbols are not special in this sense, that is they are not easier to evaluate than ordinary strings.
Symbol is much like a string, it just doesn't have quotes around it. Well, the fundamental difference is, of course, not absence of quotes, but the fact that symbols are interned. This means that strings "x" and "x" are two different strings (although they are equal), while symbols 'x and 'x are actually the same object.

Why is this legal (racket) scheme?

I was going through htdp and found this somewhere in the beginning :-
Explain why the following sentences are illegal definitions:
1. (define (f 'x) x)
However, it works fine in racket:
> (define (f 'x) x)
> (f 'a)
3
> (define a 5)
> (f a)
3
Obviously, I'm missing something ... what, exactly ?
Short answer: you should not be using the full "#lang racket" language. The teaching languages strip out the potentially confusing advanced features of the language that you're encountering.
In this case, your definition is being interpreted as a function called f with an optional argument called quote whose default value is provided by 'x'.
Set the language level to Beginning Student, and you'll get a much more reasonable answer.
This line does not work for me in Racket: (define (f 'x) x). The error reported is define: not an identifier for procedure argument in: (quote x).
What language are you using? did you try to run the above line in the interaction window?

Resources