Poll: Significant Indentation

On 2009-12-15, David M. [email protected] wrote:

On Monday 14 December 2009 02:55:06 pm Seebs wrote:

On 2009-12-14, David M. [email protected] wrote:

And again, optional significant whitespace. Would you stop using Ruby
if it became an option?

I don’t think it makes sense to describe it as optional.

Why not?

If it’s there, then the parser has to handle it for any modules which use
it. Which means I have to deal with at least some incoming code using it,
and that means I can no longer trust blocks to have end markers.

So, by this logic, use (or lack) of parentheses are optional, as are curly
brackets around hash literals (if they’re immediately passed as the last
argument to a method)…

The grammar for parentheses in Ruby is not-optional, but it happens to
allow either form.

Hmm. Here’s the thing. You can’t do it unless you have some special
token that indicates the start of a block which is whitespace-delimited.
Otherwise, consider:
if true
indented
things
more things
end

Did that block end at “more things” or at “end”?

For it to not be ambiguous, you have to know in advance which one you’re
looking for.

Do you really not find ways people can write unreadable code in Ruby as it is?
Oh, sure. But the language is at least theoretically subject to
indentation
fixers now. It wouldn’t be with this change.

I don’t feel it should be the job of the language to enforce coding standards,
and that is one of the reasons I use Ruby in the first place.

I suppose if we’re talking about a special thing which introduces
blocks,
part of my objection goes away – it’s no longer impossible.

I still can’t comprehend wanting that feature – it’s always struck me
as introducing a lot more prospective undiganosible errors than it
could ever remove.

(Disclaimer: I get a lot of mail that’s been corrupted by a messaging
server which strips or squashes leading whitespace.)

-s

On Monday 14 December 2009 08:10:09 pm Seebs wrote:

For it to not be ambiguous, you have to know in advance which one you’re
looking for.

I agree. I don’t think it has to be a special token at the start of a
block,
but definitely, some context which unambiguously marks this as an
indented
block, and which doesn’t make existing blocks autoindented.

If I were writing a new language, I’d much prefer something like
endless.rb,
where ‘end’ is simply optional, but as you point out, that would screw
up
existing code. So, very worst case, you’d specify it per-file or
per-block.

Do you really not find ways people can write unreadable code in Ruby as
it is?

Oh, sure. But the language is at least theoretically subject to
indentation fixers now. It wouldn’t be with this change.

Sure it would, they’d just be more complicated to write, and wouldn’t
apply
universally. Also, indentation fixers are far from the only automated
tools
which could be applied – I suspect there are some that already don’t
work
because of syntax that’s already flexible.

I don’t feel it should be the job of the language to enforce coding
standards, and that is one of the reasons I use Ruby in the first place.

I suppose if we’re talking about a special thing which introduces blocks,
part of my objection goes away – it’s no longer impossible.

I still can’t comprehend wanting that feature – it’s always struck me
as introducing a lot more prospective undiganosible errors than it
could ever remove.

I’d argue that “undiagnosable” is a strong word, especially when we’re
talking
about a language with a strong community ethic of testing and beautiful
code.
Again, I’d suggest that it’s that code in particular, and not the
syntax,
which would make it unreadable.

But my goal here isn’t to get you to agree. I think at least you’re no
longer
opposed to the feature existing, though you’d be opposed to the use of
it.

(Disclaimer: I get a lot of mail that’s been corrupted by a messaging
server which strips or squashes leading whitespace.)

And I see the same thing happening in IM clients.

But IM clients also tend to notice smileys and such, which can corrupt
the
code to unreadability long before indentation would, and don’t always
even
make it possible to copy and paste it in its original format.

There’s no limit to the extent that bad tools can screw up code. The
solution
is to not use tools like that – worst case, that’s what pastie is for.

I just think we should try to avoid adding new exceptional situations to
the
language. The simpler the language, the more elegant and easy to use,
all
these “it works this way… except sometimes, but sometimes that’s not
the
case either” just bog everyone down.

I do hate the pyramid code I see fairly often:

class This
class That
def something
call_method do |obj|
obj.blah_blah do
if condition
puts ‘Mt. Everest!’
end
end
end
end
end
end

