[E-Lang] of historical interest only...
zooko@mad-scientist.com
zooko@mad-scientist.com
Thu, 01 Mar 2001 22:37:45 -0800
I had written an unfinished plea to make parens required on functions,
when I read that MarkM had already done so. For the record, then, here
is the opinion of "Zooko the Picky Programmer" on optional parens.
Regards,
Zooko
------- Forwarded Message
To: markm@caplet.com
Subject: Re: [E-Lang] newbie syntax: picayune points from a prejudiced programmer
In-Reply-To: Message from Ben Laurie <ben@algroup.co.uk>
of "Thu, 01 Mar 2001 11:34:04 GMT." <3A9E33AC.54717F4@algroup.co.uk>
References: <E14YIB7-0001cB-00@imp> <3A9E33AC.54717F4@algroup.co.uk>
From: zooko@mad-scientist.com
Date: Thu, 01 Mar 2001 21:49:51 -0800
Wow! Your flexibility ("rationality") on the matter of syntax (which
is, after all, mostly a matter of taste) astonishes me.
I won't bother sending to the list, then, this unfinished advocacy for
required parens on functions.
Regards,
Zooko
P.S. Sorry about zooko.com bouncing. Fixes are wending their way
through the depths of DNS. zooko@mad-scientist.com continues to work.
Ben Laurie wrote:
> > Don't bother. I don't want to know the underlying design decisions.
> > All functions should be invoked as `barf()' because that is how C,
> > Java, Perl and Python do it.
>
> Oh no it isn't! Brackets are optional in Perl (even if you have
> arguments).
>
> open F,'somefile' || die "Can't open somefile";
>
> will not die if the open fails, whereas:
>
> open F,'somefile' or die "Can't open somefile";
>
> or:
>
> open(F,'somefile') || die "Can't open somefile";
>
> will.
Ugh. This is an example of why I hate Perl. I learned Perl at
DigiCash and then used it to maintain the "buy stuff with ecash" cgi
scripts that Deutsche Bank supplied to participating merchants.
I always put `()' on each function invocation.
Presumably I knew that this was optional at the time (I did, after all,
manage to read my predecessors' code at least a little bit, if not
comfortably), but I've long since forgotten. In any case, I ended up
tossing out all of the code and writing everything from scratch so that
I could make the script into more than one function, document the
function arguments, etc.
Hm. I think there may be a theme here. Language designers and genius
programmers want the syntax to be the minimal necessary to make the
meaning clear to an interpreter. Newbies (and also experienced
programmers, if they are of the obsessive-compulsive variety such as
myself), want syntax to be consistent and to "show the way".
I want to look for `()' when I am learning the language for the first
time, or when I am reading someone else's code, and know that I now
have *all* of the invocations in my mind's eye. I want to scan,
without reading, down a page looking for the next time someone invokes
a method of the `foo' object, which I do by seaching for "foo.___()".
I want to look for non-optional enclosing curly brackets and know where
the blocks are.
One important characteristic of newbies and less-than-genius-level
programmers is that they haven't yet grasped, or they have already
forgotten, much of the actual semantic rules of the language. This
should be triply true for E, where the semantics are subtle and
flexible and include several unfamiliar features.
This means that you cannot expect them to understand the *reason* that
a certain syntactic construct which is superficially similar has
different meaning. It also means that they depend on syntax, even
when it is technically unnecessary, to remind them of the underlying
meaning.
Tyler's example:
def hello() :any {
"hello"
}
def greeting := hello run()
def greeting := hello run
def greeting := hello()
def greeting := hello // wrong
Is, frankly, infuriating to me in the same way that Perl syntax is
infuriating. I want the syntax to help me predict the semantics, and
in this example it is misleading me.
Hm. Perhaps part of why this is so offensive to my eyes is that
I don't have a syntactic clue reminding me that `hello' is an object
and `run' is a function...
def greeting := hello.run()
def greeting := hello.run
def greeting := hello()
def greeting := hello // wrong
Hm. The first and third lines look better to me now, but the second
line looks like it is assigning `greeting' to reference the thing that
`run' references. Oops.
I would be happiest if the only valid
def greeting := hello.run()
def greeting := hello()
------- End of Forwarded Message