Here's one more version of the partial evaluation. It works with 
Procs and Methods, and it allows to "override" not only the first 
arguments (see the example of minus at the end).

Like Robert's solution, it uses the arity method, and it only handles 
the simple cases of arity, too...


def partial_eval( function, *args )
  
  remaining_args = []
  all_args = []
  
  function.arity.times do | i |
    if args[ i ]
      all_args << "args[#{i}]"
    else
      remaining_args << "a#{i}"
      all_args << "a#{i}"
    end
  end

  remaining_args = remaining_args.join( ", " )
  all_args = all_args.join( ", " )
  
  eval "proc { | #{remaining_args} | function[ #{all_args} ] }"

end

#---------------

sum_proc = proc { |a,b| a+b }

def sum_method( a, b )
  a+b
end

sum_proc_4 = partial_eval( sum_proc, 4 )
sum_method_4 = partial_eval( method( :sum_method ), 4 )

puts sum_proc_4[ 8 ]     # --> 12
puts sum_method_4[ 8 ]   # --> 12

#---------------

minus = proc { |a,b| a-b }

minuend_5 = partial_eval( minus, 5 )
subtrahend_5 = partial_eval( minus, nil, 5 )

puts minuend_5[ 3 ]      # --> 2
puts subtrahend_5[ 9 ]   # --> 4


Regards,
Pit

On 1 Dec 2001, at 6:17, MikkelFJ wrote:

> 
> "Ralph Mason" <ralph.mason / telogis.com> wrote in message
> news:13ef01c1795d$0580a180$0101a8c0 / p3...
> > I'm not so sure what you are trying to do here.  It looks like you
> > are returning a combination of a class instance and a function.
> 
> Yes - that is one the issues. I don't even know how this works in an
> OOP style functional language like OCaml.
> 
> I don't quite follow your example:
> 
> > y = x.doit(4)
> >
> > z = y.doit(3,5)
> 
> Now y should hold a function, curried (partially evaluated), but it is
> not an object with a method doit, it is just a function of one
> parameter - and a hidden context to its owner. Hence z = y(5) #=> 4 +
> 5 = 9 But this example doesn't exploit the hidden context. The pure
> functional view has been covered by Feldt and Splitz.
> 
> MikkelFJ
> 
> 
> 
>