From: ···············@gmail.com
Subject: mapcar using a function with one argument fixed
Date: 
Message-ID: <e2e2edd7-da5c-4d77-8405-7039e3fdcb19@e4g2000hsg.googlegroups.com>
Greetings!

What is the most _elegant_ way to mapcar a list with a function that
takes multiple values, setting some constant.  Is there no neater
alternative to

(mapcar (lambda (x) (my-function x a b c)) my-list)

?

I use this a lot, and the lambdas are taking over!!

If this is not possible, would it be difficult to write a macro
implementing a construct like this:

(my-map (x1 .. xN) form list1 ... listN)

where form can reference xi.  So I could for example just write

(my-map (x y) (my-function a y x b) list-for-xs list-for-ys)

I am new to lisp so I would appreciate any advice.

Thanks,
Andrew

From: Alan Crowe
Subject: Re: mapcar using a function with one argument fixed
Date: 
Message-ID: <86hciypdct.fsf@cawtech.freeserve.co.uk>
···············@gmail.com writes:

> What is the most _elegant_ way to mapcar a list with a function that
> takes multiple values, setting some constant.  Is there no neater
> alternative to
> 
> (mapcar (lambda (x) (my-function x a b c)) my-list)
> 
> I use this a lot, and the lambdas are taking over!!

I like to hide the lambdas with a little macro

