I've started trying to learn the innards of Scheme evaluation, and one aspect of quasiquotation, unquoting, evaluation and cons-cells is confusing me. If you can recommend any good references on the subject I'd be very grateful.
The R7RS draft has this example in section 4.2.8 on quasiquotation.
`(( foo ,(- 10 3)) ,#(cdr '(c)) . ,(car '(cons)))
(It's in the R4RS spec too, so this isn't a new thing.)
According to the spec this should evaluate to:
((foo 7) . cons)
I'm having some trouble understanding why. To my mind, the . removes the unquote from the start of the inner list, meaning it won't be evaluated as a procedure.
Here's a simpler expression that demonstrates the same problem:
`(foo . ,(car '(bar)))
Using the same logic as above, this should evaluate to:
(foo . bar)
And indeed it does evaluate to that on the Scheme systems I've tried.
However, to my understanding it shouldn't evaluate to that, so I want to find out where I'm going wrong.
My understanding of Scheme evaluation is (OK, simplified) if it's the first keyword after an open-bracket, call that procedure with the remainder of the list as the parameters.
My understanding of the spec is that ',' is exactly equivalent to wrapping the next expression in an '(unquote' procedure.
My understanding of the dot notation is that, for general display purposes, you remove the dot and opening parenthesis (and matching closing parenthesis), as described here:
In general, the rule for printing a pair is as follows: use the dot
notation always, but if the dot is immediately followed by an open
parenthesis, then remove the dot, the open parenthesis, and the
matching close parenthesis.
So:
`(foo . ,(car '(bar)))
Could equally be rendered as:
(quasiquote (foo unquote (car (quote (bar)))))
(In fact, this is how jsScheme will render the input in its log window.)
However, when it comes to evaluating this:
(quasiquote (foo unquote (car (quote (bar)))))
Why is the 'unquote' evaluated (as a procedure?), unquoting and evaluating the (car...) list? Surely it should just be treated as a quoted symbol, since it's not after an opening bracket?
I can think of a number of possible answers - 'unquote' isn't a regular procedure, the 'unquote' is evaluated outside of the regular evaluation process, there's a different way to indicate a procedure to be called other than a '(' followed by the procedure's symbol - but I'm not sure which is right, or how to dig for more information.
Most of the scheme implementations I've seen handle this using a macro rather than in the same language as the evaluator, and I'm having difficulty figuring out what's supposed to be going on. Can someone explain, or show me any good references on the subject?
You are correct in that there are macros involved: in particular, quasiquote is a macro, and unquote and unquote-splicing are literals. None of those are procedures, so normal evaluation rules do not apply.
Thus, it's possible to give (quasiquote (foo bar baz unquote x)) the special treatment it needs, despite unquote not being the first syntax element.
Related
Should numbers in scheme be quoted?
In the following examples (tested in ikarus), it seems that quoting numbers does not matter while too much quoting creates problems.
> (+ '1 1)
2
> (+ '1 '1)
2
> (+ '1 ''1)
1
What is the standard way to use numbers (e.g. in the definition of a function body)? quoted or not quoted?
Numbers in Scheme are self evaluating. That means they act in the same way if they are quoted or not.
If you enter (some 1) in DrRacket and start the Macro stepper and disable macro hiding the call will end up looking like:
(#%app call-with-values (lambda () (#%app some (quote 1))) print-values))
Thus Racket actually quotes the values that are self evaluating because their runtime doesn't support self evaluation in the core language / fully expanded program.
It might be that in some implementations a unquoted and a quoted number will be evaluated differently even if Racket threats them the same, however it would be surprising if it had any real impact.
Most programmers are lazy and would refrain from quoting self evaluating code. The exception would be as communication to the reader. Eg. in Common Lisp nil () and the quoted variants are all the same and could indeed used () everywhere, but many choose to use nil when the object is used as a boolean and '() if it is used as a literal list.
R6RS's definition of quotation says so:
(quote <datum>) syntax
Syntax: <Datum> should be a syntactic datum.
Semantics: (quote <datum>) evaluates to the datum value represented by
<datum> (see section 4.3). This notation is used to include constants.
So it is correct to do '"aa" or '123 but I have never seen it, I would find it funny to read code quoting the numbers or other constants.
In older lisps, such as emacs lisp, it is the same (in emacs lisp the syntax is called sexp or S-Expression instead of datun). But the real origin of the quotation's meaning comes from McCarthy and described in A Micro-Manual for Lisp.
I have been reading the first chapter of "The Little Schemer". The problem is, some examples work in DrRacket like (eq? "foo" "foo") and some don't like (car ("a" "b")) or (cdr ("a" "b")) because of
application: not a procedure;
expected a procedure that can be applied to arguments
given: "a"
arguments...:
Can you point me why these example do not work?
These examples don't work because they're not legal Scheme. I'm not familiar with the book, but it may be the case that it has been typeset in a way which may make it slightly hard to transcribe examples from it without the mistake you've made. To see why they're not you need to think about how the system evaluates things. Here is a simple-minded and partial description of how that might work (real implementations do something much hairier than this, and this description is partial not least because it contains no explanation for how we get the bindings of things at all).
To evaluate something:
is it something special like a string or a number or something like that, in which case its value is just itself;
is it a symbol, in which case look up the binding for that symbol and that is the value;
is it a compound form like (foo ...)? If it is, then –
look at its first element: is it a special magic thing we know about? If it is then do an appropriate special thing (see below);
otherwise evaluate all of the elements of the compound form in any order you like – the value of the first element should be a function, and the value is the result of applying this function to the values of the remaining elements.
So we can use these rules to try to evaluate (car ("a" "b")).
the form is a compound form, so we need to take the compound form case;
car is not any kind of special thing, so we don't hit that case;
so, evaluating the elements of the form (I'll do it left to right for simplicity) –
car is a symbol, so look up its value which is a function;
("a" "b") is a compound form, and its first element is not special –
evaluate its elements, both of which are literal strings whose value is themselves;
and now try to apply the value of first element to the values of all the others, and fail, because it is a string not a function.
OK, so this can't work. To make it work we need to go back and look at a case in the evaluation rules: when evaluating a compound form we sneak a look a the first element to decide if it is some special magic thing we know about and in that case we do something special. There are a small number of such special magic things: the only one that we care about here is quote. The special rule for this is:
if we see a compound form whose first element is quote, which will look like (quote ...), then –
it should have exactly two elements, so it should look like (quote <x>) for some <x>;
the value of the form is <x> with no further attempt to evaluate <x>.
So, for instance:
the value of (quote x) is the symbol x;
the value of (quote (1 2 3)) is the list (1 2 3);
the value of (quote "x") is the string "x" (you don't need quote in this case, since strings already evaluate to themselves by the very first rule above, but it does not hurt).
So to go back to the form we wanted to evaluate, what we actually need is (car (quote ("a" "b"))). When evaluating this:
the form is a compound form, so we need to take the compound form case;
car is not any kind of special thing, so we don't hit that case;
so, evaluating the elements of the form (I'll do it left to right for simplicity) –
car is a symbol, so look up its value which is a function;
(quote ("a" "b")) is a compound form –
its first element is special, since it is quote;
so use the rule for quote and the result is ("a" "b");
now apply the value of car to ("a" "b"), and the result is "a".
So then there is one more trick: (quote <x>) occurs a lot, so there is a special syntax for it, which is a single ': 'x reads identically to (quote x). This just makes source code less verbose. So this gives the final form of the working version of what you're trying to do:
(car '("a" "b"))
Finally, the reason Lisps need quote is an interesting thing to think about, but off-topic for this answer.
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.
I am reading an article which uses Scheme for describing an implementation. I know a bit of Common Lisp but no Scheme.
I am hoping you will be so kind as to explain two Scheme code samples and show me how they correspond to Common Lisp.
First, what does this Scheme mean:
(define (content cell)
(cell ’content))
I believe it means this: define a function named content which has one argument named cell. In Common Lisp it is written as:
(defun content (cell)
(...))
Am I right so far?
I am uncertain what the function's body is doing. Is the argument (cell) actually a function and the body is invoking the function, passing it a symbol, which happens to be the name of the current function? Is this the corresponding Common Lisp:
(defun content (cell)
(funcall cell ’content))
Here is the second Scheme code sample:
(define nothing #(*the-nothing*))
I believe it is creating a global variable and initializing it to #(*the-number*)). So the corresponding Common Lisp is:
(defvar nothing #(*the-nothing*))
Is that right? Does the pound symbol (#) have a special meaning? I'm guessing that *the-nothing* is referring to a global variable, yes?
Broadly speaking: yes to both, with one major caveat. More specifically, the first one is accepting an argument called cell and calling it with the symbol 'content. (BTW, your unicode quotation mark is freaking me out a bit. Is that just a copy-paste issue?)
In the second case, the hash is a shortcut for defining a vector. So, for instance:
(vector? #(abc)) ;; evaluates to #t
However, the hash also has quoting behavior. Just as the first element of
'(a b c)
is the symbol 'a (and not the value of the variable named a), the first value in the vector
#(*the-nothing*)
is the symbol '*the-nothing*, rather than the value of a global variable.
Following is a exercise from SICP. I couldn't figure it out on my own. Can some why help me understand?
Type following code into interpreator:
(car ''abracadabra)
And it print out 'quote'. Why?
As gimpf said, 'abracadabra = (quote abracadabra). You can verify this by typing ''abracadabra to the REPL, which will print (quote abracadabra).
Because ''abracadabra is really (quote (quote abracadabra)). In Scheme, the rule is: evaluate all the parts of the s-expression, and apply the first part to the rest of the parts.
"car" and "quote" are symbols in the below. #car and #quote are the functions they refer to.
If you take
(car (quote (quote abracadabra)))
and evaluate the parts, you get
(#car (quote abracadabra))
Then, apply the first part (the car function) to the second part (a list of two symbols).
quote
And you get just the symbol "quote".
Just remember, to figure out what happens in Scheme, evaluate the parts and apply the first to the rest. If you evaluate quote, you get the stuff inside. The only confusing part is that some primitives (number and strings) evaluate to themselves.