[plt-scheme] Why isn't the car of a list of symbols a symbol?

From: Joe Marshall (jmarshall at alum.mit.edu)
Date: Fri Jul 10 14:42:27 EDT 2009

On Fri, Jul 10, 2009 at 10:33 AM, Marco Morazan<morazanm at gmail.com> wrote:
>
> Let's not equate an expression with a list.

Well, you pretty much have to consider expressions as a subset of
lists because large parts of the standard (both R5 and R6) depend on
this.

I quote from R6RS:
Syntactic data (also called external representations) double
as a notation for objects, and Scheme’s (rnrs io ports
(6)) library (library section 8.2) provides the get-datum
and put-datum procedures for reading and writing syntactic
data, converting between their textual representation
and the corresponding objects. Each syntactic datum represents
a corresponding datum value. A syntactic datum
can be used in a program to obtain the corresponding datum
value using quote (see section 11.4.1).
Scheme source code consists of syntactic data and (nonsignificant)
comments. Syntactic data in Scheme source
code are called forms. (A form nested inside another form
is called a subform.) Consequently, Scheme’s syntax has
the property that any sequence of characters that is a form
is also a syntactic datum representing some object. This
can lead to confusion, since it may not be obvious out of
context whether a given sequence of characters is intended
to be a representation of objects or the text of a program.

I quote from R5RS:
Note that the sequence of characters "(+ 2 6)" is not an
external representation of the integer 8, even though it is an
expression evaluating to the integer 8; rather, it is an external
representation of a three-element list, the elements of
which are the symbol + and the integers 2 and 6. Scheme's
syntax has the property that any sequence of characters
that is an expression is also the external representation of
some object. This can lead to confusion, since it may not
be obvious out of context whether a given sequence of characters
is intended to denote data or program,

End quotes.

Obviously, there are some here that wish to insist that *all*
sequences of characters is intended to exclusively denote programs.
Some of us here make use of contextual wording such as `evaluates to'
or `produces' to indicate that we're talking about a program fragment
and `is' or `represents' to indicate that we're talking about data.
I don't think anyone here has taken the stand that *all* sequences
of characters must exclusively denote data (how would you write a program?)

While I understand the allure of wanting to avoid the `confusion' mentioned
in the standard, one cannot consistently maintain that view in light
of the existence of `read' and `write'.

> (* 1 2 3) and (- 10 4) are both application expressions.

> (list? (read (open-input-string "(* 1 2 3)")))
#t

The first is evidently a list.

> (car (read (open-input-string "(* 1 2 3)")))
*
> (symbol? (car (read (open-input-string "(* 1 2 3)"))))
#t

It is a symbol.

> (eq? (car (read (open-input-string "(* 1 2 3)"))) *)
#f

It is *not* the multiply procedure.

>
> Usually, the input is read and parsed resulting in a parse tree. In
> this parse tree, ((quote yes) (quote no)) is an application
> expression. This all occurs *before* eval comes into the picture.

This returns a list, not a parse tree:
  (read (open-input-string "((quote yes)(quote no))"))

Eval can take a list argument:
  (eval (read (open-input-string "(+ 2 3)"))) => 5

By `parse tree' I refer to what is called in section 4 `program syntax',
*not* what is called `datum syntax'.  Since the program syntax did not
exist until eval was called, eval must have constructed it.

We can see that read does not construct program syntax:
(read (open-input-string "(lambda () lambda if if)"))

This cannot return a program under the standard meaning of lambda
and if, yet read gives no error.



-- 
~jrm


Posted on the users mailing list.