# Suggestion: Proc#curry

**URL:** <https://www.ruby-forum.com/t/suggestion-proc-curry/128616>\
**Category:** Development\
**Created:** [February 9, 2008, 12:40pm UTC](https://www.ruby-forum.com/t/suggestion-proc-curry/128616 "2008-02-09T12:40:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [February 9, 2008, 12:40pm UTC](https://www.ruby-forum.com/t/suggestion-proc-curry/128616/1 "2008-02-09T12:40:59Z")

</div>

e$B1sF#$H?=$7$^$9!#e(B

[http://subtech.g.hatena.ne.jp/cho45/20071119/1195420784](http://subtech.g.hatena.ne.jp/cho45/20071119/1195420784)  
e$B$GDs0F$5$l$F$$$ke(B Proc#curry e$B$rAH$\_9~$`$N$O$I$&$G$7$g$&$+!#e(B

proc {|x, y, z| x + y + z }.curry  
e$B$,e(B  
proc {|x| proc {|y| proc {|z| x + y + z } } }  
e$B$HF1$80UL#$K$J$j$^$9!#e(B

ski e$B%3%s%S%M!\<%?$r=q$/$H$-$J$I$K!"$5$5$d$+$J9,$;$,F@$i$l$^$9!#e(B

s = proc {|f, g, x| f[x][g[x]] }.curry  
k = proc {|x, y| x }.curry

e$B5U$K!"e(BProc#curry e$B$NB8:\_$,32$K$J$k$3$H$O$J$$$H;W$$$^$9!#e(B

e$B0J2\<$O$?$?$-Bf$G$9!#e(B

# Index: proc.c

— proc.c (revision 15417)  
+++ proc.c (working copy)  
@@ -1608,7 +1608,60 @@  
return bindval;  
}

+static VALUE curry(VALUE dummy, VALUE args, int argc, VALUE \*argv);  
+  
+static VALUE  
+make\_curry\_proc(VALUE proc, VALUE passed, VALUE arity)  
+{

- VALUE args = rb\_ary\_new2(3);
- RARRAY\_PTR(args)[0] = proc;
- RARRAY\_PTR(args)[1] = passed;
- RARRAY\_PTR(args)[2] = arity;
- rb\_ary\_freeze(args);
- rb\_ary\_freeze(passed);
- return rb\_proc\_new(curry, args);  
+}
- 

+static VALUE  
+curry(VALUE dummy, VALUE args, int argc, VALUE \*argv)  
+{

- int i;
- VALUE proc, passed, arity;
- proc = RARRAY\_PTR(args)[0];
- passed = RARRAY\_PTR(args)[1];
- arity = RARRAY\_PTR(args)[2];
- 
- passed = rb\_ary\_plus(passed, rb\_ary\_new4(argc, argv));
- if(RARRAY\_LEN(passed) \< FIX2INT(arity)) {
- return make\_curry\_proc(proc, passed, arity);
- }
- return rb\_proc\_call(proc, passed);  
+}
- 

/\*

- 
  - call-seq:

- 
  - 

```
prc.curry => a_proc

```

- 
  - 

- 
  - Returns a curried proc.

- 
  - 

- 
  - 

```
x = proc {|a, b, c| a + b + c }

```

- 
  - 

```
p x[1, 2, 3] #=> 6

```

- 
  - 

```
x = x.curry

```

- 
  - 

```
p x[1][2][3] #=> 6

```

- \*/  
+static VALUE  
+proc\_curry(VALUE self)  
+{
- VALUE arity = proc\_arity(self);
- 
- if(FIX2INT(arity) \< 0) {
- arity = INT2FIX(-FIX2INT(arity) - 1);
- }
- 
- return make\_curry\_proc(self, rb\_ary\_new(), arity);  
+}
- 

+/\*

- `Proc` objects are blocks of code that have been bound  
to
- a set of local variables. Once bound, the code may be called in
- different contexts and still access those variables.  
@@ -1646,6 +1699,7 @@  
rb\_define\_method(rb\_cProc, “to\_s”, proc\_to\_s, 0);  
rb\_define\_method(rb\_cProc, “lambda?”, proc\_lambda\_p, 0);  
rb\_define\_method(rb\_cProc, “binding”, proc\_binding, 0);

- rb\_define\_method(rb\_cProc, “curry”, proc\_curry, 0);

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [February 11, 2008, 2:52pm UTC](https://www.ruby-forum.com/t/suggestion-proc-curry/128616/2 "2008-02-11T14:52:22Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:33676] Suggestion: Proc#curry”  
on Sat, 9 Feb 2008 20:40:19 +0900, “Yusuke ENDOH” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|[はてなグループの終了日を2020年1月31日(金)に決定しました - はてなの告知](http://subtech.g.hatena.ne.jp/cho45/20071119/1195420784)  
|e$B$GDs0F$5$l$F$$$ke(B Proc#curry e$B$rAH$\_9~$`$N$O$I$&$G$7$g$&$+!#e(B  
|  
|proc {|x, y, z| x + y + z }.curry  
|e$B$,e(B  
|proc {|x| proc {|y| proc {|z| x + y + z } } }  
|e$B$HF1$80UL#$K$J$j$^$9!#e(B

e$B$&!\<$s!"%+%j!\<2=$C$Fe(B

f = proc{|x, y, z| x + y + z }  
f2 = f.curry(2)  
f3 = f2.curry(3)  
f3[4] # =\> 9

e$B$C$Fe(BAPIe$B$J$s$8$c$J$$$s$G$7$g$&$+!#$=$l$H$b$?$$$7$?0c$$$8$c$Je(B  
e$B$$!)e(B

|e$B5U$K!"e(BProc#curry e$B$NB8:\_$,32$K$J$k$3$H$O$J$$$H;W$$$^$9!#e(B

e$BL\>A0$NE@$GG\<F@$9$l$PF3F~$KH?BP$7$^$;$s!#e(B

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [February 11, 2008, 5:29pm UTC](https://www.ruby-forum.com/t/suggestion-proc-curry/128616/3 "2008-02-11T17:29:34Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:33701] Re: Suggestion: Proc#curry”  
on Mon, 11 Feb 2008 23:53:59 +0900, “Yusuke ENDOH” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|\> e$B$&!\<$s!“%+%j!\<2=$C$Fe(B  
|  
|e$B%+%j!\<2=$H$$$&$N$O!”!Ve(Bn e$B8D$N0z?t$rF1;~$K\<u$1\<h$C$F\<B9T$9$k4X?t!W$r!"e(B  
|e$B!V0z?t$re(B 1 e$B8D$:$De(B n e$B2s$N8F$S=P$7$KJ,$1$F\<u$1\<h$C$?8e$K\<B9T$9$k4X?t!We(B  
|e$B$KJQ$($k$3$H$G$9!#e(B  
|e$B7?$G8@$&$J$ie(B (ae$B!\_e(Bbe$B!\_e(Bce$B!\_e(Bd)-\>z e$B$J4X?t$+$ie(B a-\>b-\>c-\>d-\>z e$B$J4X?t$K$9$ke(B  
|e$B$3$H$G$9!#e(B

e$B$=$&$J$s$@!#L5CN$rO\*Dh$7$F$^$9$M!#e(B

|\> f = proc{|x, y, z| x + y + z }  
|\> f2 = f.curry(2)  
|\> f3 = f2.curry(3)  
|\> f3[4] # =\> 9  
|\>  
|\> e$B$C$Fe(BAPIe$B$J$s$8$c$J$$$s$G$7$g$&$+!#$=$l$H$b$?$$$7$?0c$$$8$c$Je(B  
|\> e$B$$!)e(B  
|  
|e$B$3$l$O%+%j!\<2=$G$O$J$/$FItJ,E,MQ$G$9$M!#$3$l$O$3$l$G0UL#$,$"$ke(B  
|e$B$+$b$7$l$^$;$s!#e(B

e$B@$$NCf$K$O$3$&$$$&e(Bcurrye$B4X?t$,$"$U$l$F$^$9$M!#e(B

e$B$G!"G\<F@$7$?$N$G%3%\_%C%H$7$F$/$@$5$$!#e(B

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [February 11, 2008, 3:54pm UTC](https://www.ruby-forum.com/t/suggestion-proc-curry/128616/4 "2008-02-11T15:54:51Z")

</div>

e$B1sF#$G$9!#e(B

08/02/11 e$B$Ke(B Yukihiro M.[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
e$B$5$s$O=q$-$^$7$?e(B:

> |proc {|x| proc {|y| proc {|z| x + y + z } } }  
> |e$B$HF1$80UL#$K$J$j$^$9!#e(B
> 
> e$B$&!\<$s!"%+%j!\<2=$C$Fe(B

e$B%+%j!\<2=$H$$$&$N$O!"!Ve(Bn  
e$B8D$N0z?t$rF1;~$K\<u$1\<h$C$F\<B9T$9$k4X?t!W$r!"e(B  
e$B!V0z?t$re(B 1 e$B8D$:$De(B n  
e$B2s$N8F$S=P$7$KJ,$1$F\<u$1\<h$C$?8e$K\<B9T$9$k4X?t!We(B  
e$B$KJQ$($k$3$H$G$9!#e(B  
e$B7?$G8@$&$J$ie(B (ae$B!\_e(Bbe$B!\_e(Bce$B!\_e(Bd)-\>z e$B$J4X?t$+$ie(B  
a-\>b-\>c-\>d-\>z e$B$J4X?t$K$9$ke(B  
e$B$3$H$G$9!#e(B

> f = proc{|x, y, z| x + y + z }  
> f2 = f.curry(2)  
> f3 = f2.curry(3)  
> f3[4] # =\> 9
> 
> e$B$C$Fe(BAPIe$B$J$s$8$c$J$$$s$G$7$g$&$+!#$=$l$H$b$?$$$7$?0c$$$8$c$Je(B  
> e$B$$!)e(B

e$B$3$l$O%+%j!\<2=$G$O$J$/$FItJ,E,MQ$G$9$M!#$3$l$O$3$l$G0UL#$,$"$ke(B  
e$B$+$b$7$l$^$;$s!#e(B

---

<div class="post-metadata">

**Author:** ![Yusuke\_ENDOH](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/c89c15/32.png) [@Yusuke\_ENDOH](https://www.ruby-forum.com/u/Yusuke_ENDOH)\
**Post date:** [February 13, 2008, 1:57pm UTC](https://www.ruby-forum.com/t/suggestion-proc-curry/128616/5 "2008-02-13T13:57:57Z")

</div>

e$B1sF#$G$9!#e(B

08/02/12 e$B$Ke(B Yukihiro M.[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
e$B$5$s$O=q$-$^$7$?e(B:

> e$B@$$NCf$K$O$3$&$$$&e(Bcurrye$B4X?t$,$"$U$l$F$^$9$M!#e(B

e$B$h$/$"$k8mMQ$\_$?$$$G$9!#8mMQ$b9-$^$l$P@5MQ!)e(B  
[http://lambda-the-ultimate.org/node/2266](http://lambda-the-ultimate.org/node/2266)

> e$B$G!"G\<F@$7$?$N$G%3%\_%C%H$7$F$/$@$5$$!#e(B

e$B%3%\_%C%H$7$^$7$?!#e(B  
e$B2DJQD90z?t$I$&$9$k$H$+!"e(Blambda e$B$He(B proc  
e$B$N0c$$$I$&$9$k$H$+!"e(B  
e$B0z?te(B 0 e$B8D$N$H$-$I$&$9$k$H$+$O!"E,Ev$K7h$a$F$7$^$$$^$7$?!#e(B  
e$B$^$:$+$C$?$iD\>$7$^$9!#e(B

- call-seq:
- 

```
prc.curry => a_proc

```

- 

```
prc.curry(arity) => a_proc

```

- 
- Returns a curried proc. If the optional _arity_ argument is  
given,
- it determines the number of arguments.
- A curried proc receives some arguments. If a sufficient number of
- arguments are supplied, it passes the supplied arguments to the  
original
- proc and returns the result. Otherwise, returns another curried  
proc that
- takes the rest of arguments.
- 
- 

```
b = proc {|x, y, z| (x||0) + (y||0) + (z||0) }

```

- 

```
p b.curry[1][2][3] #=> 6

```

- 

```
p b.curry[1, 2][3, 4] #=> 6

```

- 

```
p b.curry(5)[1][2][3][4][5] #=> 6

```

- 

```
p b.curry(5)[1, 2][3, 4][5] #=> 6

```

- 

```
p b.curry(1)[1] #=> 1

```

- 
- 

```
b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, 

```

&:+) }

- 

```
p b.curry[1][2][3] #=> 6

```

- 

```
p b.curry[1, 2][3, 4] #=> 10

```

- 

```
p b.curry(5)[1][2][3][4][5] #=> 15

```

- 

```
p b.curry(5)[1, 2][3, 4][5] #=> 15

```

- 

```
p b.curry(1)[1] #=> 1

```

- 
- 

```
b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }

```

- 

```
p b.curry[1][2][3] #=> 6

```

- 

```
p b.curry[1, 2][3, 4] #=> wrong number of arguments (4 or 

```

1. 

- 

```
p b.curry(5) #=> wrong number of arguments (5 or 

```

1. 

- 

```
p b.curry(1) #=> wrong number of arguments (1 or 

```

1. 

- 
- 

```
b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, 

```

&:+) }

- 

```
p b.curry[1][2][3] #=> 6

```

- 

```
p b.curry[1, 2][3, 4] #=> 10

```

- 

```
p b.curry(5)[1][2][3][4][5] #=> 15

```

- 

```
p b.curry(5)[1, 2][3, 4][5] #=> 15

```

- 

```
p b.curry(1) #=> wrong number of arguments (1 or 

```

1. 

- 
- 

```
b = proc { :foo }

```

- 

```
p b.curry[] #=> :foo

```
