<!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> </DIV>
<DIV><FONT face="Courier New" size=2>; permute : list-of-a (a a -> boolean)
-> (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> (if (null? lst) '(())<BR>
(apply append (map (curry process-rotation eq) (rotations lst eq)))))</DIV>
<DIV> </DIV>
<DIV>; rotations : list-of-a (a a -> boolean) -> (list-of list-of-a)</DIV>
<DIV>; take all rotations of a list, but only those with different cars.</DIV>
<DIV></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>(define (rotations lst eq)<BR> (let
loop ((head lst) (tail '()))<BR> (cond<BR> ((null? head)
'())<BR> ((ormap (curry eq (car head)) tail)<BR>
(loop (cdr head) (cons (car head) tail)))<BR>
(else<BR> (cons<BR> (append head
(reverse tail)) ; (*)<BR> (loop (cdr head) (cons
(car head) tail)))))))</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>; process-rotation : (a a -> boolean)
(list-of a) -> (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> </DIV>
<DIV><FONT face="Courier New" size=2>(define (process-rotation eq
rot)<BR> (map (curry cons (car rot)) (permute (cdr rot) eq)))</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>; curry : procedure any ... ->
procedure</FONT></DIV>
<DIV><FONT face="Courier New" size=2>; curry from left</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>(define (curry fun . args)<BR> (lambda
other-args<BR> (apply fun (append args other-args))))</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>;test</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </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> (a a c b)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (a b c a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (a b a c)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (a c a b)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (a c b a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (b c a a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (b a a c)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (b a c a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (c a a b)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (c a b a)</FONT></DIV>
<DIV><FONT face="Courier New" size=2> (c b a a))) ; -->
#t</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </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 may be listed in
another order.</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>Jos</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>----- Original Message ----- </FONT>
<DIV><FONT face="Courier New" size=2>From: "Ben Simon" <</FONT><A
href="mailto:benjisimon@gmail.com"><FONT face="Courier New"
size=2>benjisimon@gmail.com</FONT></A><FONT face="Courier New"
size=2>></FONT></DIV>
<DIV><FONT face="Courier New" size=2>To: <</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>></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" <</FONT><A
href="mailto:gret...@acm.org"><FONT face="Courier New"
size=2>gret...@acm.org</FONT></A><FONT face="Courier New" size=2>>
wrote:<BR>> On Tue, Dec 30, 2008 at 11:44 PM, Richard Cleis <</FONT><A
href="mailto:rcl...@me.com"><FONT face="Courier New"
size=2>rcl...@me.com</FONT></A><FONT face="Courier New" size=2>>
wrote:<BR>> > On Dec 30, 2008, at 9:12 PM, Grant Rettke wrote:<BR>>
>> Why do layman (working programmers) care about Currying? Or how
are<BR>> >> they applied in daily use to help one
out?<BR>><BR>[...]<BR>> I don't understand the practical application of
currying in Scheme, so<BR>> I'm not asking about one or the other; the
wikipedia link was just my<BR>> 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. 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> (printf "Would
have sent a message: \n")<BR> (printf " SMTP server: ~a:~a\n"
smtp-host smtp-port)<BR> (printf " From: ~a\n" from)<BR>
(printf " To: ~a\n" to)<BR> (printf " Subject: ~a\n"
subject)<BR> (printf " 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> '("</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 (<> serves as a place
holder). The result of this is a<BR>those<BR>;; function that takes in
just 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>" <>
<> <>))<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. Notice how we can<BR>operate on
our already curried<BR>;; function.<BR>(define broadcaster (cut mailer <>
"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>
(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" <>))<BR><BR>;; Pretend this is some complicated
function<BR>(define (something-complicated logger)<BR> (logger "Starting
to do something complicated...")<BR> (void)<BR> (logger "Whew, and
we're done."))<BR>(something-complicated
logger)<BR>_________________________________________________<BR> For
list-related administrative tasks:<BR> </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>