Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Pythonic indentation (or: beating a dead horse)

Reply
Thread Tools

Pythonic indentation (or: beating a dead horse)

 
 
Juan Zanos
Guest
Posts: n/a
 
      05-20-2009

On May 20, 2009, at 11:51 AM, Rick DeNatale wrote:

> On Wed, May 20, 2009 at 11:05 AM, J Haas <> wrote:
>> On May 19, 4:49 pm, Eric Hodel <drbr...@segment7.net> wrote:
>>> Does anybody complain about terminating '}' in C, C++ or Java?

>>
>> I do, now. Redundancy irritates me.
>>
>>> Does anybody complain about terminating '.' on sentences?

>>
>> If the period accounted for one-sixth of English text, perhaps they
>> would.

>
> wellwhydontwegetridofallpunctuationthingslikespace scommassemicolonsquotesetcperiodcertainlytakeupmuc hmoreofourprosethantheydeserveandcapitalizationeat supvaluableverticalspaceandnoneedforparagraphsepar ationeither
>
> Seriously, if you measure things by avoiding extra keystrokes, get a
> better editor. I value readability over parsimony of lexical items.
>
>
>
> --
> Rick DeNatale
>
> Blog: http://talklikeaduck.denhaven2.com/
> Twitter: http://twitter.com/RickDeNatale
> WWR: http://www.workingwithrails.com/pers...-rick-denatale
> LinkedIn: http://www.linkedin.com/in/rickdenatale
>


That would be a valid criticism if J Haas's suggestion made things
less readable. But having to scroll less makes things more readable.


 
Reply With Quote
 
 
 
 
Joshua Ballanco
Guest
Posts: n/a
 
      05-20-2009
On May 19, 2009, at 5:40 PM, J Haas wrote:

> My friends, when ONE OUT OF EVERY SIX of your code lines consists of
> just the
> word "end", you have a problem with conciseness. I recognize that
> syntactically-
> significant indentation is not perfect, and it would bring a few pain
> points
> with it. But let me say that again: ONE OUT OF EVERY SIX LINES, for
> crying out
> loud! This should be intolerable to engineers who value elegance.
> "Streaks"
> means what you'd expect: there are four places in the scanned files
> that look
> like this:
>
> end
> end
> end
> end
> end
> end
> end
>
> This is *not* DRY. Or anything remotely resembling it. This is an
> ugly blemidh on a language that otherwise is very beautiful.


It's at this point that I started to wonder if you've had a look-see
at _why's new language, Potion? Specifically:

> * Deeply nested blocks can be closed quickly. I don't like
> significant whitespace, personally. But I don't like end end end end.
> say = (phrase):
> 10 times (i):
> 20 times (j):
> phrase print
> _say
> The closing "_ say" ends the block saved to "say" var.


 
Reply With Quote
 
 
 
 
Roger Pack
Guest
Posts: n/a
 
      05-20-2009
> ...maybe something like this:
>
> module Kernel
> override print(*args)
> do_something
> overridden *(args + [" "])
> end
> end


Yeah the inheritance chain thing is hard.
The closest you can come is with modules.

class Class
def override &block
m = Module.new
m.module_eval &block
include m
end
end

# now

class Object
override do
def print *args
super *(args + [" "])
end
end
end

>> print 3

3

ref: http://www.ruby-forum.com/topic/176080#new last post
http://yehudakatz.com/2009/03/06/ali...ain-in-models/


> But I digress... the purpose of this post is to talk about one of the
> relatively
> few areas where I think Python beats Ruby, and that's syntatically-
> significant
> indentation.


Not having the "end" is indeed very clean and kind on the eyes--kind of
reminds me of what Ruby does, which is try to make things look better
for you.

The only complaint I've heard about it was from Tony Arcieri's post
wondering "how do you return anything from blocks?"

i.e. in Ruby "array.collect{|a|}.reject{|b| true}"

how to do that with indented blocks.

That being said, splitting it up into 3 neat python blocks doesn't look
bad at all, so it's not a big loss there. I'm not too familiar with
Python syntax so I'm not exactly sure what's possible, either. What
would a good syntax be to return values from indented blocks?

