<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.6000.16788" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY>
<DIV><FONT face="Courier New" size=2>#lang scheme</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>; permute : list-of-a (a a -&gt; boolean) 
-&gt; (list-of list-of-a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>; take all permutations of a list, but do 
not include more than one</FONT></DIV>
<DIV><FONT face="Courier New" size=2>; copy of all permutations A and B for 
which (andmap eq A B)</FONT></DIV><FONT face="Courier New" size=2>
<DIV><BR>(define (permute lst eq)<BR>&nbsp;(if (null? lst) '(())<BR>&nbsp; 
(apply append (map (curry process-rotation eq) (rotations lst eq)))))</DIV>
<DIV>&nbsp;</DIV>
<DIV>; rotations : list-of-a (a a -&gt; boolean) -&gt; (list-of list-of-a)</DIV>
<DIV>; take all rotations of a list, but only those with different cars.</DIV>
<DIV></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>(define (rotations lst eq)<BR>&nbsp;(let 
loop ((head lst) (tail '()))<BR>&nbsp; (cond<BR>&nbsp;&nbsp; ((null? head) 
'())<BR>&nbsp;&nbsp; ((ormap (curry eq (car head)) tail)<BR>&nbsp;&nbsp;&nbsp; 
(loop (cdr head) (cons (car head) tail)))<BR>&nbsp;&nbsp; 
(else<BR>&nbsp;&nbsp;&nbsp; (cons<BR>&nbsp;&nbsp;&nbsp;&nbsp; (append head 
(reverse tail)) ;&nbsp;(*)<BR>&nbsp;&nbsp;&nbsp;&nbsp; (loop (cdr head) (cons 
(car head) tail)))))))</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>; process-rotation : (a a -&gt; boolean) 
(list-of a) -&gt; (listof list-of a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>; cons the car of a rotation to all 
permutations of the cdr of that rotation.</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>(define (process-rotation eq 
rot)<BR>&nbsp;(map (curry cons (car rot)) (permute (cdr rot) eq)))</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>; curry : procedure any ... -&gt; 
procedure</FONT></DIV>
<DIV><FONT face="Courier New" size=2>; curry from left</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>(define (curry fun . args)<BR>&nbsp;(lambda 
other-args<BR>&nbsp; (apply fun (append args other-args))))</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>;test</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>(equal? (permute '(a a b c) 
eq?)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>'((a a b c)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(a a c b)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(a b c a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(a b a c)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(a c a b)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(a c b a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(b c a a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(b a a c)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(b a c a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(c a a b)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(c a b a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2>&nbsp;&nbsp;(c b a a))) ; --&gt; 
#t</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>(*) the reversal is not necessary, but 
without it the word 'rotation' would be misleading </FONT><FONT 
face="Courier New" size=2>and the permutations&nbsp;may&nbsp;be&nbsp;listed in 
another order.</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>Jos</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2></FONT>&nbsp;</DIV>
<DIV><FONT face="Courier New" size=2>----- Original Message ----- </FONT>
<DIV><FONT face="Courier New" size=2>From: "Ben Simon" &lt;</FONT><A 
href="mailto:benjisimon@gmail.com"><FONT face="Courier New" 
size=2>benjisimon@gmail.com</FONT></A><FONT face="Courier New" 
size=2>&gt;</FONT></DIV>
<DIV><FONT face="Courier New" size=2>To: &lt;</FONT><A 
href="mailto:plt-scheme@list.cs.brown.edu"><FONT face="Courier New" 
size=2>plt-scheme@list.cs.brown.edu</FONT></A><FONT face="Courier New" 
size=2>&gt;</FONT></DIV>
<DIV><FONT face="Courier New" size=2>Sent: Sunday, January 04, 2009 8:48 
PM</FONT></DIV>
<DIV><FONT face="Courier New" size=2>Subject: [plt-scheme] Re: Why do layman 
programmers care about Currying?</FONT></DIV></DIV>
<DIV><FONT face="Courier New"><BR><FONT size=2></FONT></FONT></DIV><FONT 
face="Courier New" size=2>On Jan 2, 9:57 am, "Grant Rettke" &lt;</FONT><A 
href="mailto:gret...@acm.org"><FONT face="Courier New" 
size=2>gret...@acm.org</FONT></A><FONT face="Courier New" size=2>&gt; 
wrote:<BR>&gt; On Tue, Dec 30, 2008 at 11:44 PM, Richard Cleis &lt;</FONT><A 
href="mailto:rcl...@me.com"><FONT face="Courier New" 
size=2>rcl...@me.com</FONT></A><FONT face="Courier New" size=2>&gt; 
wrote:<BR>&gt; &gt; On Dec 30, 2008, at 9:12 PM, Grant Rettke wrote:<BR>&gt; 
&gt;&gt; Why do layman (working programmers) care about Currying? Or how 
are<BR>&gt; &gt;&gt; they applied in daily use to help one 
out?<BR>&gt;<BR>[...]<BR>&gt; I don't understand the practical application of 
currying in Scheme, so<BR>&gt; I'm not asking about one or the other; the 
wikipedia link was just my<BR>&gt; going in position on trying to understand 
what is currying.<BR><BR>For me, the practical side of currying has to do with 
providing some<BR>arguments to a function, while leaving others unset. The 
result is a<BR>new function that takes in just the unset arguments.&nbsp; This 
may not<BR>sound very useful, but as the example below attempts to show, it 
can<BR>actually be quite handy.<BR><BR>My suggestion is to read up on SRFI 26 
and make it one of the standard<BR>tools you use.<BR><BR>;;; 
----------------------------------------------------------<BR>#lang 
scheme<BR><BR>;; Scheme doesn't offer automatic currying, but SRFI-26 
provides<BR>;; the (cut ...) operator which gets us close enough.<BR>(require 
srfi/26)<BR><BR>;; A function to send e-mail. This is a bogus 
implementation,<BR>;; could easily be a "real" implementation<BR>(define 
(send-mail smtp-host smtp-port from to subject message)<BR>&nbsp; (printf "Would 
have sent a message: \n")<BR>&nbsp; (printf "&nbsp; SMTP server: ~a:~a\n" 
smtp-host smtp-port)<BR>&nbsp; (printf "&nbsp; From: ~a\n" from)<BR>&nbsp; 
(printf "&nbsp; To: ~a\n" to)<BR>&nbsp; (printf "&nbsp; Subject: ~a\n" 
subject)<BR>&nbsp; (printf "&nbsp; Message: ~a\n" message))<BR><BR>;; A place 
holder function to return a list of e-mail addresses. Used<BR>;; for testing 
below.<BR>(define (list-of-emails)<BR>&nbsp; '("</FONT><A 
href="mailto:foo@nowhere.com"><FONT face="Courier New" 
size=2>foo@nowhere.com</FONT></A><FONT face="Courier New" size=2>" "</FONT><A 
href="mailto:bar@nowhere.com"><FONT face="Courier New" 
size=2>bar@nowhere.com</FONT></A><FONT face="Courier New" size=2>" "</FONT><A 
href="mailto:baz@nowhere.com"><FONT face="Courier New" 
size=2>baz@nowhere.com</FONT></A><FONT face="Courier New" size=2>"))<BR><BR>;; 
Let's start currying...<BR><BR>;; EXAMPLE 1<BR>;; Here we provide two arguments 
to our send-mail function, and leave<BR>;; 3 unset (&lt;&gt; serves as a place 
holder). The result of this is a<BR>those<BR>;; function that takes in 
just&nbsp; 3 remaining arguments.<BR>;;<BR>;; Now we can use `mailer' throughout 
our application and not have to<BR>worry about providing<BR>;; the SMTP host and 
port.<BR>(define mailer (cut send-mail "mail.myhost.com" 25<BR>"</FONT><A 
href="mailto:noreply@myhost.com"><FONT face="Courier New" 
size=2>noreply@myhost.com</FONT></A><FONT face="Courier New" size=2>" &lt;&gt; 
&lt;&gt; &lt;&gt;))<BR><BR>;; Use our mailer<BR>(mailer "</FONT><A 
href="mailto:example@nowhere.com"><FONT face="Courier New" 
size=2>example@nowhere.com</FONT></A><FONT face="Courier New" size=2>" "Hello 
World" "This is just a test...")<BR><BR>;; EXAMPLE 2<BR>;; Let's say we want to 
send the same message over and over again. We<BR>can use (cut ...) to<BR>;; 
provide every argument but the to address.&nbsp; Notice how we can<BR>operate on 
our already curried<BR>;; function.<BR>(define broadcaster (cut mailer &lt;&gt; 
"A Special offer, Just For You"<BR>"Here's a special offer, sent only to you. We 
promise..."))<BR><BR>;; Use our broadcaster<BR>(for-each 
broadcaster<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
(list-of-emails))<BR><BR>;; EXAMPLE 3<BR>;; We can provide all the arguments 
except for a message, and turn our<BR>mail<BR>;; function into a 
logger.<BR>(define logger (cut mailer "</FONT><A 
href="mailto:logging@nowhere.com"><FONT face="Courier New" 
size=2>logging@nowhere.com</FONT></A><FONT face="Courier New" size=2>" "Log 
Message" &lt;&gt;))<BR><BR>;; Pretend this is some complicated 
function<BR>(define (something-complicated logger)<BR>&nbsp; (logger "Starting 
to do something complicated...")<BR>&nbsp; (void)<BR>&nbsp; (logger "Whew, and 
we're done."))<BR>(something-complicated 
logger)<BR>_________________________________________________<BR>&nbsp; For 
list-related administrative tasks:<BR>&nbsp; </FONT><A 
href="http://list.cs.brown.edu/mailman/listinfo/plt-scheme"><FONT 
face="Courier New" 
size=2>http://list.cs.brown.edu/mailman/listinfo/plt-scheme</FONT></A></BODY></HTML>