CL-USER> (defmacro defcurry (name 
                             (&rest primary-arglist)
                             (&rest secondary-arglist)
                             &body code)
           `(defun ,name ,primary-arglist
             (lambda ,secondary-arglist ,@code)))

CL-USER> (defcurry increase-by (x)(y) (+ x y))

CL-USER> (funcall (increase-by 5) 7) => 12

Using LOOP is also good, but they do not do quite the same
thing

CL-USER> (mapcar (increase-by (random 100)) '(1 2 3 4 5 6 7))

=> (11 12 13 14 15 16 17)

CL-USER> (loop for x in '(1 2 3 4 5 6 7)
               collect (+ x (random 100)))

=> (38 21 29 99 21 63 103)

LOOP has a WITH keyword

CL-USER> (loop with y = (random 100)
               for x in '(1 2 3 4 5 6 7)
               collect (+ x y))

=> (83 84 85 86 87 88 89)

but I prefer defcurry because it tidies away the tempory variable.

> 
> If this is not possible, would it be difficult to write a macro
> implementing a construct like this:
> 
> (my-map (x1 .. xN) form list1 ... listN)
> 
> where form can reference xi.  So I could for example just write
> 
> (my-map (x y) (my-function a y x b) list-for-xs list-for-ys)
> 
> I am new to lisp so I would appreciate any advice.
> 

The rule that I try to stick to is that my macros automate the
writing of boiler plate code, but do not try to add general
purpose enhancements to the language. My macros end up
capturing knowledge about my application, not about
programming in general. 

The reasoning behind my rule is that Lisp is an adequate
general purpose programming language. So it is hard to come
up with general purpose macros. One whiles away many a happy
hour fiddling with this or footering with that until one
sighs and admits that ones cute little macro doesn't earn
its keep.

So do as I do, and not as I say, and enjoy wasting all the Sunday
afternoons till the end of time writing little macros to
"improve" Common Lisp.

Alan Crowe
Edinburgh
Scotland
From: Rainer Joswig
Subject: Re: mapcar using a function with one argument fixed
Date: 
Message-ID: <joswig-080690.17553104122007@news-europe.giganews.com>
In article 
<····································@e4g2000hsg.googlegroups.com>,
 ···············@gmail.com wrote:

> Greetings!
> 
> What is the most _elegant_ way to mapcar a list with a function that
> takes multiple values, setting some constant.  Is there no neater
> alternative to
> 
> (mapcar (lambda (x) (my-function x a b c)) my-list)
> 
> ?
> 
> I use this a lot, and the lambdas are taking over!!
> 
> If this is not possible, would it be difficult to write a macro
> implementing a construct like this:
> 
> (my-map (x1 .. xN) form list1 ... listN)
> 
> where form can reference xi.  So I could for example just write
> 
> (my-map (x y) (my-function a y x b) list-for-xs list-for-ys)
> 
> I am new to lisp so I would appreciate any advice.
> 
> Thanks,
> Andrew

MAPCAR allows you to use multiple lists:

? (mapcar (lambda (x y) (+ x y 1)) '(1 2 3) '(11 12 13))
(13 15 17)

Best to use MAP and MAPCAR like they are, i.e. with LAMBDA
for anonymous functions. This is common practice and
allows other people to understand your code more
easily.

If you want other forms of iteration use LOOP:

(LOOP FOR x IN list-for-xs AND y IN list-for-ys
      COLLECT (my-function a y x b))

-- 
http://lispm.dyndns.org/
From: Maciej Katafiasz
Subject: Re: mapcar using a function with one argument fixed
Date: 
Message-ID: <fj4e9d$qkv$2@news.net.uni-c.dk>
Den Tue, 04 Dec 2007 08:00:09 -0800 skrev andrew.polonsky:

> What is the most _elegant_ way to mapcar a list with a function that
> takes multiple values, setting some constant.  Is there no neater
> alternative to
> 
> (mapcar (lambda (x) (my-function x a b c)) my-list)

There are some libraries that provide you with CURRY, for example arnesi. 
You could also use #L() reader macro, from the same library:

(mapcar #L(my-function !1 a b c) my-list)

http://common-lisp.net/project/bese/docs/arnesi/html/api/function_005FIT.BESE.ARNESI_003A_003ASHARPL-READER.html

Cheers,
Maciej
From: Rob Warnock
Subject: Re: mapcar using a function with one argument fixed
Date: 
Message-ID: <vMqdnQHag-TGsMvanZ2dnUVZ_ternZ2d@speakeasy.net>
Maciej Katafiasz  <········@gmail.com> wrote:
+---------------
| skrev andrew.polonsky:
| > What is the most _elegant_ way to mapcar a list with a function that
| > takes multiple values, setting some constant.  Is there no neater
| > alternative to
| > (mapcar (lambda (x) (my-function x a b c)) my-list)
| 
| There are some libraries that provide you with CURRY, for example arnesi. 
| You could also use #L() reader macro, from the same library:
| 
| (mapcar #L(my-function !1 a b c) my-list)
| 
| http://common-lisp.net/project/bese/docs/arnesi/html/api/function_005FIT.BESE.ARNESI_003A_003ASHARPL-READER.html
+---------------

How neat hacks *do* get re-invented... and re-invented...  ;-}  ;-}

I call my equivalent of that #$, and use $1, $2, ... $9 as the names
of the args, as in the shell:

    > (mapcar #$(+ (* 100 $2) $1) '(1 2 3 4) '(5 6 7 8) '(9 10 11 12))

    (501 602 703 804)
    > 

I also provide a $* which gets stuck after &REST, but that doesn't
work very well, since unlike Arenesi's #L I don't count to see what
the highest ${n} was, so $* only starts with the 10th arg. (Oops!)

I should re-do my version to count the ${n} args [and/or use #{n}$
like Arenesi does] so as to place the $* properly...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: ···············@gmail.com
Subject: Re: mapcar using a function with one argument fixed
Date: 
Message-ID: <05fa2066-634e-418e-9dcf-3f7bfe9069ff@o42g2000hsc.googlegroups.com>
Thanks guys, that is neat!

On Dec 5, 5:47 am, ····@rpw3.org (Rob Warnock) wrote:
> Maciej Katafiasz  <········@gmail.com> wrote:
> +---------------
> | skrev andrew.polonsky:
> | > What is the most _elegant_ way to mapcar a list with a function that
> | > takes multiple values, setting some constant.  Is there no neater
> | > alternative to
> | > (mapcar (lambda (x) (my-function x a b c)) my-list)
> |
> | There are some libraries that provide you with CURRY, for example arnesi.
> | You could also use #L() reader macro, from the same library:
> |
> | (mapcar #L(my-function !1 a b c) my-list)
> |
> |http://common-lisp.net/project/bese/docs/arnesi/html/api/function_005...
> +---------------
>
> How neat hacks *do* get re-invented... and re-invented...  ;-}  ;-}
>
> I call my equivalent of that #$, and use $1, $2, ... $9 as the names
> of the args, as in the shell:
>
>     > (mapcar #$(+ (* 100 $2) $1) '(1 2 3 4) '(5 6 7 8) '(9 10 11 12))
>
>     (501 602 703 804)
>     >
>
> I also provide a $* which gets stuck after &REST, but that doesn't
> work very well, since unlike Arenesi's #L I don't count to see what
> the highest ${n} was, so $* only starts with the 10th arg. (Oops!)
>
> I should re-do my version to count the ${n} args [and/or use #{n}$
> like Arenesi does] so as to place the $* properly...
>
> -Rob
>
> -----
> Rob Warnock                     <····@rpw3.org>
> 627 26th Avenue                 <URL:http://rpw3.org/>
> San Mateo, CA 94403             (650)572-2607