> My proposal is to, first, not change a thing with respect to existing
> syntax. Second, steal the : from Python and use it to signify a scope
> that's marked by indentation:


I did note Matz recent comment on using the ":" as a separator:
http://redmine.ruby-lang.org/issues/show/1389

Perhaps you could take your pitch to him

> while some_condition:
> # this scope will terminate when the indentation level decreases
> to the
> # level before it was entered
> do_something


Interesting--so you propose to use : when you want a block but *dont*
care about using its return value, is that right?


> We can get around this by saying that braces, wherever they may appear,
> always define a new scope nested within the current scope, regardless
> of indentation.
>
> def do_something(a, b, c):
> { print a, b, c } # this works
> a + b + c


and then afterward it picks up the previous indentation? I
suppose...that would work. It's an odd use for {}'s though which are
already pretty heavily used.

Overall I like the idea--making "end's" optional would indeed be kind.
It is better than a similar idea I had recently, which was to use : for
single line blocks (only), i.e.

if a == b : do_something
instead of
if a == b; do_something; end

but your suggestion seems to include even more than that.

The other concern is that "the allure of magic indentation wears thin
for large docs" which fact "worked to ensure you kept your methods
short."[1]

Also could parsers handle it?
Thoughts?

=-r
[1] http://www.artima.com/forums/flat.js...&thread=256682
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Joel VanderWerf
Guest
Posts: n/a
 
      05-20-2009
Joshua Ballanco wrote:
> It's at this point that I started to wonder if you've had a look-see at
> _why's new language, Potion? Specifically:
>
>> * Deeply nested blocks can be closed quickly. I don't like significant
>> whitespace, personally. But I don't like end end end end.
>> say = (phrase):
>> 10 times (i):
>> 20 times (j):
>> phrase print
>> _say
>> The closing "_ say" ends the block saved to "say" var.


Or maybe some variation on Lisp's superparenthesis?

http://www.gavilan.edu/csis/languages/parentheses.html

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

 
Reply With Quote
 
J Haas
Guest
Posts: n/a
 
      05-20-2009
On May 20, 8:51*am, Rick DeNatale <rick.denat...@gmail.com> wrote:
> Seriously, if you measure things by avoiding extra keystrokes, get a
> better editor. *I value readability over parsimony of lexical items.


Cluttering up your code with "end" everywhere makes it less readable,
not more.

On May 20, 9:01 am, "Michael Bruschkewitz"
<brusch4_removeunderlinesandtextbetwe...@gmx.net > wrote:
> I have some suspicion this was a joke thread.
> (Hint: Format of OP)


Nope, I'm sincere. As I said before, I'm new. The formatting was a
misguided attempt to make things look nice by manually wrapping them
at 80 columns. Oops.

> This sort of structuring pieces of code stopped me from trying Python
> seriously.


And I specifically addressed this in my OP. A lot of engineers who
haven't done work in Python think that the idea of giving syntactical
significance to whitespace is a ridiculous idea. I used to be one of
them. Now I know better. Don't knock it until you've tried it.

> Isn't there an Syntax-Highlighting Editor out there which allows assigning
> 1-Point size to End-Only-Lines?


Aside from the fact that this wouldn't solve the problem that I'd
still have to _write_ the damned things, this is possibly the
kludgiest solution imaginable.

> Wouldnt this be the easiest way to solve your problem?


The easiest way to solve _my_ problem would be for me to use one of
the preprocessing scripts that impose Python-like indentation syntax
on Ruby. But that wouldn't solve the larger problem, which is that
Ruby could be better than it is.

On May 20, 10:04 am, Joshua Ballanco <jball...@gmail.com> wrote:
> It's at this point that I started to wonder if you've had a look-see
> at _why's new language, Potion?


Nope. but I'll check it out. Thanks.
 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      05-20-2009
On Wed, May 20, 2009 at 2:35 PM, J Haas <> wrote:
> On May 20, 8:51=A0am, Rick DeNatale <rick.denat...@gmail.com> wrote:
>> Seriously, if you measure things by avoiding extra keystrokes, get a
>> better editor. =A0I value readability over parsimony of lexical items.