I find it extremely difficult to figure out where I am, so I somehow
manage
to avoid typing code like this. If whitespace is the solution, then I’m
not
opposed to it, but having to remember “this little section has that
little
identifier which means that whitespace is turned on this time, but the
line
ended in a comma or slash or plus sign, so this line is actually a
continuation of the last line so whitespace doesn’t matter on this
line.” is
just a weight on my ability to concentrate.

I need simple intuitive consistent rules that I don’t have to look up
constantly, or make frequent exceptions to.

On Monday 14 December 2009 10:40:19 pm Josh C. wrote:

I just think we should try to avoid adding new exceptional situations to
the language. The simpler the language, the more elegant and easy to use,
all these “it works this way… except sometimes, but sometimes that’s not
the case either” just bog everyone down.

If you really think that, I think you’ll find Lisp much easier and more
intuitive. We already have tons of exceptional situations, and most of
them, I
think, make the language more readable. The obvious example:

has_many :comments, :through => :posts

So, you can omit the parens and the curly brackets sometimes, but not
all the
time. For example:

p {:a => :b}

Whoops. I meant a Hash literal, but Ruby assumed it was a block instead.
Looks
like I have to do this:

p({:a => :b})

It’s not too much to hold in your head, and it’s fairly easy to figure
out,
but it’s not pure, and it’s not consistent.

    end
  end
end

end
end

I find it extremely difficult to figure out where I am, so I somehow manage
to avoid typing code like this.

I agree, which is why I dropped it for awhile. But I like Haml, and I
find
that this is inevitably what happens with any even moderately complex
HTML
document – so it would happen if I started using Erector.

But even without that, while your example looks ludicrous, how would you
refactor it? I only see two obvious changes:

class This::That
def something
call_method do |obj|
obj.blah_blah do
some_other_method obj
end
end
end
def some_other_method obj
if condition
puts ‘Mt. Everest!’
end
end
end

But that didn’t really get rid of the problem, nor did it remove a
single end
statement. I’d argue that actually makes it less readable – in this
contrived example, it’s not as though some_other_method is being reused
elsewhere, so all this serves to do is spread the logic out more. It may
be
easier to follow in that it’s not as deeply nested (theoretically), but
it’s
more complex.

In fact, interestingly, the ratio of ‘end’ noise to actual code is still
exactly the same – 6 ends to 7 real lines of code, almost 50%.

There is one way to really seriously refactor it:

class SomeObject
def foo
self.blah_blah do
if condition
puts ‘Mt. Everest’
end
end
end
end

class This::That
def something
call_method do |obj|
obj.foo
end
end
end

You could imagine similarly pushing the “call_method” logic somewhere
else,
until eventually, your nested loops are hidden deep in library code, or
even
removed – blocks replaced with even more methods.

But this comes at a cost of flexibility. Presumably there was a reason
blah_blah is exposed, and takes a block. Blocks are, after all, one of
the
coolest things about Ruby. You can say that nesting that deeply is a Bad
Thing, but there are many cases where it really is appropriate.

I suppose it all comes back to that basic idea of not wanting the
language to
tell me what to do. I’d like to be able to nest things that deeply, when
I
have to, and have them look good.

If Ruby had optional significant whitespace as a core language feature
(maybe
like endless.rb · GitHub), would you use it:

  • Never?
  • Sometimes?
  • All the time?
  • Don’t care?
  • Only with different syntax (lazibi, colon, something else?)

In general I’m in favor of optional significant whitespace, because it
fits more code onto the current viewable page.

In general I think that whitespace delimited code is easier to read, but
harder to write.

Does anybody have any experience as to whether that makes code easier to
maintain, or not?

-r

2009/12/15 Roger P. [email protected]:

If Ruby had optional significant whitespace as a core language feature
(maybe
like endless.rb · GitHub), would you use it:
 - Never?
 - Sometimes?
 - All the time?
 - Don’t care?
 - Only with different syntax (lazibi, colon, something else?)

I’m not sure adding significant indentation is a good idea. The Ruby
syntax is already so complex that most editors can’t get all of it -
some constructs simply don’t indent right so I have to split them
differently or indent them manually.

Imagine adding significant indentation to that.

I would probably use the feature it it just implicitly sprung to
action the moment I forget some ends. However, it would probably make
working with Ruby code harder.

In general I’m in favor of optional significant whitespace, because it
fits more code onto the current viewable page.

