Please appreciate the difference between a specification and its implementation. Scheme has an excellent specififcation of so little that you guys have to rely on implementation-specific extensions to get any real work done, but that doesn't mean you should _forget_ the specification. The same applies to macros, of course.
#:Erik -- If this is not what you expected, please alter your expectations.
Christopher Browne wrote in message ... >A legitimate problem is that there's not a single scheme for >handling macros, but rather two or three, most of which are >somewhat less powerful than CL macros.
Most Scheme-implementations support the 'defmacro'-style way of macros, like this:
(define-macro (when test . body) ; or 'defmacro' `(if ,test (begin ,@body) #f) )
I don't see the difference to CL macros. I just don't see it. (Those implementations that provide this type of macros also have gensym, so it is *exactly* the same).
The 'define-syntax' stuff is something different, and I agree with everybody who isn't particularly fond of them. But since the oh-so-powerful CL-macros are easy to implement, many Scheme implementations provide them.
Pierre R. Mai wrote in message <87ya23sd79....@orion.bln.pmsf.de>... >You cannot demonstrate the truth of a statement about a language by >sampling a small subset of it's implementations. You have to ... > [blablabla] >...That in "real live" many (though not all) Scheme implementations _do_ >accept (if 1 2 . (3)), and treat it identically to (if 1 2 3) is a >different matter.
If you mean that the Scheme-standard is full of holes, yep, you're right with that. If you consider yourself a language lawyer, then there is absolutely nothing to say about the enormous advantage that a huge and mature standard gives to a language. I wished something like that would exist for Scheme. But CL (and that includes its predecessors like MacLISP) had a lot of time to evolve, and you see that everywhere in the language specification.
But, I think I can very well take some of the most used Scheme implementations and regard their behaviour as common practice. No, I'm not talking about the language Scheme as defined in the standards document, I'm talking about the language Scheme as implemented, in "real live", as you call it.
I guess the authors of the various incarnations of the "Revised Report on Scheme" had it in their mind to keep the language small. First, to give implementors freedom in the range of implementation-techniques (and that has resulted in some really interesting ideas), and second, to keep the language open, and not to constrain it's development too early. (Of course, I might be completely wrong)
BTW, how many CL implementations adhere *fully*, 100%, to the Hyperspec? I'm sure every implementation has it's little incompatibilities (especially in a *huge* language like Common LISP).
Anyway, I think you are right in that the R5RS isn't really that great. But Scheme (and many of it's implementations) is! ;-)
(Sorry, I couldn't resist, I just can't stop teasing ;)
This is what I find most objectionable about this scheme. Instead of a simple, robust, clean, unambiguous, one line expression, Paul seems to find preferable a three-line, hard to visually parse, difficult to properly quote on Usenet, over-white-spaced abomination. Pardon me if I sound too grumpy about this.
Instead of a proven, robust, reliable method of including bodies, for instance, in let blocks, Paul seems to prefer introducing another extra line containing some syntactic sugar '...'.
Come on! Paul, you are totally underestimating the benefits of having explicit parentheses, and totally overestimating the "benefits" of making white space significant.
If you really want to remove parentheses from your screen, have your editor color them with a foreground color identical to your background color. Then see how easy it is to write Lisp. Your editor will still be able to indent using the invisible parentheses, so you'll get *all* the benefits of your scheme, without changing Lisp one bit. I think most programmers would quickly go bonkers using my method, which as far as I can tell is equivalent in most respects to yours, except the '...'.
Yet another subtlety that I think is missed in this discussion is the special treatment of certain macros, which take ordinary arguments and &body lists. They get indented specially, in my experience, although the Lisp reader doesn't care. Will this scheme enforce certain behaviors on the part of the programmer for these macros to be properly parsed???
I think that whatever utility Python people get from their whitespace is far overwhelmed by the utility that Lisp people get from their own uniform, robust, unambiguous, and simple use of parentheses. Pardon me if this is obvious to all you Lispers.
+--------------- | There isn't "a lot of" cut and paste in Lisp, but _when_ you want to | move or copy whole expressions, Emacs users double-click on one of | the parentheses and the whole expression is instantly highlighted and | ready for copy... +---------------
By the way, even "vi" lets you do this -- "y%" will copy (or "d%" will cut) the following sexp into the anonymous buffer, and "p" (or "P") will paste.
+--------------- | Also, when people need to move expressions around, they have tools in Emacs | like transpose-sexp, which I suppose you would do with transpose-lines or | something... +---------------
In "vi", to transpose two sexps, just type "d%%p".
+--------------- | "Those who do not know Emacs are doomed to reinvent it". +---------------
I'm sure Emacs is the ultimate tool for this[*], but still, if you use the mechanisms available in "vi", editing Lisp is pretty easy.
-Rob
[*] For those who can make their fingers work that way; mine can't seem to.
----- Rob Warnock, 41L-955 r...@sgi.com Applied Networking http://reality.sgi.com/rpw3/ Silicon Graphics, Inc. Phone: 650-933-1673 1600 Amphitheatre Pkwy. PP-ASEL-IA Mountain View, CA 94043
in article 39946CC5.625D5...@kurtz-fernhout.com, Paul Fernhout at pdfernh...@kurtz-fernhout.com wrote on 2000.08.11 14:14:
> Speaking in terms of psycho-physiology, it is hard to tell the > difference between, for example, two or three parens, thus "))" is > difficult to distinguish between ")))"
Exactly. Simply from a typographical standpoint, long strings of parenthesis are undesirable. However, the readability can be improved with a little typographical help without changing the language. For example, outer parenthesis can be displayed in a larger size, or a heavier weight, or by using glyphs that have different amounts of curvature. Going further, one can begin to vary the symbols used: {[(
And I think the reference to typography here is of prime importance. Parenthesis, white space, and semicolons, for example, are fluid things in the world of publishing. They can be displayed in many different ways, to make the text easier to read, and sometimes to add meaning.
I hope that single-font, single-size, mono-space, plain text editors are finally replaced by something richer soon.
[And when I use the future tense in any of my postings on this topic, I'm not trying to say that these haven't been tried or don't exist, but that they aren't found in common usage. And if that isn't enough of a qualification for some of you, I'll add: Found in common usage in the world of consumer software development.]
-- Chris Page Mac OS Guy Palm, Inc.
let mail-to = concatenate( "Chris Page <page", "@", "best.com>");
in article sfwem3vr8h2....@world.std.com, Kent M Pitman at pit...@world.std.com wrote on 2000.08.11 10:52:
> As a linguistics professor of mine, the late Bill Martin, used to say, > "languages aren't about saying what is expected, but about what is > not". He would go on to say that if "cheese mouse eat" was enough as > just a sequence of words to mean "the obvious thing" then there would be > no need for syntax. Just the words and their obvious meaning would be > enough. But languages are about being able to express complex > situations like "the cheese ate the mouse", and that's why we have complex > syntax.
Of course, in Esperanto each word has a prefix and/or suffix to indicate its role, so that sentences can be arranged in almost any order without destroying the meaning. Unconventional orderings can be harder to read, but it provides a freedom that can be used to add meaning and stress (as, of course, does English, but not to as great an extent).
A lesson to be learned here is that some complexity in a computer language can be a good thing. If anything, one (not me of course) might argue that Lisp syntax isn't complex enough. That it's too smooth. And of course we all know that smooth things are often uninteresting things. (Clearly Lisp isn't that smooth.)
So I see a lot of merit in "infix" syntaxes. And I think Dylan provides a good example of how a language can provide for a range between "smooth" and "interesting" (speaking loosely). So that programmers have a tool for communicating information to human readers with emphasis and stress in their programs. An extremely brief example:
dog.color := #'black';
vs.
color-setter( #'black', dog );
These always mean the same thing to the computer, but not always the same thing to the human.
-- Chris Page Mac OS Guy Palm, Inc.
let mail-to = concatenate( "Chris Page <page", "@", "best.com>");
I think it's important to note that this can be taken even further in Dylan:
bar-setter(\+(bar(foo), \*(aref(a, i, j), xyz(abc))), foo);
I think it's also important to note that in the absence of a parenthesis-balancing editor, I had to spend quite a bit of time making sure I had this right, whereas the infix version is obviously correct. Maybe it's just me.
-- Chris Page Mac OS Guy Palm, Inc.
let mail-to = concatenate( "Chris Page <page", "@", "best.com>");
in article 398BA35A.CAC8...@fisec.com, Robert Monfera at monf...@fisec.com wrote on 2000.08.10 22:19:
>> I think the future holds a programming experience where [...] programs are >> manipulated in terms of their semantic objects at a far quicker pace and >> with less errors than at present.
>> Think I'm blue-skying? Just wait. Or better yet, start working on making it >> a reality.
> You are predicting the past :-) I think it used to be a reality for > various programming environments.
I appreciate the smiley, but I feel compelled to say that I meant that this is not yet a reality in mainstream commercial development, in the same way that Dylan and Lisp are not a reality. That is, apart from my two years helping develop Harlequin/Fun-O Dylan at Harlequin, I can't readily find a job writing shrink-wrapped consumer software in either of these languages.
> For example, there was a recent thread about structure editors and the > Interlisp environment. There were some discussions about the merit of > object-based versus text-based editing.
Thanks for the pointer. I'll look for that.
>> P.S. When you have an editor that manipulates code rather than text, then it >> also becomes possible to instantly recompile code as it is changed,
> It can be done both ways. The question is: do you _always_ want to have > a function recompiled? Maybe you make a dozen modification steps - do > you want a dozen recompliation? Do you want instant recompilation when > you would rather want to recompile several functions in one > _transaction_ - for example to preserve metastability?
I fully expect any good system would include such "escapes" where at the extreme one could edit raw text and have it parsed only after some editing has been performed. Hopefully this would only be necessary when merging in code from external text sources.
I recognize that this is an area fraught with issues, but I think it should be possible to allow programmers to enter incomplete code in a structured manner and simply have the compiler put on hold for that code until it is complete.
Also, when I say that the code is compiled, I don't necessarily mean that it is "committed" to the output binary. What I'm getting at is that the parser, compiler, and linker would be able to appear to take no time, because they can be done incrementally and/or threaded in the background. So that when you are ready to run the code, there is no delay.
> If anything, I'd like an editor that can manipulate definitions beyond > the boundaries of stone-age file concepts (e.g., seeing all methods of a > GF on the screen, or seeing all business logic code, or seeing all code > related to a class). I hear Dylan's editor is like this.
Apple Dylan edits code like this, although technically it is just editing smaller source files. That is, you edit smaller chunks of text, which typically contain single definitions, but which can contain more if you like. One can even round-trip import-edit-export traditional source files, as it keeps all the definitions from a file grouped together. Too bad it's no longer a commercial product (dangit).
> An indicator for each declaration would also not hurt. It could have > one of the following states: > - currently active > - changed, not yet compiled (i.e., obsolete) > - removed from image (undefined)
You're nearly describing Apple Dylan. Each source record (which typically holds a single definition) has flags for:
- Unsaved: has unsaved changes. - Uncompiled: has uncompiled changes. - Warnings: the compiler generated warnings about it.
And source records can be "Excluded", which means they're ignored by the compiler. (The equivalent of wrapping a Lisp defining form with #| |#.)
> Another area to improve is macros. Currently the only safe thing to do > after macro redefinition is to recompile all files that possibly use the > macro.
Right. Once you have sub-file source records like Apple Dylan, you can at least reduce the amount of recompiled source to each definition that references the macro (directly or indirectly).
Even better, would be to only have to recompile the code within the definition that is affected by the macro.
> A GF browser would also be helpful.
I'm pretty sure I recall seeing a GF browser in Harlequin Lisp (and Dylan). I hope they're not that uncommon.
-- Chris Page Mac OS Guy Palm, Inc.
let mail-to = concatenate( "Chris Page <page", "@", "best.com>");
in article sfwg0obr9di....@world.std.com, Kent M Pitman at pit...@world.std.com wrote on 2000.08.11 10:32:
> Consider, by contrast, infix languages where you have a situation like:
> a*b+c > ^
> with the cursor at the indicated point and you want to grab the expression > after the cursor. You can't. You don't know if "the expression" is a, > a*b, or a*b+c because the situation is ambiguous.
This may be a bit difficult with some text editors, but it doesn't mean that it can't be handled. Take a look at Graphing Calculator (the one that comes with Mac OS) for an example. When dragging the mouse over an expression it automatically selects sub-expressions, rather than just characters. If you drag over "*b" it selects "a*b". If you continue dragging to include "+", it selects "a*b+c". [If you actually try this, you'll find that it doesn't draw the "*", since "ab+c" is sufficient.]
There's an implicit set of parenthesis around the entire expression and precedence implies internal parenthesis. They're there, they just aren't displayed -- for clarity.
Of course when you say "the situation is ambiguous" you mean "the situation is ambiguous for a text editor that knows nothing about the language". If nothing else can be learned from the example of emacs, it must be true that (at least some) people desire smart editors.
> My concern would also be about subtleties like: > (setq x f) > vs > (setq x (f)) > Were I to replace parens with indentation, it's not obvious to me how to > easily distinguish these two items. Do I add "a little extra" identation > for the second? That would be awful.
I'm pretty sure the original proposal for indentation-sensitivity allowed for parenthesis to remain in the language. So you could keep the parenthesis around "f" if they're significant. I think all you've shown is that programmers would still need the option of using parenthesis.
-- Chris Page Mac OS Guy Palm, Inc.
let mail-to = concatenate( "Chris Page <page", "@", "best.com>");
Paul Fernhout <pdfernh...@kurtz-fernhout.com> writes: > Paolo-
> Mostly that impression is from comments on this newsgroup to this > posting. The possibility that an indentational syntax might make cut and > paste more difficult seems to be a source of strong objections to an > indentationally significant syntax (not that there aren't others).
I think that the reason why you are seeing so many objections to the idea of removing parens in lisp is due to a subconscious mental process that nobody has yet been able to articulate, though some have come very close by noting the code-and-data aspect of lisp. Let me try to make that articulation, by posing a puzzle:
How many parens, left and right, are in Lisp code?
Answer: very few.
To illustrate this, let's take a couple of examples:
Example 1:
How many parens are in the following code?
(defun foo (a b) (let ((c (+ a b))) (list a b c)))
Answer: 0
Example 2:
How many parens are in the following code?
(defun foo () #\()
Answer: exactly 1 left paren.
The problem with actually _describing_ the lisp code that is associated with the above _text_ in a newsgroup such as this one is that the communication must be made by textual means, and thus the program content cannot be easily transferred without using some representation that would probably include parens.
Let me buck this tendency, however, and show you two ways to represent a lisp program without parens:
Method 1: Replace parens with something else.
Unfortunately, the Allegro CL reader has been optimized to recognize parens, and thus is not general enough to do this. Perhaps there is another CL out there that is general enough. But conceptually, it should be easy to reconfigure both the reader and the printers (pretty and non-pretty) to recognize and print the following code:
[defun foo [a b] [let [[c [+ a b]]] [list a b c]]]
Which describes _precisely_ the same program in Example 1, above, or to recognize and print the following code:
[defun foo [] #\(]
as the same program as in Example 2, above. Note that my answers to the puzzle are much more evident in these textual representations than in the more traditional and standard CL representations, above.
Method 2: Represent code with pointers and pictures.
This is _much_ harder to do, and so I will create a more trivial example, the expression (+ a b), to illustrate. This is the way most lisp books teach inner lisp list structure.
The list (+ a b) is represented internally as
--------- ------- ------- | | | --> | | | --> | | | --> nil --------- ------- ------- | | | v v v
+ a b
Where each box represents a cons cell, with the left half being the car and the right half being the cdr.
In CL, a parenthesis is a mechanism to trivially transform between a textual representation of lisp code, and the lisp code itself. Some people call this code "the internal form", but I don't believe that this does it justice; I view it as the "real" form of the lisp code; it is simply a hard form to describe without a textual representation of some sort.
Finally, you have seen many Lispers point out that parens disappear for them. What is this phenomenon, and when does it happen? I believe that it occurs when the programmer realizes that lisp code is not "what you see", but instead what it actually represents.
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
* "felix" <fe...@anu.ie> | If you mean that the Scheme-standard is full of holes, yep, you're | right with that.
The Scheme standard is possibly the single best standard there is, and such as snotty remark as your betrays utter ignorance of its contents. Do yourself a favor, and don't do marketing for Scheme.
| But, I think I can very well take some of the most used Scheme | implementations and regard their behaviour as common practice.
There is no value at all in discussing them, since if you point out a problem in or with _Scheme_, somewhere, there is an implementation that gets that one problem solved in some way.
| No, I'm not talking about the language Scheme as defined in the | standards document, I'm talking about the language Scheme as | implemented, in "real live", as you call it.
Some of us like to program to specifications, not just hope it works.
| BTW, how many CL implementations adhere *fully*, 100%, to the | Hyperspec?
None. They adhere to the standard, ANSI X3.226-1994.
| I'm sure every implementation has it's little incompatibilities | (especially in a *huge* language like Common LISP).
Arguments from ignorance are _so_ powerful.
| Anyway, I think you are right in that the R5RS isn't really that | great. But Scheme (and many of it's implementations) is! ;-)
None have said that R5RS isn't great. It really is, as a standard. If you bothered to read it, instead of parroting comments you don't grasp, you would have the possibility of understanding this yourself.
The reason Scheme sucks, and it does, is that a beautiful standard is not enough. A necessary condition, but not a sufficient one in any capacity at all. If all the good stuff is extra-standard, the _language_ has serious problems.
| (Sorry, I couldn't resist, I just can't stop teasing ;)
I wonder who you think you're teasing, flaunting your ignorance.
#:Erik -- If this is not what you expected, please alter your expectations.
* Craig Brozefsky <cr...@red-bean.com> | That doesn't imply confusion and intimidation tho.
I think it does to a person who is stupid and incompetent in the face of complexity he is afraid of, especially if he has failed to handle some complex things in the past. Many programmers should never have started down that carreer path.
#:Erik -- If this is not what you expected, please alter your expectations.
I put that example on multiple lines to amplify the difference. You are right, it seems like a gratuitous use of indentation. In practice I might well write "(+ (* a b) c)" depending on the context.
For example:
define (foo a b c) let ... y (+ (* a b) c) print y
Someone else has suggested mapping the font of parentheses to another color or size. This would not work in my approach because I am not eliminating all parentheses, just the ones at the edges of expressions.
For example, the Scheme expression conatining parentheses:
define (foo x) print x
would be OK in the approach I outlined. Note this has a paren on a "edge", but it is not from the entire S-expression consisting of a line; instead it is related to an internal nested S-expression.
My current thinking is that as soon as the parser encountered an open paren, it would start using conventional Lisp reader parsing rules.
In this case, I think the only different behavior one encounters from conventional Lisp behavior (regarding parens) would be when one had multiple expressions on a top level line, like "reader> (foo) (bar) (baz)" which indentational syntax would parse as the Lisp equivalent of "reader> ((foo) (bar) (baz))" (because of the rule that multiple S-expressions on a line are gathered together as a list). Everything else I think would work the same, as this gathering rule would not apply once one had descended under the sea of parens with the first one, and until coming to the surface of that sea with the matching one. Obviously, this might in some cases make error detection and providing correction suggestions harder.
Regarding the "syntactic sugar" of "...", it is a needed way to indicate that a blank line represents the start of a nested list. I would be glad to see a better alternative. Right now, in terms of just textual represnetaion, instead of "...", I am considering "~", "[", "\" and ".". Of these, "\" and "[" seems the strongest candidates to me right now for various reasons. However, short of allowing indentation to increase by more than one step at a time, such an operator is unfortunately needed for this approach.
You may well be correct that I am overestimating one set of benefits and underestimating another. However, I hope Lisp developers might be willing to consider the same, if I have a working system which I can demonstrate and it works effectively. Since I do not have one yet, I am mainly looking for useful feedback at this point on refining the approach, and whether it can work technically -- whether or not it is desirable, which, frankly, I myself will have to see work in practice before I will make stronger arguments on its behalf. I obviously believe in its potential value, or I would not be pursuing it.
I do not full understand Lisp macros. I have a partial understanding of Scheme macros. So it may well be there is something fundamental I have missed. I would be grateful for an example of a macro where that macro can not be represented using syntactically significant indentation. I wouldn't say I'd be happy about it, but I would rather find out now than after investing time trying to make an indentational system work.
Your point on Python vs. Lisp is well made. There certainly are many advantages Lisp has that Python lacks when code and data have the same format.
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
> Paul Fernhout <pdfernh...@kurtz-fernhout.com> writes: > >(Quoting KMP example)
> >>infix > >> a*b+c > >> ^
> vs. Lisp prefix > >> (+ (* a b) c) > >> ^
> vs. proposed "indentational prefix" > > + > > ^ > > * a b > > c
> This is what I find most objectionable about this scheme. Instead of a > simple, robust, clean, unambiguous, one line expression, Paul seems to > find preferable a three-line, hard to visually parse, difficult to > properly quote on Usenet, over-white-spaced abomination. Pardon me if > I sound too grumpy about this.
> Instead of a proven, robust, reliable method of including bodies, for > instance, in let blocks, Paul seems to prefer introducing another > extra line containing some syntactic sugar '...'.
> Come on! Paul, you are totally underestimating the benefits of having > explicit parentheses, and totally overestimating the "benefits" of > making white space significant.
> If you really want to remove parentheses from your screen, have your > editor color them with a foreground color identical to your background > color. Then see how easy it is to write Lisp. Your editor will still > be able to indent using the invisible parentheses, so you'll get *all* > the benefits of your scheme, without changing Lisp one bit. I think > most programmers would quickly go bonkers using my method, which as > far as I can tell is equivalent in most respects to yours, except the > '...'.
> Yet another subtlety that I think is missed in this discussion is the > special treatment of certain macros, which take ordinary arguments and > &body lists. They get indented specially, in my experience, although > the Lisp reader doesn't care. Will this scheme enforce certain > behaviors on the part of the programmer for these macros to be > properly parsed???
> I think that whatever utility Python people get from their whitespace > is far overwhelmed by the utility that Lisp people get from their own > uniform, robust, unambiguous, and simple use of parentheses. Pardon me > if this is obvious to all you Lispers.
Thanks for this and the other great replies on this topic.
I picked up the concept of discussing "typography" as opposed to deep structure from your post on the future of editing programs. It is a great distinction.
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
> in article 39946CC5.625D5...@kurtz-fernhout.com, Paul Fernhout at > pdfernh...@kurtz-fernhout.com wrote on 2000.08.11 14:14:
> > Speaking in terms of psycho-physiology, it is hard to tell the > > difference between, for example, two or three parens, thus "))" is > > difficult to distinguish between ")))"
> Exactly. Simply from a typographical standpoint, long strings of parenthesis > are undesirable. However, the readability can be improved with a little > typographical help without changing the language. For example, outer > parenthesis can be displayed in a larger size, or a heavier weight, or by > using glyphs that have different amounts of curvature. Going further, one > can begin to vary the symbols used: {[(
> And I think the reference to typography here is of prime importance. > Parenthesis, white space, and semicolons, for example, are fluid things in > the world of publishing. They can be displayed in many different ways, to > make the text easier to read, and sometimes to add meaning.
> I hope that single-font, single-size, mono-space, plain text editors are > finally replaced by something richer soon.
> [And when I use the future tense in any of my postings on this topic, I'm > not trying to say that these haven't been tried or don't exist, but that > they aren't found in common usage. And if that isn't enough of a > qualification for some of you, I'll add: Found in common usage in the world > of consumer software development.]
> -- > Chris Page > Mac OS Guy > Palm, Inc.
> let mail-to = concatenate( "Chris Page <page", "@", "best.com>");
You are quite right in pointing out that parentheses are still supported in the approach. Here is my current thinking on them.
As soon as a paren "(" or quote paren "'(" is encountered, significant indentation and bracket rules are suspended until the close paren, to constuct an embedded S-expression. At that point, indentation rules resume as if the entire paren expression was a single item on one line. The start paren or quote of such an expression must still be indented properly however.
Example:
define foo '(this is a very long list of symbols being strangely wrapped) print foo
=> '(this is a very long list of symbols being strangely wrapped)
Note however, that more than one parenthesized S-expression on a line outside of a parenthesized expression will still be taken together to form a list.
Thus, in indentational syntax:
(foo x) (bar x) (baz x)
is equivalent in conventional Lisp syntax to:
((foo x) (bar x) (baz x))
which is not what someone used to working in the old convention might expect for evaluation of a top level line.
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
> in article sfwg0obr9di....@world.std.com, Kent M Pitman at > pit...@world.std.com wrote on 2000.08.11 10:32:
> > Consider, by contrast, infix languages where you have a situation like:
> > a*b+c > > ^
> > with the cursor at the indicated point and you want to grab the expression > > after the cursor. You can't. You don't know if "the expression" is a, > > a*b, or a*b+c because the situation is ambiguous.
> This may be a bit difficult with some text editors, but it doesn't mean that > it can't be handled. Take a look at Graphing Calculator (the one that comes > with Mac OS) for an example. When dragging the mouse over an expression it > automatically selects sub-expressions, rather than just characters. If you > drag over "*b" it selects "a*b". If you continue dragging to include "+", it > selects "a*b+c". [If you actually try this, you'll find that it doesn't draw > the "*", since "ab+c" is sufficient.]
> There's an implicit set of parenthesis around the entire expression and > precedence implies internal parenthesis. They're there, they just aren't > displayed -- for clarity.
> Of course when you say "the situation is ambiguous" you mean "the situation > is ambiguous for a text editor that knows nothing about the language". If > nothing else can be learned from the example of emacs, it must be true that > (at least some) people desire smart editors.
> > My concern would also be about subtleties like: > > (setq x f) > > vs > > (setq x (f)) > > Were I to replace parens with indentation, it's not obvious to me how to > > easily distinguish these two items. Do I add "a little extra" identation > > for the second? That would be awful.
> I'm pretty sure the original proposal for indentation-sensitivity allowed > for parenthesis to remain in the language. So you could keep the parenthesis > around "f" if they're significant. I think all you've shown is that > programmers would still need the option of using parenthesis.
> -- > Chris Page > Mac OS Guy > Palm, Inc.
> let mail-to = concatenate( "Chris Page <page", "@", "best.com>");
I guess I am seeing Lisp or Scheme programming right now as primarily involving defining tree structures. That is done with a typographical convention involving nesting parenthetical lists.
I have no interest in replacing the parens with similar character symbols or other graphical contentions (although that certainly is an interesting idea, and could be quite useful for illustrating to newbies how Lisp works, as such diagrams are frequently seen in introductory texts at the start.)
If Lisp code is what it represents, than one could view what I am proposing as a way to create Lisp and Scheme representations so that "what you see" is as close as possible to that underlying structure, with a minimum of extra characters, given that 2D space layouts can in some circumstances make sense to the human eye. In effect, I am trying to make the tree structure implicit in all Lisp S-expressions explicit on the page, and without anything unneeded.
[Yes, I know in Scheme for example you can define joined branches to form a web using special techniques, etc.]
I really am trying to look into the possibility of a fundamental improvement in Lisp language family typography -- hopefully without affecting any other aspects of the language. My direction is in the direction Edward Tufte might call "removing Chart Junk" where I define edge parentheses as "Chart Junk". I can't say Tufte would necessarily agree with anything I have said, but I certainly personally feel the use of syntactically significant indentational whitespace in programming languages would be something he might find interesting and of which he might approve. Anyone out there at Yale and also willing to ask him for an opinion?
I have been thinking of moving to indentation style of one space only, on the argument the burden of proof should be to show this is not enough to distinguish nesting levels. The advantage to this approach is then a single space key press nests an expressions, and a single delete key press unnests. So there is a direct mapping of single common keystrokes to list sub-expression promotion and demotion. Obviously, a fancy editor or printing package could know if desired how to draw spaces to the left of expression perhaps much wider than spaces within expressions, or to draw such spaces using other conventions.
My current thinking on indenting is below. Note that parens suspend indentational syntax rules and revert to regular conventional Lisp parsing rules (explained in other posts).
========= Indenting Rules ================
Indenting is done by a single space. [Previously I had suggested two spaces, which was similar to Occam.]
A line containing one expression (symbol, list, quoted list) returns that expression, unless it has children. These expressions are processed using conventional Lisp S-expression rules.
Example:
define foo "hello"
is equivalent to:
(define foo "hello")
A line containing two or more expressions, or one expression with children, returns a list of those expressions.
The only equivalent to the paren I have been thinking about is the idea of a bracket which is automatically closed at the end of a line. This would take the place of the "..." I introduced in the original proposal. I think using an open bracket is a real possiblity. However, I am also considering the "\" symbol, which sort of indicates indentation to me (implying the following is on a lower level sliding down the symbol). I might have used "/" except for it's meaning as divides, and "." except it has several menanings in Lisp already. I don't think "\" has a meaning outside of a string (in Scheme at least). [Feel free to point out a useage for "\" if I am wrong -- I haven't researched this one detail very far.]
Here is my current thinking on this idea of terminating common short lists at the end of a line:
========== Bracket Rules ================
If starting a line by itself, an open bracket indicates start of list (with children or empty)
Example:
define (foo) let [ x 10 print x
is equivalent to:
(define (foo) (let ( (x 10)) (print x)))
Example:
define empty-list quote [
is equivalent to:
(define empty-list (quote ())
Example:
define (print-sum) print [ + 2 3
is equivalent to:
(define (print-sum) (print ( + 2 3)))
If starting a line with one expression (symbol or parenthesized list, or quoted list), an open bracket indicates a list containing that expression as a single element.
Example:
define [print2 print "2"
is equivalent to:
(define (print2) (print "2"))
If starting a line with two or more expressions, an open bracket is ignored, except as a placeholder if there is another bracket following.
Example:
define [foo x [print x
is equivalent to:
(define (foo x) (print x))
Example:
define (foo x) let [[x 10 print x
is equivalent to:
(define (foo x) (let ((x 10)) (print x)))
Note that both open brackets are required, lest "[[x 10" be interpreted as just a list of "(x 10)" as opposed to the list of a list as in the expression "((x 10))".
If in the middle of a line, an open bracket indicates the start of a list that ends with the end of the line.
Example:
define [foo x print x
is equivalent to:
(define (foo x) (print x))
Example:
define [foo let [[x 10 print x
is equivalent to:
(define (foo) (let ((x 10)) (print x)))
Undecided: close brackets are optional? Or are not allowed?
* The quote operator or "'" works the same as in Lisp/Scheme.
Example:
define foo '[1 2 3 4
is equivalent to:
(define foo '(1 2 3 4))
==================================
An example in indentational Scheme:
; let for only one variable define let-be 'to-be-written
; for-in works like python "for x in array:" define for-in 'to-be-written
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
> Paul Fernhout <pdfernh...@kurtz-fernhout.com> writes:
> > Paolo-
> > Mostly that impression is from comments on this newsgroup to this > > posting. The possibility that an indentational syntax might make cut and > > paste more difficult seems to be a source of strong objections to an > > indentationally significant syntax (not that there aren't others).
> I think that the reason why you are seeing so many objections to the > idea of removing parens in lisp is due to a subconscious mental process > that nobody has yet been able to articulate, though some have come very > close by noting the code-and-data aspect of lisp. Let me try to make that > articulation, by posing a puzzle:
> How many parens, left and right, are in Lisp code?
> Answer: very few.
> To illustrate this, let's take a couple of examples:
> Example 1:
> How many parens are in the following code?
> (defun foo (a b) > (let ((c (+ a b))) > (list a b c)))
> Answer: 0
> Example 2:
> How many parens are in the following code?
> (defun foo () > #\()
> Answer: exactly 1 left paren.
> The problem with actually _describing_ the lisp code that is > associated with the above _text_ in a newsgroup such as this > one is that the communication must be made by textual means, > and thus the program content cannot be easily transferred without > using some representation that would probably include parens.
> Let me buck this tendency, however, and show you two ways to > represent a lisp program without parens:
> Method 1: Replace parens with something else.
> Unfortunately, the Allegro CL reader has been optimized to recognize > parens, and thus is not general enough to do this. Perhaps there > is another CL out there that is general enough. But conceptually, > it should be easy to reconfigure both the reader and the printers > (pretty and non-pretty) to recognize and print the following code:
> [defun foo [a b] > [let [[c [+ a b]]] > [list a b c]]]
> Which describes _precisely_ the same program in Example 1, above, > or to recognize and print the following code:
> [defun foo [] > #\(]
> as the same program as in Example 2, above. Note that my answers to > the puzzle are much more evident in these textual representations than > in the more traditional and standard CL representations, above.
> Method 2: Represent code with pointers and pictures.
> This is _much_ harder to do, and so I will create a more trivial > example, the expression (+ a b), to illustrate. This is the way > most lisp books teach inner lisp list structure.
Still, there are some surprising things that are relatively easy to do with an indentational syntax that don't require signifianct editor support. In an indentational syntax, every line starts an S-expression, and thus one can switch S-expressions mainly by just using the up and down arrow keys. Embedded S-expressions may be defined using parentheses within a line, and so do cause more difficulties (perhaps severe ones, although in practice we will have to see).
It is quite possible that similar operators to the ones mentioned for emacs could be made for an indentational syntax. Do I have such operators at the moment? No. Will I? Probably not as long as I keep spending most of my free time replying to this thread. :-) And also, since at the moment I use DrScheme and not emacs, there is no particular reasons for me to enhance emacs. DrScheme may be a different story, and then some of those ideas might be applicable to emacs.
However, many editors support block-shift-left and block-shift-right, so I think this particular issue you raise at the end is already handled to an extent with a minimum of keystrokes in practice. Will it always take more keystrokes on average than a fully parenthesized system, requiring only a paste and reformat? Perhaps. Perhaps not.
Could all this be handled even better in a specialized emacs editing mode for indentational syntax? Most likely yes, given all the great things people say about emacs. Given the hybrid of indentational and parenthesization allowed, this mode might require some sophisticated coding.
To address your point in terms of future possiblities made easier by indentational syntax, imagine basically dragging and dropping Lisp expressions in a hierarchical tree editor on nested S-expressions.
Will such a mode ever be as good as what people have now for fully parenthesized expressions? I don't know. We're comparing several decades and hundreds of person-years of Lisp editor development against a new(?) proposal.
Obviously, one of the drawbacks of anything new or better (not to insist this proposal is necessarily either) is that the existing system is in place already and working. I guess this is one of the reasons "Worse is Better", even when it comes to something about Lisp. <Ducks...> :-) http://www.jwz.org/doc/worse-is-better.html
(?) -- no one has yet pointed out this exact thing has been tried with Lisp. I still find that hard to believe...
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
> * Paul Fernhout <pdfernh...@kurtz-fernhout.com> > | On a tangent, could it be that the reason for a lot of cut and paste > | in Lisp is precisely because it is so hard to get all those > | parentheses consistent or configured correctly for a specific > | operation (when typing them in by hand)?
> There isn't "a lot of" cut and paste in Lisp, but _when_ you want to > move or copy whole expressions, Emacs users double-click on one of > the parentheses and the whole expression is instantly highlighted > and ready for copy (at least under X -- Windows requires a lot more > manual labor, as is usual). This is even used to see the whole > expression better in a nested form. Also, when people need to move > expressions around, they have tools in Emacs like transpose-sexp, > which I suppose you would do with transpose-lines or something...
> I once said: "Those who do not know Lisp are doomed to reinvent it" > in an Emacs setting. This is a Lisp setting, so maybe I should say: > "Those who do not know Emacs are doomed to reinvent it".
> | I'd like to come to a full understanding of what exactly it is about > | indentation that makes cut and paste in Lisp so awkward.
> Suppose you have an expression at indentation level N. Copy it to a > place where indentation level M prevails. How much work do you need > to do to get the indentation right? In a fully parenthesized Lisp, > you have tools to do this for you. In a less parenthesized Lisp, > you have no tools, but must shift the newly copied block of code > right or left more or less by hand.
> #:Erik > -- > If this is not what you expected, please alter your expectations.
Thanks for the reply. You make some excellent points.
When discussing "error free" editing, I guess what it comes down to is that the types of errors one can make using indentational syntax are usually different from the ones made with explicit delimiters. Certainly most programmers are used to explicit delimiters, and so one might expect them to make less errors in that context as it is what they are experienced with. And obviously, if the editing tools are set up to support delimited syntax, that too makes it more likely programmers will be more productive in such a setting. Whether indentational syntax used for Lisp/Scheme in the hands of experienced programmers can ever meet the standards of excellence maintained by programmers using the conventional syntax is to me still an open question (although obviously many people in this thread have pointed out difficulties which may or may not be insurmountable in practice).
While I agree that an indentational syntax seems to put a heavier burden on the programmer in terms of managing structure, it seems to me that in some ways it just makes a burden that already exists more explicit, both because the hierarchical structure of S-expressions is always visible, and because it can be changed rapidly -- perhaps too rapidly, :-) as you point out. The indentational syntax gives one a powerful tool to rapidly change structure by deleting or adding some whitespace. One might argue that managing whitespace is like having a chainsaw. Obviously, a chainsaw is a dangerous tool -- and depending on the context, may be quite inappropriate for the task at hand. I do remember seeing someone sculpt wood with a chainsaw once -- most impressive (and scary!)
Still, ultimately, I am intrigued enough by it that I'd like to get to the point where I could see it fail or succeed in practice. Famous last words... :-)
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
> In article <39929AF6.AA334...@kurtz-fernhout.com>, > Paul Fernhout <pdfernh...@kurtz-fernhout.com> writes: > > ... > > But, I think in practice, when indentation is significant, people tend > > to always do formatting right away when cutting and pasting anything -- > > so as to always maintain the logical structure of the program. So, I
> true, but contrary to the delimited syntax the whitespace syntax does > rely on errorfree editing. in my experience (maybe it's just me, it > is quite easy to put the mark in the wrong place, leading to errors > that can be very hard to track down. with a delimited syntax you the > cutted and pasted code being transferred with its delimiters simply > doesn't raise this problem, and if you made a mistake when cutting > (leaving out or adding a delimiter) you most likely will get a syntax > error.
> > don't see this being a big problem in practice, and in the Python or > > Occam case I don't remember ever experiencing such a problem (at least > > not down the road -- it may have been more of an issue at the start).
> the problem with the white space syntax as i see it: provided the > delimiters in the delimited syntax aren't too verbous, it buys you > very little in typing effort (in emac's python mode you have to use an > extra keystroke to indicate that you want to revert the indentation to > the previous level (at least most of the time), but it removes > valuable redundancy what you have when you combine a delimited syntax > with a pretty printer, where the programming environment uses what you > typed to put the structure of your code on display. i actually would > argue that the whitespace syntax, rather than being helpful and save > the programmer some work transfers a much harder burden (to keep track > of the structure) to the programmer.
> I find typing an extra parenthesis no more burdensome than to hit a > key to tell the editor to reverse the indentation. it might be a > little bit differend with very verbose delimiters (like mandatory 'end > keyword' etc)
If that style seemed heavier to parse, then how about this?
let [[ b (cdr x) doo b and (worth-it-p b) (pay b) bar b sting-like-a b
It uses incomplete bracket notation (list ends at end of line) and embedded paren expressions (which are parsed using regular conventional lisp parsing rules).
The original for comparison:
(let ((b (cdr x))) (doo b) (and (worth-it-p b) (pay b)) (bar b) (sting-like-a b))
Thanks for your post!
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
Thanks for the pleasant message. Some comments below.
Lars Lundback wrote:
> Paul,
> Thank you for introducing and keeping this particular thread alive for > so long. You have a nice way of saying things, and it is always a > pleasure to listen to friendly discussions.
You're welcome. Thanks for the compliment.
I should say people like Eric Clayberg and James A. Robertson on comp.lang.smalltalk are my role models. I've learned a lot from seeing how they respond publicly in their posts.
I've certainly learned a lot from this thread. Although at some point I'm hoping things wind down so I can put more time into implementing something. :-)
> I see that you move away from syntax, towards some kind of program > source editor that you outlined in your RFC. Such a programmer's tool > for Lisp-like language constructs, seems more appropriate than dealing > with Lisp syntax itself. The code eventually generated would contain all > the parenthesis needed by Lisp. (?)
That's the way I'm leaning towards at this point. My first approach if I pursue it is to have something that can read the syntax from a file and generate parsable Scheme code.
> Your code examples triggered my memory. I remembered some feeble > attempts of my own, along these lines, some 15 years ago. At that time, > I had to introduce (Common) Lisp to our students in the mechanical > CAD/CAM domain, and tried to do away with parenthesis, at least in > application programming.
Interesting.
Obviously I've seen Python and Occam which both use significant indentaion. Actually, as I think on it, I vaguely remember someone (at CMU? NC State?) perhaps mentioning casually to me a dozen years or more ago that indentation could replace parens (I can't remember specifics, although I do remember doubting it!). I don't claim this idea to be uniquely original, although I still haven't heard of an actual Lisp that uses it. Yours sounds close -- although it seems perhaps you are describing a "little language"?
> I would like to disregard the tool and the interaction with it. It was > said before: of course it can be done.
> Others have already stated how important the parenthesis are, when > dealing with Lisp code. So do I, they are _not_ noise. In fact, when > looking at your version, I find that my eyes "fall off" the line edges.
OK. And I can understand things more better from the way you put it as "falling off the line". That is an interesting point. Sort of like safety rails for the eye. I'll have to consider that.
On what I mean by "noise"...
Maybe "noise" isn't the best term because it does sound derogatory. I am trying to use it in an engineering sense on the one hand, and admittedly in an aesthetic sense on the other hand.
However, I have always tried to call it "high frequency noise" and not just "noise". What I mean by "high frequency noise" is simply that "((((((" looks a lot like "(((((". They are both "noisy expressions" in the sense of presenting lots of things that seem to demand attention. Also a row of parens compared to a mix of other characters sets up a certain visual effect (almost a Moire pattern?). http://www.sandlotscience.com/Moire/Moire_frm.htm Although now that I think about it, if serifs and such on characters are tinier, they are really higher frequency. So perhaps I should say repeated parens are "low frequency noise"? Of course, low frequency noise can be that sort of bass rumble from a thunderstorm that sets dogs to barking...
> The "de-parenthesised" version may look easier to a non-Lisper. There is > a superficial resemblance to ordinary text, and indentation seems to > convey structure (although not to me).
OK. However, I am trying to convince myself (perhaps by trying to convince others) that indentation can convey meaningful structure -- enough to define arbitrary S-expressions.
> However, the "extra" parenthesis were no burden to some of the students, > once they got past the initial shock. Those that didn't, were unsuited > for programming/problem-solving in the first place, and the > first example had not helped them any.
Well, there are many types of people with many different abilities. And the woods would be very quiet if no bird sang there but the best... That being said, obviously not everybody is suited for everything.
It seems to me that many people never get over the shock enough to even give Lisp family languages a chance. Obviously if you are taking a class on it you may be motivated. But there are so many programmers out there who could learn Lisp who don't. And I think one reason is the typography. Even if it is only a one hour hurdle -- maybe that is too much, given all the other alternatives (mainly C/C++ and VB), and the fact that Lisp is the underdog (along with Smalltalk and Forth and lots of other languages people shy away from due to other minor hurdles).
> I think there is a place in this world for your fewer-parenthesis > scheme. Excuse, I couldn't resist. :-)
:-)
> A bounded, application-oriented language (perhaps with a Lisp touch) is > probably best. If the vocabulary and syntax is well matched against the > domain, "superfluous" parenthesis can be avoided. But indentation as a > replacement generally for the lists' parenthesis? I don't think so.
Well, I'll have to see how far it gets me before it runs out of gas. I'm not actually trying to convert anyone at this point. My major reason in starting this thread (beyond of course fame or notoriety as fate deals it :-) is to see if syntactically significant indentation had been done before in Lisp or Scheme, as well as whether there were any obvious technical holes in the idea of representing S-expressions using indentation (none so far, although obviously people point to other practical difficulties).
I'm mainly thinking about using this syntax myself to build an application in DrScheme. That would at least give me a little practical experience with the concept.
If I can just get a first translator going... Then I can bootstrap the parser in itself.
> Lars
> PS. (A slightly similar topic, about where to put trailing parenthesis, > was very hot in this group some time ago. That discussion sort of > resolved itself, once the prerequisites of the programmers' situation > (ICAD in that case) were visible to us.)
Thanks for the pointer.
Well, of course, I might say that trailing parentheses are superfluous.
Actually, I'm looking at extending this approach to include a bracket notation where the bracketed list ends at the end of the line. Thus:
define [ foo x let [[ y 10 print [ * y x
as equivalent to:
(define (foo x) (let ((y 10)) (print (* y x))))
Thanks again for the great comments and kind words.
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
Paul Fernhout <pdfernh...@kurtz-fernhout.com> writes: > Duane-
> A very thought provoking post. Thanks!
You're welcome.
> I guess I am seeing Lisp or Scheme programming right now as primarily > involving defining tree structures. That is done with a typographical > convention involving nesting parenthetical lists.
Yes, and tree structures are often represented textually in intented outline form. However, it is a very space-intensive representation, and takes up a lot of vertical real-estate.
> I have no interest in replacing the parens with similar character > symbols
But don't you see? That's precisely what you're doing! You are replacing some of the parens with newlines and appropriate tabs. There are two ways to do this:
1. Replace _all_ parens with newline/tab combinations for a completely paren-free representation.
2. Replace only parens that span across line boundaries, leaving parens intact within a line.
#1 has the disadvantage of being extremely wasteful of vertical space. I assume from your posts that you do not propose or approve of this method.
#2, which you seem to be espousing, is more complex because it does not have one way to represent form, but two. This carries with it the added burden of not being able to see that two forms are identical. Note that you give an example of precisely this ambiguity:
> Example:
> define > foo string > print string
> or:
> define (foo string) (print string)
> is equivalent to:
> (define (foo string) (print string))
Note that the traditional lisp/scheme syntax has only one form of the expression, though you have much freedom to add or remove line real-estate to make the form more readable, as in
(define (foo string) (print string))
or
(define (foo string) (print string))
Though the lines are different, the forms are the same and retain their identity no matter how you edit them, and comparison tools that ignore whitespace will tell you that the forms are all identical. Your proposal does not allow this. In fact, the only way to actually make it consistent is to go to style #1 (above) and remove the redundancy that hybrid indentation/parens gives.
My final points are
- Parens _are_ the simplest representation of the "internal" lisp code structure, and all other ways to represent such structure are either identity transforms on the paren style, or else more complex.
- If you want to program in CL, you need to get past the syntax issue and learn how to program lisp code, rather than worrying about text. If you are coming from a scheme background, it will be harder, but a few months diving into a well-written CL program will give you a good feel for why CL programmers tend to ignore the paren issue.
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
> In article <3992235B.5C9B7...@kurtz-fernhout.com>, > Paul Fernhout <pdfernh...@kurtz-fernhout.com> writes: > > I think, for example, this:
> > define (foo x) > > * x x
> > is less intimidating than this:
> > (define (foo x) > > (* x x))
> > for someone not used to dealing with lots of parentheses.
> I think someone who isn't used to dealing with lots of parentheses has > insufficient experience to be able to pass judgment on whether Lisp is worth > investigating further.
While your point is well made, unfortunately for Lisp's rate of adoption, many programmers are passing judgment on it based on a few minutes spent looking at it, and others after just one class. This may not be fair, or even smart, but it is more or less what happens in practice. (Obviously there are other factors as well.)
"Worse is Better" is a nice essay that makes a Lisp developer feel good, http://www.ai.mit.edu/docs/articles/good-news/subsection3.2.1.html but sometimes it is the elephant in the living room that no one wants to talk about. (For the record, I think there is a lot of truth in the "Worse is Better" essay.)
For example, I last read this entire article a couple years ago: http://www.ai.mit.edu/docs/articles/good-news/good-news.html but I don't recall it mentioning parentheses much. Does it? There is not a mention of parentheses on the first page. Yet at this point Lisp code appearance represents a major hurdle to Lisp family language adoption -- even if parentheses work well in practice.
In my case, I am "passing judgment" on Lisp based on about three to four person months spent with the language in chunks of a few weeks spread over about twenty years. Is that fair? Maybe not, but that's the situation.
And of course, to an extent, I also have to justify my decision to use Lisp or Scheme to a business partner who has never programmed it at all and has already expressed some displeasure with its parentheses. Frankly, I think a lot of Lisp programmer "wannabees" may be in a similar situation of having to justify the language to management who may not have gotten over (and may never get over) the parentheses hurdle.
Yet, I think Algol-like Lisp hybrids like Dylan, NewtonScript, and Python don't quite have the charm of the Lisp language family prefix notation approach (not to say they don't each have interesting features and things at which they excel). I believe the approach I outlined to be in a very different class from these attempts because I suggest an absolute minimum set of changes targeted purely at one issue -- minimizing edge parentheses made redundant by syntactically significant indentation. Everything else about the language stays the same, so much that I am hoping a preprocessor of a page of code or so can do the translation.
Even if the reaction of novices to the parentheses may not in the end be justified, one can't deny the initial reaction many people have when confronted with a Lisp program. That is a problem reducing Lisp and Scheme adoption rates, whether or not dealing with parentheses are a problem in practice.
And I may point out, I take great pains to separate the concept that I see Lisp having a disadvantage in this area (perhaps surmountable with experience) from the issue of whether overall the advantages to using Lisp outweigh the disadvantages, taken as a whole. To any non-Lisp developers out there, I am not saying "don't learn Lisp or Scheme because of parentheses". <- not saying this! I am saying "Lisp or Scheme are great languages to learn and they are worth learning despite any initial discomfort with parentheses". But to the Lisp developers out there, I would still like to say, "let's admit there is an acceptance issue or entry barrier and try to find a way around it". My way around the entry barrier is to explore indentational syntax. There may be other ways having more to do with education or presentation.
> And someone who _is_ used to dealing with lots of > parentheses is unlikely to notice that they are there -- as many Lisp > programmers report.
Obviously, most or all Lisp programmers would agree with you. But this is true for many situations where one picks up a learning curve and learns to "chunk" a complex problem domain or complex visual input (like a chess board). Ask a 747 Pilot whether the cockpit seems complex and I'm sure they will point out how it is second nature to them where everything is. But, that does not prevent research on new pilot interfaces -- especially ones that make certain common errors less common.
> It seems misguided at best to optimise for novices, > especially for a programming language: one hopes and expects that people > remain novices for only a vanishingly small fraction of their lives as a > programmer.
While I think removing edge parentheses may have benefits for novices, I admit that I don't know for sure, and it may have no benefit, or even make it harder for novices to learn Lisp.
The major thing that drives my approach is admittedly my own sense of aesthetics after having programmed in a wide variety of languages for 20+ years (including a small amount of Lisp in several small projects). Lisp S-expressions defined in an indentational typography are the closest I have been able to come so far to defining a "spare" language with no excess characters -- one that is primarily just naming and structuring. I think this approach may hold benefits for novices and experts alike -- but I have no proof.
And, I admit, not everyone may see something like this as clear:
define (hello-world) print "hello world"
(hello-world)
> > Meaningful hierarchical indentation is often encountered outside of > > programming. People use it all the time to make outlines. People write > > pseudo-code using meaningful indentation.
> Precisely. This is one of the complaints I have with the way Python does > things. I've heard Python programmers saying that Python syntax is > `parsable pseudo-code' or some such -- but none seem to realise just how bad > an idea that is.
I think the phrase Python programmers use is "executable pseudo-code" meaning that it looks like pseudo code but it actually runs and works.
This slight difference weakens the following point you made.
> The point about pseudo-code is that it's a helpful, > abstract notation _for_humans_. Pseudo-code isn't given to compilers to > deal with. It isn't read and stored as data. It isn't passed around via > lossy communication channels which have problems with whitespace. Most > importantly, though, it tends to be written once, and deleted once finished > with. This means that certain of its properties (that it can be hard to > parse unambiguously, that its textual representation is far from robust, and > so on) aren't a problem. However, when you use such notations for real > code, these things can make you lose big.
I can see how one can fool oneself with pseudo code. That is quite true.
It is also true tools and channels have problems with whitespace. However, if the channels don't preserve white space, then one needs to work around this -- like using Zip files to transmit code and such. Or one needs to upgrade editors. Obviously this assumes the benefits are worth the upgrades. I feel they likely are, but I'll admit I have little direct proof at this point, because I have never written a serious program in this Lispish indentational syntax (beyond coding the simple examples). However I have written bigger programs in Python and Occam and they worked well and were maintainable (IMHO).
I actually find it ironic that probably most Lisp developers responding to this thread are in all likelihood using a mail reader that shows them the threaded discussion as a hierarchical tree. Thus, the very tool Lisp developers are using to say indentation isn't good enough to present structure (without parens) is itself indentationally based and has no parens. Obviously this analogy has some limits. One doesn't usually rearrange mail items in the tree, so this point does not apply well to arguments related to the potential fragility of such structures. But I still think there is some truth to this point.
> Aaron Crane <aaron.cr...@pobox.com> <URL:http://pobox.com/~aaronc/> > ** Please send on-topic followups by Usenet, not email **
Thanks again for your comments.
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com
> Paul Fernhout <pdfernh...@kurtz-fernhout.com> writes:
> > > As for Lisp, the joy of Lisp is in the parens!
> > They certainly are elegant and consistent.
> I think Paul is being too genial here. I think that the Joy of Lisp > comment was kinda silly.
Actually, I did like it. My thinking was: Lisp is elegant and powerful because of S-expressions. S-expressions are defined typographically using parens. Thus parens are the joy of Lisp. Guess I missed Glauber's 5 point joke!
> Sometimes you have to be cruel to be kind.
True. But one can be polite at the same time too.
Actually, I'm really mostly just a guest here... (Maybe I've just contracted too much, too!)
> > > The reason i don't use Python anymore and i hope > > > never to have to use this kind of language again is simple: even though > > > my indentation is always correct and perfect :-), my colleagues are not > > > as good as i am in choosing a system and sticking to it.
> > Interesting point.
> C'mon now. This "point" makes no sense at all. So you had to abandon > Python not because it wasn't good enough for the task, or because you > didn't like it, but because your colleagues couldn't keep up with you? > Please don't tell me you switched [back] to Common Lisp. I would > hardly believe it. I also don't see what "this kind of language" is > referring to (i.e. what language feature?). If it is the indentation > thing, then what are you talking about when you say "choosing a > system"? Are you colleagues unable to figure out when to press the > <ENTER> key in Emacs? I'm trying to understand this, being that most > software development problems are so much harder than what your > colleagues were supposedly having difficulty with. Were you guys > writing "hello world" in different tongues?
As Glauber points out in his reply to your post, this actually is a big problem in practice preventing the adoption of advanced technologies. It is sort of a "network effect". In a big company, a manager has to judge if the value of a few productive people if more than than the value of a large network of less productive people. This decision is only made harder by the fact that programmer productivity can vary by almost two orders of magnitude (or more when a good programmer just points out not to do something silly and to do something sensible instead -- at the application design level or requirements level) and also that some programmers even have a net negative contribution to an effort. (Frederick Brooks book "The Mythical Man Month" goes into this in some detail.) http://slashdot.org/books/980805/1148235.shtml
Luckily, we're a two programmer shop, so if we can find a tool that gives us an "edge", we have some hope of going with it.
It was in working with the language Forth that I first encountered the saying (by Chuck Moore I believe?) that most computer languages are levelers (all programmers produce about the same medium level), but Forth was an "amplifier" (a bad Forth programmer was a disaster, a great Forth programmer a god.)
Realistically, management wants predictable languages that are "levelers" (like Visual Basic) because generally the cost of person-years for software development (in a typical large company doing mostly in-house work) is a small part of the total costs of the operation and marketing for the related services. Thus management often thinks they can afford to be "wasteful" to ensure predictable linear programming success.
Good programmers on the other hand, often want amplifiers... They also know what management often doesn't want to know -- that complexity grows and grows and grows, even if you add to it in only "leveled" pieces. The leveler tools often can't handle more than a modicum of complexity, because their underlying data and programming models are sophisticated enough. As application size grows, it goes through chaotic phase changes to new levels of complexity, where new approaches must be rapidly put in place. (There is a book on this topic but I can't remember the title.)
Obviously the value to Lisp family languages is that they are good at handling complex tasks, which in the end is what many business and other tasks become given enough time.
Nonetheless, maybe within the Lisp family languages, syntactically significant indentation could be an amplifier, and parentheses could be a leveler? <Ducks...> (But sometimes you have to be cruel to be kind.) :-)
-Paul Fernhout Kurtz-Fernhout Software ========================================================= Developers of custom software and educational simulations Creators of the Garden with Insight(TM) garden simulator http://www.kurtz-fernhout.com