Hi,
I have two function one calling another.
Both function take almost same keyword argument.
As a matter of fact, caller function make the call to the callee to
extends some functionality.
The question is how can I forward the keyword paramter the caller of
function 1 passed directly to function 2?
For example, let's say I have to function
(defun make-modified-car (car-type &key (color :red) (tire-size 23)
(speed 200))
(let ((acar (make-normal-car car-type)))
(modify-car acar :color color :tire-size tire-size :speed
speed)))
(defun modify-car (acar &key (color :red) (tire-size 23) (speed 200)
(....))
Now the problem is that if I don't think that's the correct way.
I am force to duplicate the default value of modify-car to two places,
which is bad for maintenance.
I also can't tell, from modify-car, if the original caller actually
provide the :color, or is it just the default value.
I want to be able to do.
(defun make-modified-car (car-type &key color tire-size speed)
(let ((acar (make-normal-car car-type)))
(modify-car acar (passed-keyword)))) ;; only passed-in keyword
are passed through
(defun modify-car (acar &key (color :red) (tire-size 23) (speed 200)
(....))
Is there anyway to do that?
joesb wrote:
> Hi,
>
> I have two function one calling another.
> Both function take almost same keyword argument.
> As a matter of fact, caller function make the call to the callee to
> extends some functionality.
>
> The question is how can I forward the keyword paramter the caller of
> function 1 passed directly to function 2?
>
> For example, let's say I have to function
>
> (defun make-modified-car (car-type &key (color :red) (tire-size 23)
> (speed 200))
> (let ((acar (make-normal-car car-type)))
> (modify-car acar :color color :tire-size tire-size :speed
> speed)))
>
> (defun modify-car (acar &key (color :red) (tire-size 23) (speed 200)
> (....))
>
> Now the problem is that if I don't think that's the correct way.
> I am force to duplicate the default value of modify-car to two places,
> which is bad for maintenance.
> I also can't tell, from modify-car, if the original caller actually
> provide the :color, or is it just the default value.
>
> I want to be able to do.
>
> (defun make-modified-car (car-type &key color tire-size speed)
> (let ((acar (make-normal-car car-type)))
> (modify-car acar (passed-keyword)))) ;; only passed-in keyword
> are passed through
>
> (defun modify-car (acar &key (color :red) (tire-size 23) (speed 200)
> (....))
>
> Is there anyway to do that?
Pascal already mentioned CLOS, which looks like it would have the best
solution to this. If you don't like that solution, you can use &rest
and :allow-other-keys as well:
> (defun make-modified-car (car-type &key used keyword parameters &rest rest)
> (let ((acar (make-normal-car car-type)))
> (apply #'modify-car :allow-other-keys t rest)))
>
> (defun modify-car (acar &key (color :red) (tire-size 23) (speed 200))
> (....))
If you don't use any keyword parameters in make-modified-car, then you
don't need the keywords or the allow-other-keys.
-- MJF
Hi,
Tried this in CLISP, doesn't work.
(defun foo (a &key used &rest non-used)
(format t "~A ~A~%" used non-used))
It seems I can't use &rest after &key.
but
(defun foo (a &rest non-used &key used)
(format t "~A ~A~%" used non-used))
Works fine.
I will probably have to massage the non-used list a little bit.
I'll try and see if apply #foo trick work with call-next-method though.
"joesb" <··········@gmail.com> writes:
> Tried this in CLISP, doesn't work.
>
> (defun foo (a &key used &rest non-used)
> (format t "~A ~A~%" used non-used))
>
> It seems I can't use &rest after &key.
Yes. CLISP is Common Lisp compliant.
> but
>
> (defun foo (a &rest non-used &key used)
> (format t "~A ~A~%" used non-used))
>
> Works fine.
>
> I will probably have to massage the non-used list a little bit.
> I'll try and see if apply #foo trick work with call-next-method though.
You should forget about # for a while.
Always use: (function foo) to get the function named foo
and: (quote foo) to get the symbol foo.
But you don't need to use: (value foo) to get the value of foo ;-)
--
__Pascal Bourguignon__ http://www.informatimago.com/
The world will now reboot. don't bother saving your artefacts.
From: Stefan Nobis
Subject: Re: Forward keyword parameter to another function
Date:
Message-ID: <877jeuyn41.fsf@snobis.de>
Pascal Bourguignon <····@mouse-potato.com> writes:
> You should forget about # for a while.
> Always use: (function foo) to get the function named foo
> and: (quote foo) to get the symbol foo.
Hmmm... why not always use #' and '?
--
Stefan.
Stefan Nobis <······@gmx.de> writes:
> Pascal Bourguignon <····@mouse-potato.com> writes:
>
>> You should forget about # for a while.
>
>> Always use: (function foo) to get the function named foo
>> and: (quote foo) to get the symbol foo.
>
> Hmmm... why not always use #' and '?
You cut too much to understand:
"joesb" <··········@gmail.com> writes:
> I will probably have to massage the non-used list a little bit.
> I'll try and see if apply #foo trick work with call-next-method though.
Because often newbies dismiss the '.
--
__Pascal Bourguignon__ http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.
On Wed, 10 Aug 2005 03:52:55 -0700, joesb wrote:
> Tried this in CLISP, doesn't work.
>
> (defun foo (a &key used &rest non-used)
> (format t "~A ~A~%" used non-used))
>
> It seems I can't use &rest after &key.
>
> but
>
> (defun foo (a &rest non-used &key used)
> (format t "~A ~A~%" used non-used))
>
> Works fine.
(defun foo (&key (key1 :key1-default key1-used?)
(key2 :key2-default key2-used?))
(format t "~S ~S ~S ~S~%" key1 key1-used? key2 key2-used?))
[9]> (foo)
:KEY1-DEFAULT NIL :KEY2-DEFAULT NIL
NIL
[10]> (foo :key2 123)
:KEY1-DEFAULT NIL 123 T
NIL
You can portably check whether a key has been supplied in ANSI Common
Lisp:
3.4 Lambda Lists
<http://www.lispworks.com/documentation/HyperSpec/Body/03_d.htm>
3.4.1 Ordinary Lambda Lists
<http://www.lispworks.com/documentation/HyperSpec/Body/03_da.htm>
({var | (keyword-name var)} [init-form [supplied-p-parameter]])
i.e.
( key1 :key1-default key1-used? )
Regards,
Adam
From: Peder O. Klingenberg
Subject: Re: Forward keyword parameter to another function
Date:
Message-ID: <ks7jevo1r0.fsf@beto.netfonds.no>
"joesb" <··········@gmail.com> writes:
> (defun make-modified-car (car-type &key color tire-size speed)
> (let ((acar (make-normal-car car-type)))
> (modify-car acar (passed-keyword)))) ;; only passed-in keyword
> are passed through
>
> (defun modify-car (acar &key (color :red) (tire-size 23) (speed 200)
> (....))
>
> Is there anyway to do that?
Perhaps you can combine &rest and &key in make-modified-car?
(defun make-modified-car (car-type &rest keywords &key color tire-size speed)
(let* ((acar (make-normal-car car-type)))
(apply modify-car acar keywords))
;;presumably use color tire-size and speed here as well.
acar)
...Peder...
--
I wish a new life awaited _me_ in some off-world colony.
From: Pascal Costanza
Subject: Re: Forward keyword parameter to another function
Date:
Message-ID: <3lrep6F142p5mU1@individual.net>
joesb wrote:
> Hi,
>
> I have two function one calling another.
> Both function take almost same keyword argument.
> As a matter of fact, caller function make the call to the callee to
> extends some functionality.
>
> The question is how can I forward the keyword paramter the caller of
> function 1 passed directly to function 2?
>
> For example, let's say I have to function
>
> (defun make-modified-car (car-type &key (color :red) (tire-size 23)
> (speed 200))
> (let ((acar (make-normal-car car-type)))
> (modify-car acar :color color :tire-size tire-size :speed
> speed)))
>
> (defun modify-car (acar &key (color :red) (tire-size 23) (speed 200)
> (....))
Can you reformulate the solution like this?
(defun make-modified-car (car-type &key (color :red) (tire-size 23)
(speed 200))
(make-normal-car car-type :color color :tire-size tire-size :speed
speed))
Or even use inheritance?
(defclass modified-car (normal-car)
()
(:default-initargs :color :red :tire-size 23 :speed 200))
Pascal
--
In computer science, we stand on each other's feet. - Brian K. Reid