I'm having a hard time following why. Can you provide an example of a
Ruby snippet that couldn't be done with scoping defined by
indentation?
A multi-line block returning a value, e.g.
foo = somemethod do |arg1, arg2, arg3|
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3
end
Or for that matter, a multi-line lambda:
foo = lambda do |arg1, arg2, arg3|
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3
end
I'm sure you're aware the "multi-line lambda" problem is somewhat infamous
in the Python world. Guido van Rossum himself has ruled it an "unsolvable
problem" because of the statement-based nature of Python indent blocks.
Lambdas must be expressions or they are worthless, and there is no way to
embed an indent block inside of a Python expression.
And a bit of supplemental information: I conducted a poll of what Rubyists'
favorite features are in the language. Blocks were #1 by a wide margin.
This seems like a problem with Python, not a problem with indentation.
As I said, a Haskell-like syntax would facilitate including indent blocks in
a purely expression-based grammar. It's Python's statement-structured
syntax that's incompatible. However the sort of syntax you would get from a
Haskell-like approach is going to be different than Python's.
You can have a look at Logix, which is a purely expression based language
which tries to mimic Python's syntax while using Haskell-styled indent
rules. This is about the best you can do:
http://web.archive.org/web/20060517203300/www.livelogix.net/logix/tutorial/3-Introduction-For-Python-Folks.html
Well, every expression in a Ruby-like grammar must be terminated by a
token. [... snip ...]
In other words, the parser treats an indentation level less than the
indentation level of the previous line as a statement-terminating
token.
Because there are statements which contain multiple indent blocks, such as
if or try/catch. If you wanted to carry over Rubyisms, this would include
the case statement, e.g.
case foo
when bar
...
when baz
...
Therefore you can't just treat a "dedent" as a statement terminator, because
a single statement may itself contain multiple "dedent" tokens.
The best solution I could think of for this was a syntactically relevant
blank line, which sucks. It also requires lexer logic more complex than
Python to handle the case of a syntactically relevant newline, which in turn
pollutes the grammar.
> Implicit line joining works in Python because the only syntactic
> constructions which can exist surrounded in [...] (...) {...} tokens are
> expressions, so you can't put an indent block inside of these. If you
have
> an indent-sensitive Ruby with implicit line joining, you limit the
> expressiveness of what you can do inside any syntactic constructs
enclosed
> by these tokens.
This sorta makes sense but I'd really like to see a concrete example
of what you're talking about. It doesn't seem like this would be an
insurmountable difficulty but it's hard to say without the example.
This is valid Ruby:
on_some_event(:something, :filter => proc do
something_here
another_thing_here
etc
end)
Implicit line joining removes any newline tokens inside of (...) [...] {...}
type syntactic constructions. So it becomes impossible to embed anything
with an indent block inside of expressions enclosed in any of these tokens.
And now we've hit an entirely new can of worms: how do you make implicit
line joining work when parens are optional?
···
On Tue, May 19, 2009 at 4:50 PM, J Haas <Myrdred@gmail.com> wrote:
--
Tony Arcieri
medioh.com