In general I think that whitespace delimited code is easier to read, but
harder to write.

Does anybody have any experience as to whether that makes code easier to
maintain, or not?

I think that there are already fine languages with significant
indentation, and fine languages with syntax that does not heavily rely
on whitespace, including Ruby.

I would like to point out one trend that I noticed: the languages
which do rely on significant indentation seem to have overall simpler
syntax so that even in case of clobbered code it’s somewhat easier to
deduce what goes where though it’s unambiguous only if you have some
idea what the code does.

Ruby has already gone the way of more complex syntax which is more
concise at times but requires more explicit delimiters at others.
Undoing that is a challenge which requires more than just adding
significant indentation.

There has to be a balance between the two features to keep the code
readable and maintainable.

Thanks

Michal

On Thursday 17 December 2009 01:11:18 am Josh C. wrote:

If you really think that, I think you’ll find Lisp much easier and more
intuitive.

I’ve actually just bought the Prag Prog book for Clojure :slight_smile:

And I finished the Gigamonkeys book on Common Lisp:

http://gigamonkeys.com/book

Actually, syntax wasn’t my problem with Lisp – macros make it even
better,
and if I really had a problem, it’d be trivial to write an indentation-
sensitive language that compiled to s-expressions.

While Ruby just looks better, my biggest problem with Lisp was that
Common
Lisp, at least, has accumulated decades of cruft. It wasn’t the syntax,
it was
naming conventions for the functions – things I find in Ruby, like
String#chop vs String#chop!, don’t always seem to exist. Plus, too many
things
seem to be named at an uneasy balance between wanting names to be short
enough
to type (I’m guessing from the days of teletypes and such), and wanting
them
to not be “hieroglyphs” (generally preferring something like “add” to +,
though that’s a bad idea since + exists.)

Maybe I should look at Clojure, though…

has_many :comments, :through => :posts

Yes, this is more readable, and not especially complex. I am not opposed to
all exceptional situations, but we do have quite a few as is, and I’d
prefer not to superfluously add more, just because we can.

In this case, it’s not “just because we can”, but because I think it
would
look noticeably better. In particular, Ruby’s greatest strength is good-
looking DSLs. However, Haml looks better to me than any Ruby-based
builder
DSL, and the biggest reason is all those ‘end’ statements.

It just bothers me that, as a Rubyist, I would prefer a DSL targeted at
Ruby,
but which isn’t actually Ruby syntax.

But based on the response so far, it doesn’t look like enough people (at
least
on ruby-talk) care enough about this. I suspect most of them are still
too
fatigued from the “beating a dead horse” thread.

In this case, it’s not “just because we can”, but because I think it would
look noticeably better. In particular, Ruby’s greatest strength is good-
looking DSLs. However, Haml looks better to me than any Ruby-based builder
DSL, and the biggest reason is all those ‘end’ statements.

I agree about Haml, so I suppose my answer to the poll must be that
white
space should always count, or never count, but not that it should
sometimes
count. (I know the question was whether I would use it, but I’m saying
that
I shouldn’t have a choice, I would rather the language does or doesn’t
not
implement it, without the ability to choose).

If you really think that, I think you’ll find Lisp much easier and more
intuitive.

I’ve actually just bought the Prag Prog book for Clojure :slight_smile:

has_many :comments, :through => :posts

Yes, this is more readable, and not especially complex. I am not opposed
to
all exceptional situations, but we do have quite a few as is, and I’d
prefer
not to superfluously add more, just because we can.

On Thu, Dec 17, 2009 at 11:11 AM, Josh C. [email protected]
wrote:

I agree about Haml, so I suppose my answer to the poll must be that white
space should always count, or never count, but not that it should sometimes
count. (I know the question was whether I would use it, but I’m saying that
I shouldn’t have a choice, I would rather the language does or doesn’t not
implement it, without the ability to choose).

I guess I’m on the completely opposite side of the fence: I find the way
Python enforces indentation rather rigid and hacky. To handle the sorts
of
cases Haskell’s optional indentation handles quite elegantly, Python has
to
employ things like implicit line joining.

Furthermore, since Ruby is already a mature language, requiring
mandatory
indentation is extremely impractical. Indentation sensitivity in Ruby
must
allow you to retrofit it into existing codebases.