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

Re: First impressions of the specification



Mark H Weaver:
> Yes, this is definitely headed in the right direction!  I'm now able to
> understand most of the rules from the tutorial and basic specification.

Great!  In that case, we can make some specific improvements since
the basic approach seems to make it easier to understand.

> A few comments on the tutorial:
> 
> * It would be helpful to describe what happens if '.' is encountered
>   outside of any parentheses, in both the tutorial and the basic
>   specification.

Okay.  It's basically what you expect; "a . b" on a line is "(a . b)".
But we can easily add that; there are even some examples currently
in the examples section.

> * Re: "Block comments (#|...|#) are removed."  I still don't know what
>   this means exactly.  Why do you say "removed" and not simply
>   "ignored"?  Is there a difference?  Why don't you say that other kinds
>   of comments are "removed"?

If they're at the beginning of a line, the indent still matters (like GROUP).
I think people found it confusing if they did otherwise.

> * Re: GROUP and SPLIT in the tutorial: Examples needed, especially for
>   GROUP.  The language "it represents no symbol at all" is confusing and
>   unclear.  Also "intepreted the start" => "interpreted as the start".

Okay.  Perhaps we should walk through with examples for each.

I still think it's useful to have an "examples" section too, but there's no need
to duplicate ones in the tutorial.

> Some more comments, unrelated to the recent changes:
> 
> * I continue to find the use of unconventional indentation in the
>   s-expression examples to be quite distracting.  I've never seen Scheme
>   or Lisp code indented that way.
...
> * I think you should consider using conventional indentation in your
>   t-expression examples where reasonable, e.g. for 'if' and 'do'
>   Personally, I find this:
> 
>     define gcd(x y)
>       if {y = 0}
>          x
>          gcd y rem(x y)
> 
>   much easier to read than your convention of:
> 
>     define gcd(x y)
>       if {y = 0}
>         x
>         gcd y rem(x y)

The only difference I see is that "x" is indented by 2 spaces in our case,
and in your case, "x" is lined up with "{" with the assumption that characters
are always fixed-width characters of equal width.  Is that correct?

Either indentation is valid in sweet-expressions, so we *could* do it.
So now we're talking more about style for use as examples,
as opposed to some deep need to use one or the other.

I'll call these styles "fixed-indent" (always increment indent by
a fixed amount) and "line-up-indent" (line up new indent with a later
parameter in the parent).

> ...  Is there a compelling reason to break this tradition?

I don't know how much of a "tradition" this is, I haven't done a study.

I'll note that guile's pretty-printer, by default, does NOT line up the
condition and the branches; by default it uses "fixed-indent", not "line-up-indent".
Also, I normally use "fixed-indent"
when I write s-expressions, just as it's done in the spec.
E.G., in src/kernel.scm of "readable", I wrote:

>              (if (memv #\! indentation-list)
>                (read-error "Initial ident must not use '!'")
>                (if (not (memv (my-peek-char port) initial_comment_eol))
>                  (let ((results (n_expr_or_scomment port)))
>                    (if (eq? (car results) 'scomment)
>                      (begin


There are *reasons* I use fixed-indent.  First of all, the fixed-indent rule
is really simple: "indent fixed amount X".  In the "line-up-indent" style,
I have to figure out what to line up.

If I change some line with "if" etc. in "line-up-indent" style,
I'll feel compelled to change the indentation of the lines below to
"fix" a style issue. These cause extra work and
spurious "changes" when looking at diffs.

The line-up-indent approach also
assumes that you know the encoding and visual width of all characters.
This is increasingly untrue in an international world with
non-ASCII chars, various encodings, and variable-width fonts.


> * I have doubts whether the addition of '!' as an indentation character
>   is worth the added complexity in the spec (which is far more complex
>   than I'd prefer, and I'm sure I'm not alone in feeling that way).
>   Python seems to do fine without such a character.  So do Makefiles.

Actually, Python and Makefiles do NOT do fine.
It's a common complaint that leading whitespace is removed and changes
their meanings.

But historically it's been an unexamined assumption that only space and tab
can be indent characters.  We just examined it :-).

The '!' doesn't add much complexity at all, it's really just the phrase
"and the exclamation point" when defining indent characters.
I have a proposal to simplify it otherwise on the table, which may help.

I think the real problem with "complexity" is that the BNF has two parts:
(1) all the lower-level definitions, and (2) the top-level definitions that
do all the real work.  If I separate those into separate sections, I think
it'll be much easier to understand, because then you could skip the
obvious-but-I-must-define-it stuff on a first reading.

--- David A. Wheeler