From: vippstar
Subject: Trouble naming macro
Date: 
Message-ID: <3ebafbc1-93b2-4de3-b4fe-07bd7d6f15a3@a5g2000pre.googlegroups.com>
I have trouble naming this macro which I wrote:
(defmacro foo (func &rest args)
  `(lambda (&rest rest)
    (apply ,g ,@args rest)))

Here is a possible use of this:
(find-if (foo #'somefunc (someval)) list)

instead of:
(let ((val (someval)))
  (find-if (lambda (x) (somefunc val x)) list))

The let form can be get ridden of with the macro, unless SOMEVAL is
functional, in which case it can be called inside the lambda function
to avoid using LET,  but this can introduce a performance impact. This
performance is there in the macro version of FOO as well. It can be
written as a function though and all arguments will be evaluated
before they are put in the lambda form that is returned. Also, there's
no reason to write the same lambda form every time its functionality
is desired. That is the main purpose of the macro, but it also has the
benefits mentioned firstly. My question is, is there something
stardard or de facto way to do this? Most likely there is, but in case
it is not, which name would you suggest for this macro? Would you
implement it as a macro or a function for the performance benefit I
described?

From: gugamilare
Subject: Re: Trouble naming macro
Date: 
Message-ID: <dfecb4b1-4379-41fb-9c35-8e111cb4a49f@x1g2000prh.googlegroups.com>
On 12 jun, 09:35, vippstar <········@gmail.com> wrote:
> I have trouble naming this macro which I wrote:
> (defmacro foo (func &rest args)
>   `(lambda (&rest rest)
>     (apply ,g ,@args rest)))
>
> Here is a possible use of this:
> (find-if (foo #'somefunc (someval)) list)
>
> instead of:
> (let ((val (someval)))
>   (find-if (lambda (x) (somefunc val x)) list))
>
> The let form can be get ridden of with the macro, unless SOMEVAL is
> functional, in which case it can be called inside the lambda function
> to avoid using LET,  but this can introduce a performance impact. This
> performance is there in the macro version of FOO as well. It can be
> written as a function though and all arguments will be evaluated
> before they are put in the lambda form that is returned. Also, there's
> no reason to write the same lambda form every time its functionality
> is desired. That is the main purpose of the macro, but it also has the
> benefits mentioned firstly. My question is, is there something
> stardard or de facto way to do this? Most likely there is, but in case
> it is not, which name would you suggest for this macro? Would you
> implement it as a macro or a function for the performance benefit I
> described?

Actually, this macro is the almost standard function curry. It is
already present in alexandria, metatilities and most utils libraries.
From: Pascal J. Bourguignon
Subject: Re: Trouble naming macro
Date: 
Message-ID: <7chbylzjs3.fsf@pbourguignon.anevia.com>
vippstar <········@gmail.com> writes:

> I have trouble naming this macro which I wrote:
> (defmacro foo (func &rest args)
>   `(lambda (&rest rest)
>     (apply ,g ,@args rest)))
>
> Here is a possible use of this:
> (find-if (foo #'somefunc (someval)) list)
>
> instead of:
> (let ((val (someval)))
>   (find-if (lambda (x) (somefunc val x)) list))
>
> The let form can be get ridden of with the macro, unless SOMEVAL is
> functional, in which case it can be called inside the lambda function
> to avoid using LET,  but this can introduce a performance impact. This
> performance is there in the macro version of FOO as well. It can be
> written as a function though and all arguments will be evaluated
> before they are put in the lambda form that is returned. Also, there's
> no reason to write the same lambda form every time its functionality
> is desired. That is the main purpose of the macro, but it also has the
> benefits mentioned firstly. My question is, is there something
> stardard or de facto way to do this? Most likely there is, but in case
> it is not, which name would you suggest for this macro? Would you
> implement it as a macro or a function for the performance benefit I
> described?

partial-apply

It doesn't need to be a macro, since you set it to evaluate all the
arguments.

(defun partial-apply (fun &rest args)
   (lambda (&rest rest)
      (apply fun (append args rest))))

(find-if (partial-apply (function <) 1) '(0 1 2 3 4))
--> 2

(mapcar (partial-apply (function list) 1 2) '(0 1 2 3))
--> ((1 2 0) (1 2 1) (1 2 2) (1 2 3))


-- 
__Pascal Bourguignon__
From: vippstar
Subject: Re: Trouble naming macro
Date: 
Message-ID: <9e1dc4f5-4f87-4c67-818c-b4b05f36e58f@f38g2000pra.googlegroups.com>
On Jun 12, 4:03 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> vippstar <········@gmail.com> writes:
> > I have trouble naming this macro which I wrote:
<snip>
>
> partial-apply
>
> It doesn't need to be a macro, since you set it to evaluate all the
> arguments.
>
> (defun partial-apply (fun &rest args)
>    (lambda (&rest rest)
>       (apply fun (append args rest))))
>
<snip examples>

Thanks, that is the name and I will use it.

WARNING: Below is just thoughts; and they possibly address the reason
PARTIAL-APPLY is not part of the standard. (it's not general enough,
and when abstracted, it becomes too complicated for something that can
be done by hand and a simple lambda form in most cases). Partial-apply
can only be useful with a number of functions in a number of
situations. In particular, where the leftmost arguments are constants
and rightmost are variables. I realized this after looking at the
awkward implementation of 1- with PARTIAL-APPLY:
(defun my-1- (partial-apply #'+ -1))

(it wouldn't beheve exactly like 1-, another peculiarity of PARTIAL-
APPLY, because (my-1- 1 2) would be correct, whereas (1- 1 2) is not,
but that is not an issue if we "lie" in the documentation about
my-1-'s argument list, or explain this.) Because of mathematics this
is possible, but cases can arise where this is not possible, and thus
PARTIAL-APPLY can't be used. Another version of it, which gives APPLY
this list, (append rest args), instead of (append args rest), could be
used as such:
(defun my-1- (different-partial-apply #'- 1)) ; (apply - x 1)

The general case is:
(defun general-partial-apply (fun combine &rest args)
  (lambda (&rest rest)
    (apply fun (combine args rest))))

and partial-apply would be defined in terms of this function as
(general-partial-apply #'fun #'append arg1 arg2 arg3...)

and different-partial-apply would be:
(g-p-a #'fun (lambda (x y) (append y x)) arg1 arg2 arg3...)

But this lambda is another form which asks for abstraction. It
reorders the arguments in reverse with which a function is called:
(defun reorder-reverse (fun &rest args)
  (apply fun (reverse args))

Which itself has a general case:
(defun reorder (fun how &rest)
  (apply fun (funcall how rest)))

Now REORDER-REVERSE is only (reorder #'func #'reverse arg1 arg2 arg3)

D-P-A implemented again in terms of G-P-A:
(g-p-a #'fun (reorder-reverse #'append) arg1 arg2 arg3...)
From: Pascal J. Bourguignon
Subject: Re: Trouble naming macro
Date: 
Message-ID: <7cd499zhkk.fsf@pbourguignon.anevia.com>
vippstar <········@gmail.com> writes:

> On Jun 12, 4:03�pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> vippstar <········@gmail.com> writes:
>> > I have trouble naming this macro which I wrote:
> <snip>
>>
>> partial-apply
>>
>> It doesn't need to be a macro, since you set it to evaluate all the
>> arguments.
>>
>> (defun partial-apply (fun &rest args)
>> � �(lambda (&rest rest)
>> � � � (apply fun (append args rest))))
>>
> <snip examples>
>
> Thanks, that is the name and I will use it.
>
> WARNING: Below is just thoughts; and they possibly address the reason
> PARTIAL-APPLY is not part of the standard. (it's not general enough,
> and when abstracted, it becomes too complicated for something that can
> be done by hand and a simple lambda form in most cases). Partial-apply
> can only be useful with a number of functions in a number of
> situations. In particular, where the leftmost arguments are constants
> and rightmost are variables. I realized this after looking at the
> awkward implementation of 1- with PARTIAL-APPLY:
> (defun my-1- (partial-apply #'+ -1))

Actually, it is closed related to currying and the curry function.
But the problem is that curry works well when you consider that
functions only takes ONE  parameter (and return ONE value), which is
not the case in Common Lisp (or in most programming languages).

Otherwise, you might invent a complex syntax to show where to insert
additionnal parameters in a parameter list template, but soon it
becomes easier to write a lambda.

(mapcar (partial (- $1 1)) '(1 2 3)) --> (0 1 2)
(mapcar (partial (subseq "ab123cdef" $2 $1)) (cdr #1='(0 2 5 9)) #1#)  --> ("ab" "123" "cdef")

vs.

(mapcar (lambda (x) (- x 1)) '(1 2 3))
(mapcar (lambda (end start) (subseq  "ab123cdef" start end)) (cdr #1='(0 2 5 9)) #1#)

-- 
__Pascal Bourguignon__
From: Mirko Vukovic
Subject: Re: Trouble naming macro
Date: 
Message-ID: <ff4eb51d-1fb3-44fb-af48-bafff54b3e29@y6g2000prf.googlegroups.com>
On Jun 12, 9:03 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> vippstar <········@gmail.com> writes:
> > I have trouble naming this macro which I wrote:
> > (defmacro foo (func &rest args)
> >   `(lambda (&rest rest)
> >     (apply ,g ,@args rest)))
>
> > Here is a possible use of this:
> > (find-if (foo #'somefunc (someval)) list)
>
> > instead of:
> > (let ((val (someval)))
> >   (find-if (lambda (x) (somefunc val x)) list))
>
> > The let form can be get ridden of with the macro, unless SOMEVAL is
> > functional, in which case it can be called inside the lambda function
> > to avoid using LET,  but this can introduce a performance impact. This
> > performance is there in the macro version of FOO as well. It can be
> > written as a function though and all arguments will be evaluated
> > before they are put in the lambda form that is returned. Also, there's
> > no reason to write the same lambda form every time its functionality
> > is desired. That is the main purpose of the macro, but it also has the
> > benefits mentioned firstly. My question is, is there something
> > stardard or de facto way to do this? Most likely there is, but in case
> > it is not, which name would you suggest for this macro? Would you
> > implement it as a macro or a function for the performance benefit I
> > described?
>
> partial-apply
>
> It doesn't need to be a macro, since you set it to evaluate all the
> arguments.
>
> (defun partial-apply (fun &rest args)
>    (lambda (&rest rest)
>       (apply fun (append args rest))))
>
> (find-if (partial-apply (function <) 1) '(0 1 2 3 4))
> --> 2
>
> (mapcar (partial-apply (function list) 1 2) '(0 1 2 3))
> --> ((1 2 0) (1 2 1) (1 2 2) (1 2 3))
>
> --
> __Pascal Bourguignon__

Any reason why you use (function <) instead of #'< ?

Thanks,

Mirko
From: Pascal J. Bourguignon
Subject: Re: Trouble naming macro
Date: 
Message-ID: <873aa54ak3.fsf@galatea.local>
Mirko Vukovic <······················@gmail.com> writes:
> Any reason why you use (function <) instead of #'< ?

I love my reader, so I spare it some work, so we can go to the beach together.


-- 
__Pascal Bourguignon__
From: Kaz Kylheku
Subject: Re: Trouble naming macro
Date: 
Message-ID: <20090624134157.100@gmail.com>
On 2009-06-12, Pascal J. Bourguignon <···@informatimago.com> wrote:
> Mirko Vukovic <······················@gmail.com> writes:
>> Any reason why you use (function <) instead of #'< ?
>
> I love my reader, so I spare it some work, so we can go to the beach together.

It quite probably takes more work to tokenize (FUNCTION X) than #'X.

Consider:

Dispatch the function associated with #', which reads the object X the
object, then returns (cons 'function (cons object nil)),

Versus: 

Dispatch the ( reader, which has to collect the token constituent characters
#\F #\U and so on, then recognize that #\Space is a token terminator, recognize
that the token which has been has the lexical form of a symbol, and thus intern
the symbol in the current package. Then read the object, while all the time
keeping on the lookout for the list-terminating #\) character, finally
returning (cons symbol (cons object nil)).

:)