On 5/18/06, Madan Manoharan <madan.manoharan / gmail.com> wrote: > On 5/18/06, Joe Bowers <JoeBowers / bclip.com> wrote: > > > > Partials are great for deferring part of a computation > > until later- they're useful in some of the same circumstances > > as closures. They're also really easy to use in ruby already. > > > > def multiply(x, y); x * y; end > > > > multiply_by_3 = lambda { |x| multiply(3, x) } > > > > > Yesterday* Brian Mitchell *introduced me to the work of *MenTaLguY* where he > talks about 'Promise' and 'Future'; Future sounds very similar to partial > functions. > > http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/6956dd6e4a00258 I did introduce that but it isn't quite right to call them the same thing. One is delay of complete execution (Future/Promise) and the other is delay for complete application of arguments (Partial Application/Currying). There are, as mentioned, libraries that implement currying in Ruby. There are also many ways to curry and many semantics to chose (execution that is strict, eager, lazy, etc..). I have used currying many times for real world things to specialize the interface of some code while boosting the generic properties of other code. I had curry extensions used in Rails validations for a complex application. The plus came down to allowing me to write only a handful (less than ten) core validators and have many more different combinations actually used across some very rich models. This helped me keep my code DRY and very maintainable. Haskell, another beautiful language, makes good use of currying: Jim's example in Haskell: map (*3) [1,2,3] To see even deeper we can check the infered type of (*) versus (*3): (*) :: (Num a) => a -> (a -> a) (*3) :: (Num a) => a -> a Aside from explaining the syntax [1], you might notice that (*) is a function which actually returns a function which returns a result on that final application. So with this knowledge we could then take the map example one step further: mapMultBy3 = map (*3) mapMultBy3 [1,2,3] The type of mapMultBy3 is easily figured out by thinking of what you pass in and get back out (lists of numbers): mapMultBy3 :: (Num a) => [a] -> [a] This parametric aggregation is really powerful when understood. It also complements many other things like general high order programming really well [2]. In the end it is useful in Ruby if the use is chosen carefully (and sparingly). It may not be first class (for good reason IMO) but as we've seen that is hardly a reason not to consider it in some cases. Hope this didn't get too confusing! </rambling> Brian. [1] I *highly* recommend people learn a _few_ functional programming languages. Haskell is my favorite at the moment but others seem to like OCaml and other ML dialects. Erlang is functional but is quite different from Haskell and OCaml. Esoteric ones exist like Joy and others that might be fun to check out. Last but not least, Scheme is great for playing around with different combinations of things though it doesn't always end up as clean as the above. [2] There probably is a reason most FP languages feature some form of currying ^^.