Daniel Brockman wrote:

>Hi Joe,
>
>  
>
>>Sorry, please bear with me... the Lisp I had in mind was
>>more like:
>>
>>  (setf a #'length)
>>  (funcall a "foo")
>>
>>(Hard to make an exact parallel because Ruby has methods
>>not functions, and Lisp AFAIK has functions not
>>methods...?)
>>    
>>
>Ruby has both methods and functions, but methods are more
>primitive than functions.  In particular, functions are
>objects and thus have methods.  Methods, on the other hand,
>are not objects (and they are not functions).  So functions
>are implemented using methods, not the other way around.
>  
>
Interesting--that's the first I've heard of it.  Do you have a link to 
some documentation about functions?  I don't see anything in the PickAxe 
or ri.

Oh, is it the Function[] syntax you demonstrate below?

>As for the example code, the closest Ruby equivalent would
>have to be something like the following:
>
>   a = :length
>   "foo".send(a)
>
>This is because in Ruby, polymorphism is implemented by
>having different °∆length°« methods for different objects,
>whereas in Lisp, there is just one function °∆length°« that
>handles all types of objects.  (Of course, CLOS simplifies
>the task of adding new clauses by way of defmethod, but a
>generic function is still just one function.)
>  
>
I understand.  I was not concerned about polymorphic methods vs. 
functions, but rather the ability to directly capture a reference to a 
[method|function].

Let me try illustrating in Boo instead:

class Foo:
  def bar():
    print("hello")

a = Foo()  # calling Foo constructor
b = a.bar
b()   # same as calling a.bar()

This is different than what you are trying to accomplish in your post, 
and admittedly, even pretty different from what my Lisp example was in 
terms of functionality.

>>Setting a variable to the function itself seems pretty
>>different than wrapping a call to the function in a lambda,
>>    
>>
>Again, there is not just a single °∆length°« method in Ruby,
>so you can't °»set a variable to the function itself.°…  The
>closest analogy to the °»function itself°… is the method name.
>  
>
I was looking for something like the above example in Boo.  Although 
using lambda/proc, send(:symbol), or method(:symbol), they all seem to 
accomplish the task (with useful differences in behavior between the 
three of them).

>>but honestly, now I can't think of what the actual
>>implications would be... other than a little bit of
>>additional terseness in calls like
>>
>>(reduce #'+ '(1 2 3))
>>vs.
>>[1, 2, 3].inject {|a,b|a+b}
>>    
>>
>You could actually define the equivalent of Lisp's °∆+°«
>function in Ruby, by doing this:
>
>   module Kernel
>     def +(a, b) a + b end
>   end
>
>Then the example with inject could be written like this:
>
>   [1,2,3].inject &method(:+)
>  
>
That is actually pretty close.  I've never seen the &-syntax (that is, 
not from the caller)... I can see there are a lot of possibilities with 
that.

>But this will fail when someone overrides the °∆+°« operator,
>in which case you need to do something like this:
>
>   [1,2,3].inject &Object.new.method(:+)
>
>Much cleaner would be to define the function in a separate
>namespace so that name clashes are avoided:
>   
>   Function = Object.new
>   class << Function
>     alias [] method
>     def +(*terms) terms.inject(0) { |a, b| a + b } end
>   end
>
>Now the example looks like this:
>
>   [1,2,3].inject &Function[:+]
>
>You could go one step further:
>
>   class Symbol
>     def to_proc
>       Function[self].to_proc
>     end
>   end
>
>Note that if you take the Kernel#+ approach, the above
>implementation needs to be much hairier:
>
>   class Symbol
>     def to_proc
>       Binding.of_caller do |boc|
>         eval(%{method(:#{self})}, boc).to_proc
>       end
>     end
>   end
>
>Now you can reduce the original example (no pun intended)
>to the following,
>
>   [1,2,3].inject &:+
>
>which is actually *shorter* than the equivalent Lisp code.
>  
>
Wow, that is really cool.  Although one problem... my irb is complaining 
about Binding.of_caller not being defined.  Do I need to require 
something first?

>By the way, a more popular definition of Symbol#to_proc is
>to have °∆foo.each &:bar°« equal °∆foo.each { |x| x.bar }°«.
>This won't work in the above example because we cannot use
>the Fixnum#+ method to fold an array of integers (since it
>only takes one argument!).
>
>(If you want both variants of Symbol#to_proc, I guess you
>could use a unary plus or minus operator to disambiguate.
>However, °∆[1,2,3].inject &-:+°« is starting to look rather
>much like line noise.)
>  
>
I didn't mean to emphasize #'+, it is just the canonical example in the 
Lisp tutorials I've read... :)

Thanks for the very interesting response, I learned a lot.