Project

General

Profile

Feature #6253

Implement a way to pass keyword options to curried procs

Added by jballanc (Joshua Ballanco) about 8 years ago. Updated almost 8 years ago.

Status:
Rejected
Priority:
Normal
Target version:
[ruby-core:44122]

Description

=begin
(See original discussion in issue #4610)

With the introduction of keyword arguments in Ruby 2.0, it would be useful to have a way to set a keyword-based option on a curried proc. The example below demonstrates a Rack-like system where a curried proc is passed to a helper, then after partial application of the arguments, the returned curried proc is stored and later evaluated:

class NicknameTranslator
  def initialize(app)
    @app = app
  end

  def call(name)
    case name
    when 'Robert'
      @app.call('Bob')
    when 'James'
      @app.call('Jimmy')
    else
      @app.call(name)
    end
  end
end

class NightGreeting
  def initialize(app)
    @app = app
    @app.pass_option(greeting: 'Goodnight')
  end

  def call(name)
    @app.call(name)
  end
end

class Greeter
  def initialize(helper)
    @helper = helper
    @app = lambda do |sender, receiver, greeting: 'Hello'|
      puts "#{sender} says \"#{greeting}\" to #{receiver}"
    end.curry
    @greetings = {}
  end

  def call(sender, receiver)
    @greetings[sender] ||= @helper.new(@app).call(sender)
    @greetings[sender].call(receiver)
  end
end

Greeter.new(NicknameTranslator).call('Josh', 'Joe')
Greeter.new(NicknameTranslator).call('Robert', 'Joe')
Greeter.new(NicknameTranslator).call('Josh', 'Robert')

If we wanted, however, to be able to set a keyword-based option in the helper, there is currently no way in Ruby 2.0 to do so. Currently, keyword arguments can only be used at the same time as the final non-keyword, non-default, non-rest argument to the proc is applied. So, for example, there is no way to do the above with NightGreeting in place of NicknameTranslator.

Currying is really only useful when it can be used with partial application. However, Ruby currently limits how you can achieve partial application of curried procs. In particular, there is no way to manage partial application of parameters with default values. As such, it is not surprising that Proc#curry does not seem to have been adopted very widely. In my personal survey of ~600 gems that I use in various projects, I did not find any usage of Proc#curry.

So, I would request a method like Proc#pass_option (or some other, better name) that allows for setting keyword arguments on a curried proc at any time.
=end


Files

6253-proposal.pdf (30.3 KB) 6253-proposal.pdf jballanc (Joshua Ballanco), 06/28/2012 05:05 PM

Also available in: Atom PDF