>
> Cluttering up your code with "end" everywhere makes it less readable,
> not more.


Honestly, that's subjective. Some people prefer delimiters some don't.

In general I'm not a fan of languages whose syntax depends on the
number of rather than just the presence of whitespace characters. I
find it hard to count blanks while reading.

I tried hard to like haml for instance. It has a lot of good points,
but the pythonic style of nesting just doesn't work for me.

In code, the real solution is not to nest so deeply that it becomes a
problem, learn to use the composed method pattern.



--=20
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/pers...-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

 
Reply With Quote
 
J Haas
Guest
Posts: n/a
 
      05-20-2009
On May 20, 10:23*am, Roger Pack <rogerpack2...@gmail.com> wrote:
> Yeah the inheritance chain thing is hard.
> The closest you can come is with modules.
> ...
> class Object
> *override do
> * *def print *args
> * * *super *(args + [" "])
> * *end
> *end
> end
>
> >> print 3

>
> 3


Nifty! Thanks.

> The only complaint I've heard about it was from Tony Arcieri's post
> wondering "how do you return anything from blocks?"
>
> i.e. in Ruby "array.collect{|a|}.reject{|b| true}"
>
> how to do that with indented blocks.


I still have a tough time understanding this objection. What I'm
essentially proposing is that at least in the case of code blocks that
start with a colon, a de-dent takes the place of an end. Given that, I
just don't see what it is that could be done without end that couldn't
be done without dedenting. In this example, the braces would continue
to work as expected (and there are no end statements), but for
something like this:

array.reject do |b|
true
end

.... it would just be:

array.reject do |b|:
true

I guess with the collect thrown in, the current implementation with do-
end rather than braces would be

array.collect do |a|
end.reject do |b|
true
end

...is that right? Using indentation to deliniate blocks does have the
problem that you can't have a null block like the one passed to
collect here. Python gets around it with the keyword "pass", as in:

for x in xrange(50): # Python equivalent of (0...50).each do |x|
end
pass

So this could be:
arra.collect do |a|:
pass
..reject do |b|:
true

> Interesting--so you propose to use : when you want a block but *dont*
> care about using its return value, is that right?


No, not exactly. The issue with return values is orthogonal to this.
My proposal is to use the : if you want dedent to substitute for end
to terminate the block. I still don't see why return values are
affected.

> > * def do_something(a, b, c):
> > { print a, b, c } *# this works
> > * * a + b + c

>
> and then afterward it picks up the previous indentation? I
> suppose...that would work. *It's an odd use for {}'s though which are
> already pretty heavily used.


True, and I'm not too thrilled with the solution, but maybe there's
something better. {} is heavily used, but on the other hand one of its
common uses is to divide code into blocks, and that's what it's doing
here.

> Overall I like the idea--making "end's" optional would indeed be kind.
> It is better than a similar idea I had recently, which was to use : for
> single line blocks (only), i.e.
>
> if a == b : do_something
> instead of
> if a == b; do_something; end


This suggestion is not at all incompatible with mine, and in fact
that's the way Python does it too (except you'd have to put parens
after do_something ...

if a==b:
# Nothing follows the colon, so this starts a new scope indented
past the if statement
do_something()
do_something_else()

if a==b: do_something() # code follows the colon, so it constitutes
the entire block
do_something_else()

if a==b:
do_something_else() # error, the parser expects a new level of
indentation

if a==b: do_something()
do_something_else() # error, the parser does not expect a deeper
indent

> The other concern is that "the allure of magic indentation wears thin
> for large docs" which fact "worked to ensure you kept your methods
> short."[1]


Well, all I can say is, that's his opinion. Hasn't lost its allure for
me. And if it did lose its allure, I would think that it wouldn't be
for large docs, it would be for deeply _nested_ docs. I definitely
sympathize with his mockery of the notion that this limitation is a
blessing in disguise because it encourages you to keep your methods
short... it reminds me of how I felt when I first heard that Java's
lack of pointers meant you couldn't write any pointer bugs. But my
employer imposes a strict 80-column limit on source files including
Python, we have a lot of Python code, and it all works out.

