Is there any way to write a function so that it can be called either as:
(foo 1 2 3)
or
(foo '(1 2 3))
such that 1 is bound, say, to x, 2 to y, and 3 to z?
--
NewsGuy.Com 30Gb $9.95 Carry Forward and On Demand Bandwidth
····@stablecross.com (Bob Felts) writes:
> Is there any way to write a function so that it can be called either as:
>
> (foo 1 2 3)
>
> or
> (foo '(1 2 3))
It's seems unlikely to me that this is a good idea, but if you really
want to:
(defun foo (a &optional b c)
(flet ((work (a b c) ...))
(if (consp a) (apply #'work a) (work a b c))))
-Peter
--
Peter Seibel * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
Peter Seibel <·····@gigamonkeys.com> wrote:
> ····@stablecross.com (Bob Felts) writes:
>
> > Is there any way to write a function so that it can be called either as:
> >
> > (foo 1 2 3)
> >
> > or
> > (foo '(1 2 3))
>
> It's seems unlikely to me that this is a good idea, but if you really
> want to:
>
> (defun foo (a &optional b c)
> (flet ((work (a b c) ...))
> (if (consp a) (apply #'work a) (work a b c))))
>
There's a method to my madness. Suppose I have two functions, RGB->YIQ
and YIQ->RGB. Then (RGB r g b) will return a list of three values (y i
q). I can then pass in this list to YIQ->RGB to get back the original
values. Or a use can enter (YIQ y i q) to test a conversion. It's just
something that makes it easier on the user. If this were C++, for
example, it would be easy to do with overloading. But I haven't gotten
through enough of your book, yet, to have figured it out on my own.
Thanks, Peter. Danke, Ranier.
--
NewsGuy.Com 30Gb $9.95 Carry Forward and On Demand Bandwidth
····@stablecross.com (Bob Felts) writes:
> There's a method to my madness. Suppose I have two functions, RGB->YIQ
> and YIQ->RGB. Then (RGB r g b) will return a list of three values (y i
> q). I can then pass in this list to YIQ->RGB to get back the original
> values. Or a use can enter (YIQ y i q) to test a conversion. It's just
> something that makes it easier on the user. If this were C++, for
> example, it would be easy to do with overloading.
I would be inclined to use the multiple values mechanism instead.
(multiple-value-call #'yiq->rgb (rgb->yiq r g b)) => (values r g b)
Zach
Bob Felts wrote:
> There's a method to my madness. Suppose I have two functions, RGB->YIQ
> and YIQ->RGB. Then (RGB r g b) will return a list of three values (y i
> q). I can then pass in this list to YIQ->RGB to get back the original
> values. Or a use can enter (YIQ y i q) to test a conversion. It's just
> something that makes it easier on the user. If this were C++, for
> example, it would be easy to do with overloading. But I haven't gotten
> through enough of your book, yet, to have figured it out on my own.
>
> Thanks, Peter. Danke, Ranier.
You want apply. Apply applies a function to a list of arguments
http://www.lisp.org/HyperSpec/Body/fun_apply.html
-- MJF
Bob Felts wrote:
> There's a method to my madness. Suppose I have two functions, RGB->YIQ
> and YIQ->RGB. Then (RGB r g b) will return a list of three values (y i
> q). I can then pass in this list to YIQ->RGB to get back the original
> values. Or a use can enter (YIQ y i q) to test a conversion. It's just
> something that makes it easier on the user. If this were C++, for
> example, it would be easy to do with overloading. But I haven't gotten
> through enough of your book, yet, to have figured it out on my own.
> Thanks, Peter. Danke, Ranier.
Well, setting aside all the APPLY-based solutions, I would ask why you
don't just make the argument always be a list? Unlike in C++, where
it's a real pain to produce new structure, with lists and the LIST
function it isn't hard.
For example, instead of
(RGB r g b)
you could either use
(RGB '(r g b)) ; if r,g,b are numeric literals
(RGB (list r g b)) ; ... otherwise
Adding the call to LIST is hardly a big problem. Then you could treat
all of the structures as lists. That would be pretty simple and it
would also serve to keep the values together in a single albeit simple
and generic data structure.
--
Thomas A. Russ, USC/Information Sciences Institute
Thomas A. Russ <···@sevak.isi.edu> wrote:
> Bob Felts wrote:
>
> > There's a method to my madness. Suppose I have two functions, RGB->YIQ
> > and YIQ->RGB. Then (RGB r g b) will return a list of three values (y i
> > q). I can then pass in this list to YIQ->RGB to get back the original
> > values. Or a use can enter (YIQ y i q) to test a conversion. It's just
> > something that makes it easier on the user. If this were C++, for
> > example, it would be easy to do with overloading. But I haven't gotten
> > through enough of your book, yet, to have figured it out on my own.
> > Thanks, Peter. Danke, Ranier.
>
> Well, setting aside all the APPLY-based solutions, I would ask why you
> don't just make the argument always be a list? Unlike in C++, where
> it's a real pain to produce new structure, with lists and the LIST
> function it isn't hard.
I agree it isn't hard, but there is the possibility of a bit of data
entry; it's easier to type (rgb 1 2 3) than it is to type (rgb '(1 2 3))
I've gone ahead an kept the interface to the user as (f x y z) and use
APPLY internally.
--
NewsGuy.Com 30Gb $9.95 Carry Forward and On Demand Bandwidth
Bob Felts wrote:
> Peter Seibel <·····@gigamonkeys.com> wrote:
>
>
>>····@stablecross.com (Bob Felts) writes:
>>
>>
>>>Is there any way to write a function so that it can be called either as:
>>>
>>> (foo 1 2 3)
>>>
>>>or
>>> (foo '(1 2 3))
>>
>>It's seems unlikely to me that this is a good idea, but if you really
>>want to:
>>
>> (defun foo (a &optional b c)
>> (flet ((work (a b c) ...))
>> (if (consp a) (apply #'work a) (work a b c))))
>>
>
>
> There's a method to my madness. Suppose I have two functions, RGB->YIQ
> and YIQ->RGB. Then (RGB r g b) will return a list of three values (y i
> q). I can then pass in this list to YIQ->RGB to get back the original
> values.
You are looking for APPLY.
ken
--
Cells: http://common-lisp.net/project/cells/
"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
Am 18.04.2006 23:14 Uhr schrieb "Bob Felts" unter <····@stablecross.com> in
··························@stablecross.com:
> Is there any way to write a function so that it can be called either as:
>
> (foo 1 2 3)
>
> or
> (foo '(1 2 3))
>
> such that 1 is bound, say, to x, 2 to y, and 3 to z?
For example like this:
(defun foo (&optional x y z)
(if (listp x)
(apply #'foo x)
(+ x y z)))
CL-USER 11 > (foo 1 2 3)
6
CL-USER 12 > (foo '(1 2 3))
6
Rainer Joswig <······@lisp.de> writes:
> Am 18.04.2006 23:14 Uhr schrieb "Bob Felts" unter <····@stablecross.com> in
> ··························@stablecross.com:
>
>> Is there any way to write a function so that it can be called either as:
>>
>> (foo 1 2 3)
>>
>> or
>> (foo '(1 2 3))
>>
>> such that 1 is bound, say, to x, 2 to y, and 3 to z?
>
> For example like this:
>
> (defun foo (&optional x y z)
> (if (listp x)
> (apply #'foo x)
> (+ x y z)))
Just nit picking, but wouldn't it be better as
(defun foo (x &optional y z)
It just strikes me that
(ddfun foo (&optional x y z)
could also be called with no arguments as in
(foo)
Tim
--
tcross (at) rapttech dot com dot au
Tim X <····@nospam.dev.null> writes:
> Rainer Joswig <······@lisp.de> writes:
>> (defun foo (&optional x y z)
>> (if (listp x)
>> (apply #'foo x)
>> (+ x y z)))
>
> Just nit picking, but wouldn't it be better as
>
> (defun foo (x &optional y z)
>
> It just strikes me that
>
> (ddfun foo (&optional x y z)
>
> could also be called with no arguments as in
>
> (foo)
Not only that, but ...
(foo)
==> (listp nil) ==> (apply #'foo nil)
Right?
In article <··············@tiger.rapttech.com.au>,
Tim X <····@nospam.dev.null> wrote:
> Rainer Joswig <······@lisp.de> writes:
>
> > Am 18.04.2006 23:14 Uhr schrieb "Bob Felts" unter <····@stablecross.com> in
> > ··························@stablecross.com:
> >
> >> Is there any way to write a function so that it can be called either as:
> >>
> >> (foo 1 2 3)
> >>
> >> or
> >> (foo '(1 2 3))
> >>
> >> such that 1 is bound, say, to x, 2 to y, and 3 to z?
> >
> > For example like this:
> >
> > (defun foo (&optional x y z)
> > (if (listp x)
> > (apply #'foo x)
> > (+ x y z)))
>
> Just nit picking, but wouldn't it be better as
>
> (defun foo (x &optional y z)
>
> It just strikes me that
>
> (ddfun foo (&optional x y z)
>
> could also be called with no arguments as in
>
> (foo)
>
> Tim
You also can check whether the parameters are supplied:
(defun foo (x &optional (y nil y-p) (z nil z-p))
(cond ((and y-p z-p)
(+ x y z))
...
--
http://lispm.dyndns.org/
On 9449 day of my life Bob Felts wrote:
> Is there any way to write a function so that it can be called either as:
>
> (foo 1 2 3)
>
> or
> (foo '(1 2 3))
>
> such that 1 is bound, say, to x, 2 to y, and 3 to z?
If you need some speed:
(defun %foo (x y z)
;; Just an example
(sqrt (abs (* x y z))))
(defun foo (x &optional (y nil y-p) (z nil z-p))
(if (and y-p z-p)
(%foo x y z)
(apply #'%foo x)))
(define-compiler-macro foo (x &optional (y nil y-p) (z nil z-p))
(if (and y-p z-p)
`(%foo ,x ,y ,z)
`(apply #'%foo ,x)))
--
Ivan Boldyrev
Is 'morning' a gerund?