Project

General

Profile

Actions

Bug #18620

closed

Not possible to partially curry lambda or proc's `call` method

Added by waiting_for_dev (Marc Busqué) about 2 years ago. Updated about 2 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux]
[ruby-core:107820]

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.

Actions #1

Updated by waiting_for_dev (Marc Busqué) about 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) about 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) about 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) about 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) about 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”

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0