[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sweet-expressions are not homoiconic



John David Stone:
>  @         From the beginning, there was an obvious impediment to the use of
>  @ sweet-expressions: ...  Whitespace characters
>  @ don't look like grouping symbols, as parentheses, brackets, braces, or
>  @ oriented quotation marks do, because they don't have appropriate shapes and
>  @ don't come in pairs.  Moreover, they don't visibly nest, so it is unnatural
>  @ to use them to represent recursively defined syntactic structures.

I replied:
>  > This is demonstrably false.  Whitespace characters, in the form of indentation,
>  > are CURRENTLY used to group structures in pretty much all non-trivial
>  > Lisp programs.  People routinely use pretty-printers *specifically* to
>  > group and nest structures.  In fact, indentation is used
>  > to indicate nesting in practically every programming language.

John David Stone:
>         No, it's not.  It's used to manage layout, which is one of its
> principal purposes in traditional manuscripts and typography.

But that's the point.  Programmers ALREADY use layout to reveal programming
structure, even in languages where there's no syntactic need to do so.
Since people ALREADY do this, let's take advantage of it.

This may require changes in a few cases, because layout was ignored before.
But it also means that there's no longer a risk of layout misleading the developer.
And in practice, it doesn't seem to require much in the way of change at all.

>  Very few
> programming languages try to use it for grouping -- the ones that I recall
> offhand are Python and ABC, but I imagine that there are others.

Python doesn't just "try", it DOES use indentation for grouping.
Python all by itself is WAY more popular than Scheme or Common Lisp, too,
so clearly using indentation does not impede widespread use.

Other languages that consider indentation in some way include
Haskell, Occam, and Icon.  Adding ABC means that there are
quite a number, and in particular, it's a *substantial* portion of the
more recently-developed languages that don't try to closely imitate C syntax.

> Those languages get into slightly less trouble with the idea because programs in
> those languages don't use nesting quite as extensively -- the program
> structures tend to have shallower hierarchies and more flat constructions
> analogous to sequences in Scheme.

I don't think they get in trouble at all, whether they are nested or not.


>  But it is also true that Python programs
> are more difficult to read and to edit than they would have been if the
> designer had chosen to use explicit grouping symbols.

You're free to believe that, but I think you're quite wrong.


> This confusion between layout and grouping is really the crux of
> the issue.

It's not a confusion.  It's an intentional use of layout for grouping.


>  The reason that the parenthesis notation is better is that it
> separates these two functions, which both affect readability, but in
> different ways.  Using whitespace for _layout_ is, of course, a good idea,
> and almost all programmers and programming languages support it.  Using
> whitespace for _grouping_ is not such a good idea and doesn't work well
> when the groups are deeply nested, as they are in most Scheme code.

We already have 2 programs written using sweet-expressions in Lisp,
which is strong evidence *against* the claim that using
whitespace for grouping doesn't work for Scheme.

It's true that Scheme and Common Lisp tend to be more nested.
But that's trivially solved - just make the default indentation width smaller.
For example, both Alan and I use a default indentation of 2 chars
(instead of 4 or 8).  Even if you indent sometimes longer
(e.g., indent by 3 chars after "if" so the condition and branches align),
that gives you *plenty* of horizontal spacing for deep nesting.
If you have a long sequence in a deep nesting, just
use "!" to visually show the alignment.  Problem solved.

I *do* completely agree with you that using indentation as the SOLE
mechanism for grouping is a bad idea. But we retain parens.
In practice, indentation works well for the big picture, and parens work
well for the leaves.

>         Layout and grouping clearly diverge in the conventions that most
> Scheme programmers follow.  For instance, in let-expressions, the binding
> specification list and the body are indented differently, even though they
> are at the same level as far as syntactic grouping is concerned; this
> difference reflects the semantic difference between the syntactic
> constituents.

The binding spec list and body would typically be shown differently
in sweet-expressions, too.  

In sweet-expressions, short binding specs can be surrounded by <*...*>, e.g.:
let <* binding-spec... *>
! body

Long binding specs can use group, e.g.:
let
! \\
! ! binding-specs....
! body...

In both cases, the binding specs and body are distinct.
And even in cases where the "obvious"
indentation would be different, that is no tragedy.
The goal was to create a notation that people can read,
not to prevent change.

>         Another example:  In procedure calls that extend over several
> lines, the first operand may be indented differently from the others if it
> is semantically related to the operator in a way that differs significantly
> from the other operands (e.g., if the procedure is vector-set!, the vector
> operand is often indented differently from the index and new-value
> operands).

You can have differing indentation by either just continuing it on the line
or by using "\\".

Example of the first approach (which is what I'd do if it's long):
vector-set! vec
! 1
!  '("Sue" "Sue")

Example of the second approach (which I would normally only use with
keywords, but maybe you'll prefer it):
vector-set!
! vec
! \\ 1
! \\ '("Sue" "Sue")


>         John Cowan has pointed out that _uniformly_ using whitespace for
> grouping would produce programs that make excessive use of vertical space.
> This is obviously the case, and it demonstrates that the need to use
> whitespace for layout effectively contrains and complicates the use of
> whitespace for grouping, leading almost inevitably to the use of marker
> characters as syntactic guideposts.

Said another way: "Naively having only whitespace for grouping would
make excessive use of vertical space".  True, but we weren't naive.
We added a few additional markers to make the use of the notation
*pleasant* and *convenient*, and added them after trying out the
notation in real programs to see where the notation most needed help.

You seeming to complain about the use of a few markers as abbreviations,
but Lisp *ALREADY* includes some conventional abbreviations.
Do you ever write 'x instead of (quote x)?
Do you write (a b c) instead of (a . (b . (c. '())))?
I bet you do.  That's because _uniformly_ using dotted notation without
abbreviations would make excessive use of space (to paraphrase).
It should be unsurprising that indentation processing would create pressure
to add more markers, such as to counter excessive use of vertical space.
There aren't many, and each one is general and powerful.

--- David A. Wheeler