multi-line expressions (was Python had a little lambda ...)

Chris Hoffmann (choffman@vicorp.com)
Thu, 24 Feb 94 14:08:17 EST

>> On Feb 23, 21:49, Bennett Todd wrote:
>>
>> >
>> > Can this lambda support multi-line expressions? If not, is there any hope of
>> > getting one that can?
>> >
>>
>> The problem with multi-line lambda's in Python is:
>> How do you embed one in a function using INDENT/DEDENT syntax ?
>>
>> ( And remember my complaints about not being able to do:
>> "for x in seq : if f(x) : do_something" all on one line. )
>>
>> There would need to be a explicit printable symbol for the INDEDENT/DEDENT
>> tokens. This might not be a bad idea, but I haven't thought it
>> through.

We've also identified the inability to create multi-line expressions
as a weakness in Python syntax. I posted a message on 10 Dec 1993
going in to a little more detail, but the key problem for us is that
we don't want to force our users to adopt this style.

For us programmers with fancy emacs' modes the INDENT/DEDENT system is
fine. But for end-users, who may not be professional programmers
and who may be entering text in a primitive text entry widget, having
to get all their text to align properly will get stale fast.

As I mentioned last time, when I show people Python they almost
immediately complain about using indentation for nesting. I can only
think of one or two people who didn't object to it. They may get to
like it in time, but such a uniformly negative reaction may keep
potential users from trying the language at all, slowing down its rate
of acceptance.

We've been looking for solutions to this problem. We'd really like to
get a solution built in to the language rather than having to add
something non-standard ourselves.

Probably the best idea we've come up with is to add begin/end
keywords. After a "begin" statement the lexer acts as if there had
been a newline and an indentation to one more than the indentation of
the line with the "begin". While inside a begin/end pair, the lexer
considers all the lines to be at this same indentation level.

Having "begin" simulate a newline allows the following to work:

for x in seq : begin if f(x) : do_something; end

Having the indentation be one more that that of the triggering line
allows the following to work (which is clearly poor style, but should
still be legal):

if x : begin
print x
print x + 1
end

An occurance of a ":" terminated statement turns on the INDENT/DEDENT
syntax until the indentation returns to the level of indentation of
the statement that triggered it. This allows you to mix styles if you
really want to.

Reaching an "end" statement returns indentation to the level of the
line that had the matching "begin" statement.

Note that this is an addition to the current rules, not a replacement.
We can still use the indentation syntax. The only problem for existing
code is if the code uses "begin" or "end" as symbols. I'd prefer to
use keywords instead of "{}" or other weird symbols, but maybe it's
too late.

I haven't had a chance to see how this affects the implementation of
the interpreter or discover if there are hidden gotcha's in the
syntax. My biggest concern so far is that I don't think you can do
this entirely in the lexer, you need the parser to help out.

I admit I'm not completely happy with this particular solution since
it does muddy the current syntax. But we feel we have to address the
problem somehow.

Chris Hoffmann

-----------------------------------------------------------------------------
Chris Hoffmann VI Corporation
choffman@vicorp.com 47 Pleasant St. Northampton MA 01060