From: Ralph Mason Date: 2001-11-30T08:05:54+09:00 Subject: [ruby-talk:26993] Re: first class functions in Ruby irb(main):010:0> def sq(x) irb(main):011:1> x+x irb(main):012:1> end nil irb(main):013:0> def aMes(f) irb(main):014:1> send(f,42) + send(f,27) irb(main):015:1> end nil irb(main):016:0> aMes :sq 138 irb(main):017:0> Like that? ----- Original Message ----- From: "MikkelFJ" Newsgroups: comp.lang.ruby To: "ruby-talk ML" ; Sent: Friday, November 30, 2001 11:15 AM Subject: [ruby-talk:26976] first class functions in Ruby > In the thread on language design, I mentioned a wish for functions as first > class values. > > I hope someone knowing Ruby deeper than I will follow up on this. > > I'd like to be able to write a function that I can pass as argument to a > Ruby message or to another function. A function is a new concept in Ruby > context. > > There is a difference between messages and functions. The difference being > that messages has a receiver (the object the member function is a member > of). > A function is a pure mathematical abstraction that does not have any > implicit state like a receiver. > > First a way to simulate a function, then a less combersome syntax > > > class DoubleFunction > def evaluate arg > arg + arg > end > end > > #example of use > > def aMessage f > f.evaluate(42) + f.evaluate(27) > end > > def main > aMessage MyFunction.new > end > > > improved syntax: > > > fun squareFunction arg > arg + arg > end > def aMessage f > f(42) + f(27) > end > def main > aMessage squareFunction > end > > > "fun" is a new keyword that defines a function that is a receiverless > message. It can be treated like any other object. > > It would also be nice to be able to pass a message ("def") around as a > value. It may also make the "fun" keyword superflous. An example would be as > above, except that a) "fun" is replaced by "def", b) the object instance the > "def" is available and can by modified by the method the usual way: > > > def squareFunction arg > arg + arg > end > def accumulate arg > if @count > @count = @count + arg > else > @count = arg > end > end > class Processor > def initilize n > @weight = n > end > def process f > f(weight) > end > end > def main > p = Process.new(4) > p.process(squareFunction) > p.process(accumulate) > aMessage squareFunction > end > > > The above example does not use the "fun" function, instead it uses two > messages ("def"), in which one of the messages uses its ownership context, > the other basically behaves like a function. > Notice that the Process class is a bit tedious to write. It is a class with > a single function. The last example repeated with a function with partial > evaluation instead of a Process class. The "fun" keyword has been > reintroduced: > > > fun squareFunction arg > arg + arg > end > def accumulate arg > if @count > @count = @count + arg > else > @count = arg > end > end > fun process weight f > f(weight) > end > > def main > p4 = process(4) > p4(squareFunction) > process(4, squareFunction) # same as above > p4(accumulate) > aMessage squareFunction > end > > > In the above example, "p4" is a partial evaluation of the process function. > What happens is that the applied parameter 4 is saved in an internal > "weight" variable, and a new function is created with one parameter less. > This is pretty much standard in functional programming, but it should be > pretty straightforward to integrate in the ruby enviroment. In ML this can > be pretty heavy stuff to implement, but due to Ruby's dynamic nature, it > should be easy, and equally powerful. > Microsoft added the concept of delegates to java, dubbing it J++ and spawned > a major lawsuit from Sun. But the concept was great and made it much easier > to create eventhandlers. > > > MikkelFJ > > > > > >