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:
(foo ...)
? If it is, then –
So we can use these rules to try to evaluate (car ("a" "b"))
.
car
is not any kind of special thing, so we don't hit that case;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 –
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:
quote
, which will look like (quote ...)
, then –
(quote <x>)
for some <x>
;<x>
with no further attempt to evaluate <x>
.So, for instance:
(quote x)
is the symbol x
;(quote (1 2 3))
is the list (1 2 3)
;(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:
car
is not any kind of special thing, so we don't hit that case;car
is a symbol, so look up its value which is a function;(quote ("a" "b"))
is a compound form –
quote
;quote
and the result is ("a" "b")
;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.