Feature #13765
openAdd Proc#bind
Description
Proc has curry but no method to do partial application. Something like Proc#bind might be handy.
A naive implementation might look something like
class Proc
  def bind(*bound_args)
    -> (*args) { self.call(*bound_args, *args) }
  end
end
irb(main):001:0> foo = -> (first, second) { puts first, second }
=> #<Proc:0x007fc93a091f90@(irb):6 (lambda)>
irb(main):002:0> foo.bind(1).call(2)
1
2
=> nil
irb(main):003:0> foo.bind(1).bind(2).call
1
2
which does the job with the downside of only reporting argument mismatches when the returned Proc is called.
irb(main):004:0> foo3 = foo.bind(1).bind(2).bind(3)
=> #<Proc:0x007fc9378bcb00@(irb):3 (lambda)>
irb(main):005:0> foo.call
ArgumentError: wrong number of arguments (given 0, expected 2)
	from (irb):6:in `block in irb_binding'
	from (irb):35
	from /usr/local/bin/irb:11:in `<main>'
        
           Updated by k0kubun (Takashi Kokubun) over 8 years ago
          Updated by k0kubun (Takashi Kokubun) over 8 years ago
          
          
        
        
      
      Could you show a real Ruby application or code which you can write more effectively if we have partial application?
        
           Updated by shevegen (Robert A. Heiler) over 8 years ago
          Updated by shevegen (Robert A. Heiler) over 8 years ago
          
          
        
        
      
      I do not have any pro or con opinion per se; my slight worry is about the name "bind".
When I read .bind, I wonder what is actually bound, and to what it is bound.
        
           Updated by davidcornu (David Cornu) over 8 years ago
          Updated by davidcornu (David Cornu) over 8 years ago
          
          
        
        
      
      I do not have any pro or con opinion per se; my slight worry is about the name "bind".
Yeah I share that concern. Ruby has a concept of bound methods which might get confused with this.
Lodash/Underscore refer to this as partial (https://lodash.com/docs/#partial) which could be a better name.
        
           Updated by davidcornu (David Cornu) over 8 years ago
          Updated by davidcornu (David Cornu) over 8 years ago
          
          
        
        
      
      Could you show a real Ruby application or code which you can write more effectively if we have partial application?
The use case is similar to that of Proc#curry, but I'd agree that typical Ruby code doesn't rely on Procs much. The lack of partial application on Proc just seemed like an odd omission.
The particular code I was writing that led to this implemented pagination by returning the current page of results and a proc to fetch the next page.
Example:
bind = -> (fn, *bound_args) {
  -> (*args) { fn.(*bound_args, *args) }
}
fetch_page = -> (page = 1) {
  # Perform request
  [results, bind.(fetch_page, page + 1)]  
}
which lets you use it as follows
results, next_page = fetch_page.()
until results.empty?
  # Process results
  results, next_page = next_page.()
end
        
           Updated by k0kubun (Takashi Kokubun) over 8 years ago
          Updated by k0kubun (Takashi Kokubun) over 8 years ago
          
          
        
        
      
      - Related to Feature #6817: Partial application added
        
           Updated by k0kubun (Takashi Kokubun) over 8 years ago
          Updated by k0kubun (Takashi Kokubun) over 8 years ago
          
          
        
        
      
      - Related to Feature #7939: Alternative curry function creation added