Bug #18620
closedNot possible to partially curry lambda or proc's `call` method
Description
You can curry the call method of a regular object:
class Foo
def foo(a, b)
a + b
end
end
Foo.new.method(:foo).curry[1][2] # => 3
You can also curry a lambda:
lambda { |a, b| a + b }.curry[1][2] # => 3
Same for a proc:
proc { |a, b| a + b }.curry[1][2] # => 3
However, currying a lambda or proc's call
method doesn't work as expected if not enough arguments are given. Returned error differs in each case:
lambda { |a, b| a + b }.method(:call).curry[1][2] # => `block in <top (required)>': wrong number of arguments (given 1, expected 2) (ArgumentError)
proc { |a, b| a + b }.method(:call).curry[1][2] # => `+': nil can't be coerced into Integer (TypeError)
You can however totally apply the function:
lambda { |a, b| a + b }.method(:call).curry[1, 2] # => 3
proc { |a, b| a + b }.method(:call).curry[1, 2] # => 3
It prevents using callable objects (responding to #call
) and lambda/procs in a polymorphic way in regards to currying.
Updated by waiting_for_dev (Marc Busqué) over 2 years ago
- Subject changed from Not possible to partially curry lamda or proc's `call` method to Not possible to partially curry lambda or proc's `call` method
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
This likely comes from the fact that lambda{|x|}.arity => 1
, but lambda{|x|}.method(:call).arity => -1
. I think if we could set the correct arity for lambda{|x|}.method(:call)
, that would fix this problem. This problem is not specific to call
, it happens with any method whose arity is -1.
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
Turns out that fixing Method#arity
is not sufficient for this to work. This is because Method#curry
does the equivalent to_proc
on the Method, which also loses the arity. So that also needs work. I submitted a pull request to fix this, though the approach used is suboptimal: https://github.com/ruby/ruby/pull/5640
Note that I'm not sure I would consider this a bug. The pull request fixes this particular use case (Proc#method(:call)), but this curry issue occurs with all Method/Proc objects where the arity is not known. I'll add this as an issue for discussion at the next developer meeting.
Updated by Eregon (Benoit Daloze) over 2 years ago
.arity
is normally fixed for a given method definition (e.g., Proc#call
) so I'm not sure supporting this is a good idea, and it would bring some inconsistency.
IMHO the use case is too niche to be worth the added complexity and inconsistency.
Updated by ko1 (Koichi Sasada) over 2 years ago
- Status changed from Open to Rejected
from devmeeting yeasterday:
matz: No change.
matz: it would be good to add a dedicated documentation to Proc#curry, such as “it does not work if the arity is -1”