Beni Cherniavsky-Paskin:
> Summary: I only buy the first of the use cases; I think this construct will
> be rarely used and want the sematics to be as simple as possible; I propose
> some alternative ideas below.
First of all, thanks SO MUCH for posting!! I'm a big believer in feedback, so I
really appreciate your time.
I agree that the first use case (multi-line libraries) is more important, which
is why I put it first.
I do think the other use case is relevant, though, especially if we can resolve
both at once.
I completely agree that the final semantics need to be "as simple as possible".
In general, I try to do a lot of experimentation and out-of-the-box thinking
before deciding on something specific, so please don't assume that some more
complicated draft structure is the "final word".
> If we separate the 2 issues, I feel the no-blank-lines is the more
> problematic of them. In Python, I'm fine with most of my defs being
> indented because they're class methods, but couldn't live without new lines.
> Do you agree?
I don't *exactly* agree, though you may be missing an element of
sweet-expressions that makes end-on-blank-lines work. But first, my priorities.
My current view is that the more important requirement is that the REPL and
file format need to be exactly the *same* in a Lisp-based system. In Python you
often cannot cut-and-paste from files into the command line ("REPL"), because
Python files and the REPL have different blank-line semantics. (Technically,
the Python spec only covers files, but that's a useless nuance.) That's
actually a problem in Python today, and annoys me sometimes. In a Lisp such a
difference would be crazy, because Lisps are programmable programming languages
where experimentation is common.
Now for blank lines. Blank lines ending an expression actually isn't bad, even
in a larger program, because of the rule that comment-only lines (possibly
indented) are completely ignored, and do NOT end an expression. I agree that
without that rule it'd be hideous to use, but using comment-only lines to
vertically separate material actually works very cleanly.
It's not insane to use some marker to mean "end of expression", several
languages do that. Indeed, sweet-expressions could be modified to that easily
enough. But then users have to remember to do that after every expression. If
REPL use is rare, that'd be fine. But I expect lots of people to use the REPL,
often, and I want the REPL to be very pleasant to use. It's hard to beat
"enter a blank line to evaluate".
But this approach does have a downside with long library declarations (and
similar structures). In these cases, the endless indentation *and* the blank
lines ending expressions both start to get annoying. Thus, the <* ... *>
proposal.
> > Now let's look at the second use case.
> > The sweet-expression notation cleanly handles cases where let-expression
> > variables have complex values (e.g., using \\), but for simple cases
> > (1-2 variables having short initial values) ...
> I completely don't get it.
> What's wrong about ((x 5) (y 7)) or (x{5} y{7}),
> and why is <* x 5 *> or <* (x 5) *)> any better?
> When compressing nested lists on one line, parens are the - clearest way to
> represent structure.
> Specifically, I dislike the usage where <* x y *> implies a double list by
> restarting the multiple-items-on-a-"line" rule. While I see the consistent
> logic of this semantics, it's IMHO way too hard to scan this visually as a
> double list - a problem ((...)) doesn't have.
Well, the current notation is obviously not a disaster, since we've written
programs without it. But when the variables involve modest amounts of
calculation, it gets harder to see what you're doing than I'd prefer, because
it's easy to suddenly require more paren-nesting than is typical in other
languages.
Contrast:
let ((x cos(f(c))))
! dostuff x
with:
let <* x cos(f(c)) *>
! dostuff x
or:
let <* x $ cos $ f c *>
! dostuff x
In one-variable lets, a common mistake is to forget to embed the variable in
double-parens. Since the parens are also usually used for the expression
calculation, it can be easy to miss. Making it possible to visually
distinguish the outer "parens" that create the variable list, from the internal
parens used for the expression, makes it clearer which parens are more
structural vs. the ones involved in the variable calculation. That, in turn,
makes it easier to notice the omission of doubled parens for one variable.
> As I see it, we need some solution for the very-long-form problem, while
> one-liner-let is a solved problem.
> If restricting <* .. *> to EOL - or even requiring them to stand alone on a
> line - makes for a simpler spec, I'd much rather see that rather than fine
> tuning the inline semantics.
An excellent point. Yes, I agree that simplicity (of spec and implementation)
is really important. The older experimental rulesets for <* ... *> were
probably a good case-in-point of complications that, if we *had* to do them,
were a good argument against them.
As it turns out, the new ruleset for <*...*> that I just posted is quite
simple, and it basically only requires one extra line in the spec to handle the
on-the-same-line case.
> I agree that "two-liner-let" is not a solved problem. We can either cram
> it on 1 line, or nicely spread on 1+N lines using \\, but not on N lines.
It turns out the new ruleset handles this case as a byproduct, and doesn't
require any new code or productions to make it work. Which in my mind is
evidence that it's the right direction... ideally a grammar should have a few
powerful productions that keep getting reused.
> IMO this goes deeper than just let but I don't think abusing <*..*> is an
> improvement.
Fair enough.
> I'll try to post thoughts on this in the z language thread.
Okay!
> IMHO, it's very ugly that "example grid ..." are indented when the body of
> the library isn't. Indentation should be (at least) non-decreasing!
Hmm, I view this as a *solution*. There's only so much horizontal and vertical
space. If nearly the entire file is indented to several levels, that means
there's less (horizontal) room to express actual content.
I completely agree that indentation should *NORMALLY* be non-decreasing, but
the point of this structure is to "restart" indentation so you're not stuck
writing all content on the right edge.
> If I were to use a construct like this, I'd either have "define ..."
> indented deeper (only using <*..*> for blank line freedom), or flatten the
> containing lists at indent zero (on the theory it should actually be
> negative):
>
> <*
> define-library
> example grid
> export make rows cols ref each rename(put! set!)
> import scheme(base)
> <*
> begin
>
> define make(n m)
> let (grid(make-vector(n)))
> ...
> *>
> *>
I wouldn't format the first define-library...import that way, but that's
certainly consistent with the current draft semantics. Perhaps more
importantly, the second "<*" is definitely the way I'd expect to see it used.
> I'm deliberately restricting <* to the head of the list. I see it as an
> esoteric construct, and this is the simplest least-surprise version.
Okay. I actually agree with you that multi-line "<*" should be used relatively
sparingly, as it's a powerful tool that can confuse if misused. But we're
noticing its LACK as we write bigger programs, so that's why we're addressing
it.
> Which is also a weakness IMHO. Visually, < and > don't feel like a list
> start/end, at least not to lisp eyes. ([{ / }]) have a history as list
> delimiters, < / > not so much.
Fair enough. But no other character pairs, other than <..>, are available in
least-common-denominator ASCII. Also, while I think <*...*> is important, I do
not think many lines of code will directly *use* these symbols (especially in
the multi-line case). So even if I COULD find another character pair (and ), I
don't think I would want to use up valuable single-character pairs on this
functionality; it's perfectly fine to use multi-character markers.
That said, if there are multi-character symbols that you think would better
"feel" like list start/end, let us know! I thought about using "<<" and ">>",
which look like guillemets and probably "feel" more like list start/end. But
Scheme systems like scsh already use these symbols (e.g., use >> for
append-to-file).
Suggestions? The actual marker sequence would be trivial to change now... and
impractical to change later.
The rest of your post has interesting ideas I need to think about, but I have
to run right now.
--- David A. Wheeler
------------------------------------------------------------------------------
Master Java SE, Java EE, Eclipse, Spring, Hibernate, JavaScript, jQuery
and much more. Keep your Java skills current with LearnJavaNow -
200+ hours of step-by-step video tutorials by Java experts.
SALE $49.99 this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122612
_______________________________________________
Readable-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/readable-discuss