From: Clemens Hintze Date: 2000-07-17T21:44:17+00:00 Subject: [ruby-talk:04096] Re: What are you using Ruby for? > Aleksi Niemel writes: > > Johann: ... > This is one thing that I never quite understood about the "pure > object-oriented languages"---they seem to dislike functions. > Functions are very real things, quite useful in fact, but their a pain > to manipulate, at least in Eiffel and Sather. Hmmm ... I wouldn't say they dislike functions ... I think that functions are not really necessary if I can have methods and closures! They seem less powerful, IMHO, than the combination of these both ... > As an example of what I do in python, I have a program which > implements several functions over a dataset, then lets the user pick > which functions to plot from the command line. There are also > multiple forms of each function, which are (in general) variable > transformations. > > The code looks like: > > def make_g_from_f(f): > def temp(x, y, f=f): # ugly python lack of closures > return f(x, y)*scale(x, y) > return temp > > def f1(x, y): > return > register_function("f1", f1, "Compute something") > > g1 = make_g_from_f(f1) # useful python 1st-class functions > register_function("g1", g1, "Compute something scaled by scale") The closed (without thinking) I come at the first glance could be: def make_g_from_proc(f) return proc { |x, y| return f.call(x,y)*scale(x,y) } end def f1(x, y) return end register_proc("f1", method(:f1), "compute something") g1 = make_g_from_proc(method(:f1)) register_proc("g1", g1, "compute something scaled by scale") This tries to resemble as much Python's solution as possible. The only big difference is that you have to pass a Proc instance to make_g_from_proc ... So passing a method would need to get the method first and convert it into a Proc instance! If I would use closures on all places where I would use a function in Python, then I would even not have to convert a method to an Proc instance ... something like: f1 = proc { |x, y| return } register_proc("f1", f1, "compute someting") g1 = make_g_from_proc(f1) register_proc("g1", g1, "compute something scaled by scale") ... > As I understand Ruby, I would have to make all of these functions into > global Proc objects and use $-names to reference them, if I want f1 > and g1 to be callable using the same conventions. That seems like it > would get very ugly very fast. If you insisting of same call convention and global accessible names, perhaps! But no, wait a moment. There is a solution, not very elegant but ... def f1 return proc { |x, y| return } end f1.call(1,2) register_proc "f1", f1, "compute something" g1 = make_g_from_proc f1 register_proc "g1", g1, "compute something scaled by scale" Now it looks equal and you have to use the same calling convention. But I admit this is not too pretty ... Especially as calling it via f1.call will do one indirection indeed! But I would try to solve this in a more OO way ... Using closures resembling functions! Store them in a certain module/class that indicates that these closures are thought to work on certain data for computation ... ... \cle