[stack] Point free (pointless) programming in ruby? (fwd)
John Carter <[email protected]>
| Newsgroups | gmane.comp.lang.concatenative |
|---|---|
| Message-ID | <[email protected]> |
Here's a post I sent to the ruby mailing list about doing pointfree / concatenative like things in Ruby. Perhaps some of the Denizens of this list might like to apply their wondrously creative minds to the exercise. John Carter Phone : (64)(3) 358 6639 Tait Electronics Fax : (64)(3) 359 4632 PO Box 1645 Christchurch Email : [email protected] New Zealand ---------- Forwarded message ---------- Date: Wed, 14 Jan 2009 12:12:00 +1300 (NZDT) From: John Carter <[email protected]> To: ruby-talk ML <[email protected]> Subject: Point free (pointless) programming in ruby? I'm very fond of the notion of Concatenative Languages such as Joy, Factor... http://en.wikipedia.org/wiki/Joy_(programming_language) http://www.latrobe.edu.au/philosophy/phimvt/joy/jp-joyjoy.html http://factorcode.org/ There is a supreme simplicity about them. So while reading what the current state of them is, I stumbled across the notion of Point free (sometimes called Pointless) programming. The idea of sequences of function compositions that elide the arguments that they will be applied to. http://www.haskell.org/haskellwiki/Pointfree One can easily define a sequence of methods in Ruby... fun_seq = [:a, :b, :c] as a sequence of symbols. Which one could apply to an arbitrary argument.. irb > f = [:to_s, :succ] => [:to_s, :succ] > f.inject(4,:send) => "5" Oooh! Looky! That's sneaky of me! symbol_sequence.inject(arg,:send) [:a, :b, :c].inject(arg,:send) that's equivalent to arg.a.b.c Not quite function composition. Cute, but let's try... irb > def a(a) > p ["a",a] > a+"a" > end => nil > def b(b) > p ["b",b] > b+"b" > end => nil > def c(c) > p ["c",c] > c+"c" > end => nil > f=[:a,:b,:c] => [:a, :b, :c] > f.inject("foo"){|memo,obj|send(obj,memo)} ["a", "foo"] ["b", "fooa"] ["c", "fooab"] => "fooabc" [:a, :b, :c].inject(arg){|memo,obj|send(obj,memo)} is equivalent to c(b(a(arg))) > c(b(a("bah"))) ["a", "bah"] ["b", "baha"] ["c", "bahab"] => "bahabc" Or how about working with lambda's or Proc objects... > a1 = lambda {|x| x+"a"} => #<Proc:0xb7d9f744@(irb):41> > b1 = lambda {|x| x+"b"} => #<Proc:0xb7e0feb8@(irb):42> > c1 = lambda {|x| x+"c"} => #<Proc:0xb7dfa5e0@(irb):43> > [a1, b1, c1] => [#<Proc:0xb7d9f744@(irb):41>, #<Proc:0xb7e0feb8@(irb):42>, #<Proc:0xb7dfa5e0@(irb):43>] > [a1, b1, c1].inject("foo"){|memo,proc| proc.call(memo)} => "fooabc" Anyhoo! Clearly in principle one can do Pointfree programming Ruby. Questions for the Group: 1) Is there a neater way of expressing a sequence of function compositions in Ruby? 2) Which Ruby Pointfree sequences are actually useful? John Carter Phone : (64)(3) 358 6639 Tait Electronics Fax : (64)(3) 359 4632 PO Box 1645 Christchurch Email : [email protected] New Zealand