Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Elegant solution asked
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  15 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
marisal  
View profile  
 More options Mar 5 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: marisal <mari...@wrq.com>
Date: 1997/03/05
Subject: Elegant solution asked

Very often I need a function to map a 2 argument function over a list and
a fixed argument. For example, if we call such function map1:
(map1 #'list 'z '(a b c)) should return: '((z a) (z b) (z c))

Can anyone suggest an elegant solution for this. The best I could come up
with was:

(defun map1 (function fixed-argument list)
    (mapcar (lambda (element) (funcall fn fixed-argument element)) list))

This works fine, but I have the gut feeling that there must be a
better/simpler way. Any ideas?
Thanks in advance.
Please reply to: lsara...@epo.e-mail.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Erik Naggum  
View profile  
 More options Mar 5 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.no>
Date: 1997/03/05
Subject: Re: Elegant solution asked

* mari...@wrq.com
| Very often I need a function to map a 2 argument function over a list and
| a fixed argument. For example, if we call such function map1:
| (map1 #'list 'z '(a b c)) should return: '((z a) (z b) (z c))

recently, I had the same need, and used a circular list like this:

    (defun repeatingly (&rest args)
      (let ((list (copy-list args)))
        (nconc list list)))

    (mapcar #'list (repeatingly 'z) '(a b c))
 => ((z a) (z b) (z c))

this was modeled after the `constantly' function, but I don't know how good
style this is.

#\Erik
--
if you think big enough, you never have to do it


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Erik Naggum  
View profile  
 More options Mar 6 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.no>
Date: 1997/03/06
Subject: Re: Elegant solution asked

* Francis Leboutte
| Maybe you'll prefer this:
|
| USER<10> (defun circular (list)
|            (let ((new-list (copy-list list)))
|               (rplacd (last new-list) new-list)
|               new-list))
| CIRCULAR-LIST
| USER<11>  (mapcar #'list (circular '(z)) '(a b c))
| ((Z A) (Z B) (Z C))

I thought `repeatingly' (or `repeatedly', which I'm told is better a name)
was neat, because it provides a means to let a mapping function map
repeatedly over the object(s) that were the functions' arguments.  calling
it `circular' or `circular-list' says what it is, but not what it means;
there is no abstraction of purpose in sending it a list of the arguments,
quoted or otherwise.  actually, I think using a circular list with a
mapping function is a little "dangerous" unless there are other arguments
that have finite length, and it is also somewhat counter-intuitive to send
a circular list to a mapping function in the first place.  all of this led
me to discard the implementation-like name (which I used at first, too),
and then to use a more functionally abstract name.

I would like to hear opinions on whether this is good style, be it called
by a name that reflects the implementation or the purpose.

#\Erik
--
if you think big enough, you never have to do it


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jason Trenouth  
View profile  
 More options Mar 6 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: ja...@harlequin.co.uk (Jason Trenouth)
Date: 1997/03/06
Subject: Re: Elegant solution asked

On Wed, 05 Mar 1997 21:37:33 -0100, marisal <mari...@wrq.com> wrote:
> Very often I need a function to map a 2 argument function over a list and
> a fixed argument. For example, if we call such function map1:
> (map1 #'list 'z '(a b c)) should return: '((z a) (z b) (z c))

> Can anyone suggest an elegant solution for this. The best I could come up
> with was:

> (defun map1 (function fixed-argument list)
>     (mapcar (lambda (element) (funcall fn fixed-argument element)) list))

> This works fine, but I have the gut feeling that there must be a
> better/simpler way. Any ideas?

You want CURRY, which could be defined as follows:

(defun curry (fn &rest curried-args)
  #'(lambda (&rest args)
      (apply fn (append curried-args args))))

Then you can just do:

(mapcar (curry 'list 'z) '(a b c))
=> ((z a) (z b) (z c))

CURRY is named after its inventor (in case you wondered) and is standard
practice in (other) functional programming languages. For example, the Dylan
language has built-in functions CURRY and RCURRY.

__Jason


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Francis Leboutte  
View profile  
 More options Mar 6 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: a...@glo.be (Francis Leboutte)
Date: 1997/03/06
Subject: Re: Elegant solution asked

Maybe you'll prefer this:

USER<10> (defun circular (list)
           (let ((new-list (copy-list list)))
              (rplacd (last new-list) new-list)
              new-list))
CIRCULAR-LIST
USER<11>  (mapcar #'list (circular '(z)) '(a b c))
((Z A) (Z B) (Z C))

Francis
--
Francis Leboutte, Algorithme, Rue de la Charrette 141, 4130 Tilff, Belgium
a...@glo.be      http://user.glo.be/~algo     t&fax: +32-(0)4-3883528


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
William D Clinger  
View profile  
 More options Mar 6 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: William D Clinger <w...@ccs.neu.edu>
Date: 1997/03/06
Subject: Re: Elegant solution asked

Currying is named after Haskell Curry, but it seems to have been
invented by Schoenfinkel.  The definition of CURRY that was given
in Common Lisp isn't quite the same as the definition normally
used in lambda calculus, which in Scheme would be more like

    (define (curry f)    ; assumes f takes two arguments
      (lambda (x)
        (lambda (y)
          (f x y))))

Then MAP1 can be defined (still in Scheme) by

    (define (map1 f fixed-argument list)
      (map ((curry f) fixed-argument) list))

Erik Naggum wrote:
> I would like to hear opinions on whether this is good style, be it called
> by a name that reflects the implementation or the purpose.

I thought Naggum's solution was cute, although I have a stylistic
prejudice against solutions that use even local side effects (NCONC)
or rely on the fact that MAPCAR has to test all of its arguments.

There isn't much difference in their efficiency, although it should
be slightly faster for the closures created by the original version of
MAP1 or by the curried version above to fetch F and X from their local
environment than it would be to perform the extra CONSP, CAR, and CDR
operations that are required (inside MAPCAR) by Naggum's version.
Some implementations have paid more attention to optimizing MAPCAR
than closures, of course, so your mileage may vary.

Will


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Margolin  
View profile  
 More options Mar 6 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: Barry Margolin <bar...@bbnplanet.com>
Date: 1997/03/06
Subject: Re: Elegant solution asked

In article <3066630268497...@naggum.no>, Erik Naggum  <e...@naggum.no> wrote:

>I thought `repeatingly' (or `repeatedly', which I'm told is better a name)
>was neat, because it provides a means to let a mapping function map
>repeatedly over the object(s) that were the functions' arguments.  calling
>it `circular' or `circular-list' says what it is, but not what it means;
>there is no abstraction of purpose in sending it a list of the arguments,
>quoted or otherwise.  actually, I think using a circular list with a
>mapping function is a little "dangerous" unless there are other arguments
>that have finite length, and it is also somewhat counter-intuitive to send
>a circular list to a mapping function in the first place.  all of this led
>me to discard the implementation-like name (which I used at first, too),
>and then to use a more functionally abstract name.

Your arguments for the name assume that the only purpose of creating a
circular list is to pass it to a mapping function.  Unless you plan on
creating multiple functions, each named after the abstract "purpose" of the
circular list, CIRCULAR-LIST seems like a more appropriate name.  It is
nicely analogous to LIST and VECTOR.

>I would like to hear opinions on whether this is good style, be it called
>by a name that reflects the implementation or the purpose.

If you don't like the idea of passing circular lists to a mapping function
in your application code (I agree, it's somewhat confusing), you could
write an intermediate function:

(defun map-with-constant (mapping-function function constant &rest lists)
  (apply mapping-function function (circular-list constant) lists))

This can then be used as (map-with-constant #'mapcar #'cons 1 '(1 2 3)) =>
((1 . 1) (1 . 2) (1 . 3)).  Only the author of this function needs to be
aware of the way that mapping functions deal with circular lists, rather
than bothering the application programmers with this trivia.
--
Barry Margolin
BBN Corporation, Cambridge, MA
bar...@bbnplanet.com
(BBN customers, call (800) 632-7638 option 1 for support)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rainer Joswig  
View profile  
 More options Mar 8 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: jos...@lavielle.com (Rainer Joswig)
Date: 1997/03/08
Subject: Re: Elegant solution asked

In article <333fc1d0.268080729@newshost>, ja...@harlequin.co.uk (Jason

Trenouth) wrote:
> (defun curry (fn &rest curried-args)
>   #'(lambda (&rest args)
>       (apply fn (append curried-args args))))
> CURRY is named after its inventor (in case you wondered) and is standard

See also: M. Schönfinkel, Über die Bausteine der Mathematischen Logik,
          Math. Ann., 92, 1924

> practice in (other) functional programming languages. For example, the Dylan
> language has built-in functions CURRY and RCURRY.

Does it help to have this in the language itself?!?

--
http://www.lavielle.com/~joswig/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Curry (was Re: Elegant solution asked)" by Bernhard Pfahringer
Bernhard Pfahringer  
View profile  
 More options Mar 11 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: bernh...@saturn.cs.waikato.ac.nz (Bernhard Pfahringer)
Date: 1997/03/11
Subject: Curry (was Re: Elegant solution asked)

In article <333fc1d0.268080729@newshost>,

Jason Trenouth <ja...@harlequin.co.uk> wrote:
> ...
>You want CURRY, which could be defined as follows:

>(defun curry (fn &rest curried-args)
>  #'(lambda (&rest args)
>      (apply fn (append curried-args args))))
> ...

for safety you may want to copy the rest-list:

(defun curry (fn &rest curried-args)
  (setq curried-args (copy-list curried-args))  
  #'(lambda (&rest args)
      (apply fn (append curried-args args))))

and for efficiency (if you call the curried function a lot) use:

(defun curry (fn &rest curry-args)
  (compile nil
           `(lambda (&rest other-args)
              (apply ',fn
                     ,@(loop for x in curry-args collect (list 'quote x))
                     other-args))))

should cons less in for most CL implementations

Bernhard

PS: (loop for x in list collect (funcall fn constant x)) would
also be an alternative answer for the original question
--
-------------- rm - the ultimate in lossy compression ----------------
Bernhard Pfahringer
mailto:bernh...@cs.waikato.ac.nz http://www.ai.univie.ac.at/~bernhard


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Elegant solution asked" by Tom Kramer
Tom Kramer  
View profile  
 More options Mar 11 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: kra...@cme.nist.gov (Tom Kramer)
Date: 1997/03/11
Subject: Re: Elegant solution asked

In article 1...@wrq.com, marisal <mari...@wrq.com> () writes:

> Very often I need a function to map a 2 argument function over a list and
> a fixed argument. For example, if we call such function map1:
> (map1 #'list 'z '(a b c)) should return: '((z a) (z b) (z c))

> Can anyone suggest an elegant solution for this. The best I could come up
> with was:

> (defun map1 (function fixed-argument list)
>     (mapcar (lambda (element) (funcall fn fixed-argument element)) list))

> This works fine, but I have the gut feeling that there must be a
> better/simpler way. Any ideas?
> Thanks in advance.
> Please reply to: lsara...@epo.e-mail.com

I prefer the following (I guess because it avoids the funcall), although
I don't claim it is is significantly better.

(defun map1 (function fixed_argument list) (mapcar function
             (mapcar #'(lambda (x) fixed-argument) list) list))


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jason Trenouth  
View profile  
 More options Mar 11 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: ja...@harlequin.co.uk (Jason Trenouth)
Date: 1997/03/11
Subject: Re: Elegant solution asked

On Sat, 08 Mar 1997 11:13:26 +0100, in comp.lang.lisp you wrote:
> In article <333fc1d0.268080729@newshost>, ja...@harlequin.co.uk (Jason
> Trenouth) wrote:

> > (defun curry (fn &rest curried-args)
> >   #'(lambda (&rest args)
> >       (apply fn (append curried-args args))))

> > CURRY is named after its inventor (in case you wondered) and is standard

> See also: M. Schönfinkel, Über die Bausteine der Mathematischen Logik,
>           Math. Ann., 92, 1924

Also Frege in 1893 according to a functional programming FAQ:

        <URL:http://www.cs.nott.ac.uk/Department/Staff/mpj/faq.html>

> > practice in (other) functional programming languages. For example, the Dylan
> > language has built-in functions CURRY and RCURRY.

> Does it help to have this in the language itself?!?

Dylan has several built-in function-composing functions:

        COMPOSE
        COMPLEMENT
        DISJOIN
        CONJOIN
        CURRY & RCURRY
        ALWAYS

I can't vouch for the Dylan language designers or our own Dylan compiler
wizards, but the fact that they are built-in to Dylan probably serves
pedagogical, standardization, and efficiency purposes.

Eg On the efficiency front I can imagine that a sufficiently smart compiler
would be able to avoid calling the general implementation of CURRY given
above.

__Jason


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Curry (was Re: Elegant solution asked)" by Lyman S. Taylor
Lyman S. Taylor  
View profile  
 More options Mar 11 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: ly...@cc.gatech.edu (Lyman S. Taylor)
Date: 1997/03/11
Subject: Re: Curry (was Re: Elegant solution asked)

In article <5g29tf$...@saturn.cs.waikato.ac.nz>,

Bernhard Pfahringer <bernh...@saturn.cs.waikato.ac.nz> wrote:
>In article <333fc1d0.268080729@newshost>,
....

>for safety you may want to copy the rest-list:

>(defun curry (fn &rest curried-args)
>  (setq curried-args (copy-list curried-args))      
>  #'(lambda (&rest args)
>      (apply fn (append curried-args args))))

  Unless args is NIL, the append above will effectively "copy" curried-args.
  ( and may do so regardless but that's probably implementation dependant.
    I think the standard allows append may return a result that is "eq" with
    either arg if the other arg is NIL. Otherwise the first argument is
    duplicated.  Substitute nconc for append above and yes there may be some
    safety problems.) Also if curried-args is in "danger", why isn't args?

>and for efficiency (if you call the curried function a lot) use:

>(defun curry (fn &rest curry-args)
>  (compile nil
>       `(lambda (&rest other-args)
>          (apply ',fn
>                 ,@(loop for x in curry-args collect (list 'quote x))
>                 other-args))))

   Errr, you can quote functions??

? (defun tester2 ( &rest curry-args )
    (loop for x in curry-args collect (list 'quote x )))
TESTER2
? (tester2 1 2 3 )
('1 '2 '3)
? (tester2 #'car '(1 2 ))
('#<Compiled-function CAR #x65846> '(1 2))
? (funcall (first *) (second  *))

> Error: '#<Compiled-function CAR #x65846> can't be FUNCALLed or APPLYed.
> While executing: CCL::TOPLEVEL-EVAL
> Type Command-. to abort.

See the RestartsI menu item for further choices.
1 >
Aborted
?

--

Lyman S. Taylor          "Any sufficiently advanced technology is
(ly...@cc.gatech.edu)   indistinguishable from a rigged demo. "  
                                   -- paraphrased Arthur C. Clarke
                                        seen somewhere on the USENET


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lyman S. Taylor  
View profile  
 More options Mar 11 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: ly...@cc.gatech.edu (Lyman S. Taylor)
Date: 1997/03/11
Subject: Re: Curry (was Re: Elegant solution asked)

In article <5g29tf$...@saturn.cs.waikato.ac.nz>,

Bernhard Pfahringer <bernh...@saturn.cs.waikato.ac.nz> wrote:
>In article <333fc1d0.268080729@newshost>,
....

>for safety you may want to copy the rest-list:

>(defun curry (fn &rest curried-args)
>  (setq curried-args (copy-list curried-args))      
>  #'(lambda (&rest args)
>      (apply fn (append curried-args args))))

  Unless args is NIL, the append above will effectively "copy" curried-args.
  ( and may do so regardless but that's probably implementation dependant.
    I think the standard allows append may return a result that is "eq" with
    either arg if the other arg is NIL. Otherwise the first argument is
    duplicated.  Substitute nconc for append above and yes there may be some
    safety problems.) Also if curried-args is in "danger", why isn't args?

--

Lyman S. Taylor          "Any sufficiently advanced technology is
(ly...@cc.gatech.edu)   indistinguishable from a rigged demo. "  
                                   -- paraphrased Arthur C. Clarke
                                        seen somewhere on the USENET


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jason Trenouth  
View profile  
 More options Mar 12 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: ja...@harlequin.co.uk (Jason Trenouth)
Date: 1997/03/12
Subject: Re: Curry (was Re: Elegant solution asked)

On 11 Mar 1997 13:44:31 +1300, bernh...@saturn.cs.waikato.ac.nz (Bernhard

APPEND is already copies the list.

> and for efficiency (if you call the curried function a lot) use:

> (defun curry (fn &rest curry-args)
>   (compile nil
>       `(lambda (&rest other-args)
>          (apply ',fn
>                 ,@(loop for x in curry-args collect (list 'quote x))
>                 other-args))))

> should cons less in for most CL implementations

A simpler approach would be to make CURRY a macro instead:

(defmacro curry (fn &rest curried-args)
  `#'(lambda (&rest args)
       (apply ,fn ,@curried-args args)))

__Jason


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Erik Naggum  
View profile  
 More options Mar 12 1997, 3:00 am
Newsgroups: comp.lang.lisp
From: Erik Naggum <e...@naggum.no>
Date: 1997/03/12
Subject: Re: Curry (was Re: Elegant solution asked)

* Jason Trenouth
| > (defun curry (fn &rest curried-args)
| >   (setq curried-args (copy-list curried-args))  
| >   #'(lambda (&rest args)
| >       (apply fn (append curried-args args))))
|
| APPEND is already copies the list.

`append' would copy curried-args, but not args.  I believe this was the
issue, since you take pains to copy the first argument list (as I believe I
did first in this discussion and everybody just copied).

I thought it was necessary to copy the rest list, as I recall having read
that the trivial definition of `list' would not be conforming:

    (defun list (&rest args)
      args)

however, I was in error.  there is no mention of stack-allocating rest
lists in ANSI X3.226, except under the `dynamic-extent' declaration, with
which it may be requested specially.  under `apply', we find the following:

    When the function receives its arguments via &rest, it is permissible
    (but not required) for the implementation to bind the rest parameter to
    an object that shares structure with the last argument to apply.
    Because a function can neither detect whether it was called via apply
    nor whether (if so) the last argument to apply was a constant,
    conforming programs must neither rely on the list structure of a rest
    list to be freshly consed, nor modify that list structure.

the X3J13 issue REST-LIST-ALLOCATION contains a lot of discussion, see
<URL:http://www.harlequin.com/books/HyperSpec/Issues/iss297-writeup.html>.
CLtL2 includes the following about this issue (taken from the published TeX
sources).

    \begin{new}
    X3J13 voted in January 1989
    \issue{REST-LIST-ALLOCATION}
    to clarify that if a function has a {\it rest} parameter and is called
    using \cd{apply}, then the list to which the {\it rest} parameter is
    bound is permitted, but not required, to share top-level list structure
    with the list that was the last argument to \cd{apply}.  Programmers
    should be careful about performing side effects on the top-level list
    structure of a {\it rest} parameter.

    This was the result of a rather long discussion within X3J13 and the
    wider Lisp community.  To set it in its historical context, I must
    remark that in Lisp Machine Lisp the list to which a {\it rest}
    parameter was bound had only dynamic extent; this in conjunction with
    the technique of ``cdr-coding'' permitted a clever stack-allocation
    technique with very low overhead.  However, the early designers of
    Common Lisp, after a great deal of debate, concluded that it was
    dangerous for cons cells to have dynamic extent; as an example, the
    ``obvious'' definition of the function \cd{list}
    \begin{lisp}
    (defun list (\&rest x) x)
    \end{lisp}
    could fail catastrophically.  Therefore the first edition simply
    implied that the list for a {\it rest} parameter, like all other lists,
    would have indefinite extent.  This still left open the flip side of
    the question, namely, Is the list for a {\it rest} parameter guaranteed
    fresh?  This is the question addressed by the X3J13 vote.  If it is
    always freshly consed, then it is permissible to destroy it, for
    example by giving it to \cd{nconc}.  However, the requirement always to
    cons fresh lists could impose an unacceptable overhead in many
    implementations.  The clarification approved by X3J13 specifies that
    the programmer may not rely on the list being fresh; if the function
    was called using \cd{apply}, there is no way to know where the list
    came from.
    \end{new}

the index to issues lists this as having been voted MAY-SHARE, that is:

    (defvar *my-list* '(a b c))
    (defun foo (&rest x) (eq x *my-list*))
    (apply #'foo *my-list*) => implementation-dependent

in any case, it seems that the need to copy the top-level list structure of
the rest list is not necessary unless the list structure will be modified,
which we don't.  for reference, this is the function definition from Paul
Graham's ANSI Common Lisp.  his Dylan function buildrs go like this (from
figure 6.2, page 110),

    (defun compose (&rest fns)
      (destructuring-bind (fn1 . rest) (reverse fns)
        #'(lambda (&rest args)
            (reduce #'(lambda (v f) (funcall f v))
                    rest
                    :initial-value (apply fn1 args)))))

    (defun disjoin (fn &rest fns)
      (if (null fns)
          fn
          (let ((disj (apply #'disjoin fns)))
            #'(lambda (&rest args)
                (or (apply fn args) (apply disj args))))))

    (defun conjoin (fn &rest fns)
      (if (null fns)
          fn
          (let ((conj (apply #'conjoin fns)))
            #'(lambda (&rest args)
                (and (apply fn args) (apply conj args))))))

    (defun curry (fn &rest args)
      #'(lambda (&rest args2)
          (apply fn (append args args2))))

    (defun rcurry (fn &rest args)
      #'(lambda (&rest args2)
          (apply fn (append args2 args))))

    (defun always (x) #'(lambda (&rest args) x))

#\Erik
--
how to beat Microsoft, death, and poverty: in July 1994, there were more
references to my name (3039) in gopherspace than to Microsoft (2557), death
(2530), and poverty (2410).  (http://veronica.sonoma.edu:8001/top1000.html)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »