From: Brian Candler Date: 2009-01-13T01:30:32+09:00 Subject: Re: functional programming Mike Gold wrote: > Can you give an example of where the difference is "very useful"? Well, as you know, blocks are roughly just in-line lambdas: 10.times { |x| puts x } I was thinking of the following properties of the method/lambda difference: (1) You can return directly from a method, even from inside blocks. class Foo def bar 10.times { |x| ... 10.times { |y| ... return "foo" if baz(x,y) } } end end (2) The whole variable/method naming thing only works because a method starts a new scope, but a block doesn't. That is: when I write an expression like 'a+1' I don't have to mark whether 'a' is a call to a method, or retrieving the value from a local variable. Neither do I need to declare a to be a variable or a method. I just use it, and a simple rule says whether what it is, from the context. Finally: I just happen to like infix expressions, maybe because these are how we think in real life, and what we're all taught in school from an early age. In these, a+1 and (a+1) and ((a+1)) are the same expression. In Lisp, it makes a huge semantic difference whether I write parentheses, and how many, because the Lisp brackets are also in effect the apply-function operator: like a() in C. So I have to constantly think about whether I should write 'a' or '(a)' or '(quote a)' or whatever. Again, this is saying more about my mind, and possibly my upbringing, than anything else. My mind is not a Lisp processor. > Because programmers can and should always be refactoring and changing > their mind, this entails the drudgework of adding/removing the > '.call()'s or the '[]'s or (in ruby 1.9) the '.()'s. The worst > outcome is when a programmer doesn't bother to refactor because of the > hassle. It's not a problem I've ever come across in practice. For me, refactoring usually means moving code between methods in a class, or between methods in one class and another class. Usually, code which expects a block always expects a block. > By the way, since locals are determined at parse time, I don't see any > particular reason why this cannot work: > > bisect = lambda { |x, y| (x + y)/2.0 } > # ... > bisect(5, 6) > > Whether or not that _should_ work is a different story. The pro is > that I can swap lambdas and methods without changing syntax. The con > is, at least, that the meaning of existing code could change (when a > bisect method already exists). Sure. In practice, Ruby programs aren't usually composed like that, since local variables are considered "short lived" (they only exist during executing of a single method). In some cases I might write class Foo BISECT = lambda { |x,y| (x+y)/2.0) } def foo bar(someargs, &BISECT) end end but in most cases, the logical place to put the 'lambda' is inline as a block: class Foo def foo bar(someargs) { |x,y| (x+y)/2.0) } end end If 'bisect' were are large piece of code then I might implement this as a separate method, or even a class. I think I can see advantages of the "keep it simple" approach. If there are no choices to make between different ways of expressing the same thing, then you can just go ahead and code it without thinking. But then, people have also said here that Lisp has a comprehensive object system, which in turn means you'd still have to choose between functions and objects with methods. -- Posted via http://www.ruby-forum.com/.