> Also could parsers handle it?


I think so, especially since the preprocessor I've used (wish I could
remember its name... it's not Lazibi [1]) does it in a fairly clever
way in Ruby itself, so I don't see why the parser couldn't do what it
does.

Thanks for your comments, I appreciate the feedback.

[1] http://lazibi.rubyforge.org/
 
Reply With Quote
 
Tony Arcieri
Guest
Posts: n/a
 
      05-20-2009
[Note: parts of this message were removed to make it a legal post.]

On Wed, May 20, 2009 at 1:10 PM, J Haas <> wrote:

> I still have a tough time understanding this objection. What I'm
> essentially proposing is that at least in the case of code blocks that
> start with a colon, a de-dent takes the place of an end. Given that, I
> just don't see what it is that could be done without end that couldn't
> be done without dedenting.



I already responded to this. I guess you didn't see it. There are several
types of statements which contain multiple indent blocks (and thus multiple
dedent tokens). These would include if statements:

if foo
blah
elsif bar
blah2
else
baz

Begin statements (ala try/catch in Python)

begin
somecode
morecode
rescue FooError
some_rescue_action
rescue BarError
another_rescue_action
ensure
something_gets_done

Case statements:

case foo
when bar
do_something
when baz
do_something_else

Each of these statements is an expression with multiple clauses. How do you
tell when these expressions are complete? Obviously a naive "dedent = end
of expression" approach doesn't work in these cases.

These work in Python because Python has a special grammar for statements
which doesn't require a statement separator for any statements which have
indent blocks. This doesn't work in a language where everything is an
expression, because all expressions must be treated the same and all
expressions must have an expression terminator (newline or semicolon)

--
Tony Arcieri
medioh.com

 
Reply With Quote
 
Tony Arcieri
Guest
Posts: n/a
 
      05-20-2009
[Note: parts of this message were removed to make it a legal post.]

On Wed, May 20, 2009 at 1:25 PM, Tony Arcieri <> wrote:

> I already responded to this. I guess you didn't see it. There are several
> types of statements which contain multiple indent blocks (and thus multiple
> dedent tokens). These would include if statements: [... snip ...]
>
> Begin statements (ala try/catch in Python) [... snip ...]
>
> Case statements: [... snip ...]
>
> case foo
> when bar
> do_something
> when baz
> do_something_else
>


And yet another consideration with this in Ruby vs. Python: in Ruby these
are all expressions (as has been stated repeatedly) and therefore you can do
this sort of thing:

x = case foo
when bar
do_something
when baz
do_something_else
else
whatever
end

i.e. the case statement returns the value of the last expression evaluated
in the taken branch.

This is not the case in Python (well first because Python doesn't have case
statements) where no expressions can contain indent blocks.

--
Tony Arcieri
medioh.com

 
Reply With Quote
 
Juan Zanos
Guest
Posts: n/a
 
      05-20-2009

On May 20, 2009, at 2:51 PM, Rick DeNatale wrote:

> On Wed, May 20, 2009 at 2:35 PM, J Haas <> wrote:
>> On May 20, 8:51 am, Rick DeNatale <rick.denat...@gmail.com> wrote:
>>> Seriously, if you measure things by avoiding extra keystrokes, get a
>>> better editor. I value readability over parsimony of lexical items.

>>
>> Cluttering up your code with "end" everywhere makes it less readable,
>> not more.

>
> Honestly, that's subjective. Some people prefer delimiters some don't.


Is it subjective? Neither method is ambiguous. So no problem
there. But scrolling 16% more often? That must have some cost to
readability.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Beating my head -- JSPs and encoding Hegemony Cricket Java 1 08-22-2012 01:29 PM
remove overall indentation preserving reletive indentation Jesse B. Ruby 2 03-27-2010 07:23 PM
Object Oriented vs Pythonic Code, and Pythonic standards Carl J. Van Arsdall Python 4 02-07-2006 10:15 PM
Learning and beating my head Brian Andrus Java 2 05-04-2004 07:38 AM
anyone using an iPod probably deserves a beating Lucas Tam Digital Photography 38 04-29-2004 02:01 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57