From: David Masover Date: 2009-12-16T00:52:37+09:00 Subject: Re: Poll: Significant Indentation On Monday 14 December 2009 10:40:19 pm Josh Cheek 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. > 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. 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.