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.
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.
The problem is quite difficult to explain because I need to collect my thoughts, so bear with me. I've been able to reduce the problem to a minimal example for illustrative purposes. The example will not make any sense as to what this would be useful for, but I digress. Say I want to extend the racket language to write things that look like this:
(define-something
(['a] 'whatever)
(['b 'c] 'whatever2))
Between the square brackets is a sequence of one or more symbols, followed by a sequence of racket expressions (the whatever's, which are not important for the problem statement)
The example would match a macro that looks something like this:
(define-syntax (define-something stx)
(syntax-case stx ()
[(_ ([symb ...] body ...) ...)
#'()]))
Actually here we match 0 or more symbols, but we can assume there is always going to be at least one.
In the macro's body I want to generate function definitions using the concatenated symbols as the identifier. So for our silly example the macro would expand to something like:
(define (a) 'whatever)
(define (bc) 'whatever2)
I have found a similar question where the poster generates functions using a pre-defined list of strings, but I am not that fluent with macro's so I have not been able to translate the concepts to solve my problem. I thought perhaps I could try generating a similar list (by concatenating the symbols) and applying their tactic, but I've been getting way too confused with all the ellipses in my macro definition. I'm also a bit confused about their use of an ellipsis in with-syntax.
It’s possible to solve this with with-syntax and syntax-case, but the easiest way to do this is by using syntax-parse’s syntax classes. By defining a syntax class that parses a list of symbols and produces a single concatenated identifier, you can lift the symbol parsing out of the macro body:
(require (for-syntax syntax/parse
racket/string))
(begin-for-syntax
(define-syntax-class sym-list
#:attributes [concatenated-id]
(pattern (~and stx (sym:id ...))
#:attr concatenated-id
(let* ([syms (syntax->datum #'(sym ...))]
[strs (map symbol->string syms)]
[str (string-append* strs)]
[sym (string->symbol str)])
(datum->syntax #'stx sym #'stx #'stx)))))
Now you can define your macro pretty easily:
(define-syntax (define-something stx)
(syntax-parse stx
[(_ (syms:sym-list body ...) ...)
#'(begin
(define (syms.concatenated-id) body ...)
...)]))
Note that this uses unquoted symbols in the name clause, so it would work like this:
(define-something
([a] 'whatever)
([b c] 'whatever2))
The names can’t be expressions that evaluate to symbols because the information needs to be known at compile-time to be available to macro expansion. Since you mentioned in a comment that this is for an FRP-like system, your signal graph will need to be static, like Elm’s is for example. If you want the ability to construct a dynamic signal graph, you’ll need a more complex strategy than macros since that information will need to be resolved at runtime.
I would like to do something like this
(cons '(someword,string->symbol somevarname) (restoflist))
but somevarname is never replaced by its value.
I thought this was possible?
Quote makes literal lists. To make a list dynamically at runtime, you can also use quasiquote and unquote. For your case, it looks something like the following (assume somevarname is either locally or globally bound):
(cons `(someword ,(string->symbol somevarname)) (restoflist))
It is, but because you quoted the expression containing string->symbol, it never got evaluated. I'd try to show the right way to get what you want, but it isn't clear just what that is.
Based on your comment (and ignoring the comma), it seems that you would want:
(cons (list 'someword (string->symbol "somevarname")) restoflist)
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.