From: Bob Felts
Subject: Function arguments
Date: 
Message-ID: <1he02hi.teqmou8dwdq8N%wrf3@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?

-- 
NewsGuy.Com 30Gb $9.95 Carry Forward and On Demand Bandwidth

From: Peter Seibel
Subject: Re: Function arguments
Date: 
Message-ID: <m2sloaftmj.fsf@gigamonkeys.com>
····@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/
From: Bob Felts
Subject: Re: Function arguments
Date: 
Message-ID: <1he09dm.ypsu8w1kmmuv8N%wrf3@stablecross.com>
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
From: Zach Beane
Subject: Re: Function arguments
Date: 
Message-ID: <m3mzeiie66.fsf@unnamed.xach.com>
····@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
From: M Jared Finder
Subject: Re: Function arguments
Date: 
Message-ID: <trmdnaMHi8iyJdjZRVn-tg@speakeasy.net>
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
From: Thomas A. Russ
Subject: Re: Function arguments
Date: 
Message-ID: <ymislo9wgtg.fsf@sevak.isi.edu>
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
From: Bob Felts
Subject: Re: Function arguments
Date: 
Message-ID: <1he1wmq.18m87mgrdcqdwN%wrf3@stablecross.com>
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
From: Ken Tilton
Subject: Re: Function arguments
Date: 
Message-ID: <hMi1g.526$F42.439@fe09.lga>
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.
From: Rainer Joswig
Subject: Re: Function arguments
Date: 
Message-ID: <C06B299A.37D52%joswig@lisp.de>
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
From: Tim X
Subject: Re: Function arguments
Date: 
Message-ID: <87zmibx1qb.fsf@tiger.rapttech.com.au>
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
From: Ari Johnson
Subject: Re: Function arguments
Date: 
Message-ID: <m2k69fvmxo.fsf@hermes.theari.com>
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?
From: Rainer Joswig
Subject: Re: Function arguments
Date: 
Message-ID: <joswig-F39F09.02415024042006@news-europe.giganews.com>
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/
From: Ivan Boldyrev
Subject: Re: Function arguments
Date: 
Message-ID: <h8gjh3-set.ln1@ibhome.cgitftp.uiggm.nsc.ru>
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?