Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is it possible to see how many arguments a function take?

1 view
Skip to first unread message

Slobodan Blazeski

unread,
Mar 22, 2008, 10:52:27 AM3/22/08
to
I know that I'm looking too much from reflection but is there a way
to *see* at runtime how many argument a function takes? How about
number of values returned ?
Or some good tips about lisp reflections.

thanks
Slobodan
http://tourdelisp.blogspot.com/

philip....@gmail.com

unread,
Mar 22, 2008, 11:32:29 AM3/22/08
to
On Mar 22, 2:52 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:

There may be better ways but I use:

#+:clisp (sys::arglist fn)
#+:sbcl (sb-introspect:function-arglist fn)

But you'll need to normalise across implementations and probably parse
the lambda-list returned for things like &optional, etc.

--
Phil
http://phil.nullable.eu/

Brian

unread,
Mar 22, 2008, 12:33:01 PM3/22/08
to
To get the number of values returned from form you could do (length
(multiple-value-list <form>)), but I don't know how without evaluating
the form.

Marco Antoniotti

unread,
Mar 22, 2008, 1:04:06 PM3/22/08
to
On Mar 22, 4:52 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>
wrote:

There is no portable way to do the first (although most CLs have an
"arglist" vel similia); you may hope that FUNCTION-LAMBDA-EXPRESSION
worked in your CL, but it is no given. There is no portable way to do
the second one , although TYPE-OF *may* help in this case (and in the
first one as well); your CL may have something under the hood.

Cheers
--
Marco

D Herring

unread,
Mar 22, 2008, 1:09:40 PM3/22/08
to

Nor does Lisp itself; people are free to redefine functions, and
functions can return different lists depending on the arguments, time
of day, or anything else...

AFAIK, there isn't a standard way of declaring that "FOO always
returns 3 arguments, of the form '(string fixnum function)".

- Daniel

Steven M. Haflich

unread,
Mar 22, 2008, 8:57:16 PM3/22/08
to
Marco Antoniotti wrote:

> There is no portable way to do the first (although most CLs have an
> "arglist" vel similia)

It is, of course, portably possible to examine the argument list of a
generic function and its component methods.

But strictly speaking, the original question does not have definite
semantics. Precisely what does it mean that a function "takes" some
number of arguments. How many arguments does this function accept?

(defun foo (x y)
;;This example assumes program-error is a simple-error, which
;;is not a portable assumption.
(error 'program-error
:format-control "foo doesn't like these arguments: ~s ~s"
:format-arguments (list x y)))

What about this function?

(defun foo (x y)
(when (oddp (get-universal-time))
(error 'program-error
:format-control "foo doesn't like these arguments: ~s ~s"
:format-arguments (list x y))))

Calling this function with the wrong number of arguments is not portably
distinguishable from calling it with the "right" number of arguments.

vsel...@gmail.com

unread,
Mar 23, 2008, 5:26:59 AM3/23/08
to
I think, the most portable way to get function arglist is to use
swank:operator-arglist
-
Vsevolod

Marco Antoniotti

unread,
Mar 23, 2008, 9:12:31 AM3/23/08
to
On Mar 23, 2:57 am, "Steven M. Haflich" <s...@alum.mit.edu> wrote:
> Marco Antoniotti wrote:
> > There is no portable way to do the first (although most CLs have an
> > "arglist" vel similia)
>
> It is, of course, portably possible to examine the argument list of a
> generic function and its component methods.

How? AFAIR, you can if you resort to the MOP, but not if you restrict
yourself to ANSI.


>
> But strictly speaking, the original question does not have definite
> semantics.  Precisely what does it mean that a function "takes" some
> number of arguments.  How many arguments does this function accept?
>
> (defun foo (x y)
>    ;;This example assumes program-error is a simple-error, which
>    ;;is not a portable assumption.
>    (error 'program-error
>          :format-control "foo doesn't like these arguments: ~s ~s"
>          :format-arguments (list x y)))
>
> What about this function?
>
> (defun foo (x y)
>    (when (oddp (get-universal-time))
>      (error 'program-error
>            :format-control "foo doesn't like these arguments: ~s ~s"
>            :format-arguments (list x y))))
>
> Calling this function with the wrong number of arguments is not portably
> distinguishable from calling it with the "right" number of arguments.

Granted. The semantics of the OP should be further specified.

Cheers
--
Marco

Slobodan Blazeski

unread,
Mar 23, 2008, 10:01:20 AM3/23/08
to

Thanks to everybody for their answers. I think this approach got me
into dead end, and I'll have to look elsewhere.
Basically I want a facility (probably it has to be macro though I
would prefer a function) that will inspect a function and behave
according to it. baically I want a function to be some kind of
controller, that will tell the facility how to bind,step, what to
return etc.
(map #'(lambda (x) (+ 4 x)) '( 1 2 3 4)) => (5 6 7 8)
(mapcar #'(lambda (x) (+ 4 x)) '( 1 2 3 4))

(map #'(lambda (x1 x2) (+ x1 x2)) '(1 2 3 4 5)) => (3 7)
(defun foo (list)
(if (endp (cddr list)) nil
(cons (+ (car list) (cadr list)) (foo (cddr list))))

(map #'(*lambda* (x ($result 7)) (incf $result x)) '(1 2 3)) => 13
(+ 7 (reduce #'+ '(1 2 3))

Marco Antoniotti

unread,
Mar 23, 2008, 12:21:43 PM3/23/08
to
On Mar 23, 4:01 pm, Slobodan Blazeski <slobodan.blaze...@gmail.com>

This is called an interpreter. Otherwise the halting problem is
standing in front of you :)


> (map #'(lambda (x) (+ 4 x)) '( 1 2 3 4)) => (5 6 7 8)
> (mapcar #'(lambda (x) (+ 4 x)) '( 1 2 3 4))
>
> (map #'(lambda (x1 x2) (+  x1 x2)) '(1 2 3 4 5)) => (3 7)
> (defun foo (list)
>   (if (endp  (cddr list)) nil
>       (cons (+ (car list) (cadr list)) (foo (cddr list))))
>
> (map #'(*lambda* (x ($result 7)) (incf $result x)) '(1 2 3)) => 13
> (+ 7 (reduce  #'+ '(1 2 3))

This is unclear to me. What exactly do you mean with the expressions
above (especially with the *lambda* thingy?

Cheers
--
Marco

D Herring

unread,
Mar 23, 2008, 12:42:02 PM3/23/08
to
Slobodan Blazeski wrote:
> Thanks to everybody for their answers. I think this approach got me
> into dead end, and I'll have to look elsewhere.
> Basically I want a facility (probably it has to be macro though I
> would prefer a function) that will inspect a function and behave
> according to it. baically I want a function to be some kind of
> controller, that will tell the facility how to bind,step, what to
> return etc.

I'm not sure what you want, but APPLY and MULTIPLE-VALUE-LIST might do
most of what you need. That, or use the slime functions which have
implementation-specific code for such queries.

- Daniel

Slobodan Blazeski

unread,
Mar 24, 2008, 5:23:59 AM3/24/08
to


I want to create a graceful replacement for looping, with syntax like
this:
(map controler &rest generators)
Generators provide elements, they could be containers (list, hash-
tables, arrays, strings ..), atoms 1 'a #\a or even functions.
Controlers , control the initialisation,stepping, results etc. So
basically it'll render outdated control structures like: mapcar,
reduce, dolist, dotimes, do, loop.
Because you could loop through each container and as you wish using
just map and nothing more.

The only thing I have problem to figure out is how to gracefully
collect multiple results. I need an efficient equivalent to below.
(defun separate (lst)
(mapcar #'(lambda (n) (mapcar #'abs (remove-if-not n lst)))
(list #'plusp #'zerop #'minusp)))
Something graceful like it but that will travel the list only once.
Sorry for my confusing explanation but the ideas are still shaping in
my mind and it usually helps when I try to explain this to somebody.
Basically I want to use the ideas of array processing I found in APL
family of languages, j & q and implement them as library in lispified
form.
If you need inspiration to understand look at www.nsl.com especially
the challenge http://www.nsl.com/papers/kisntlisp.htm

This my blog post with even more confusing explanation
http://tourdelisp.blogspot.com/2008/03/all-those-parenthesis-are-counting-on.html

cheers
slobodan

Marco Antoniotti

unread,
Mar 24, 2008, 5:51:44 AM3/24/08
to
On Mar 24, 11:23 am, Slobodan Blazeski <slobodan.blaze...@gmail.com>

Or even enumerations (shameless plug: http://common-lisp.net/project/cl-enumeration/)

> Controlers , control the initialisation,stepping, results etc. So
> basically it'll render outdated control structures like: mapcar,
> reduce, dolist, dotimes, do, loop.
> Because you could loop through each container and as you wish using
> just map and nothing more.
>
> The only thing I have problem to figure out is how to gracefully
> collect multiple results. I need an efficient equivalent to below.
> (defun separate (lst)
>    (mapcar #'(lambda (n) (mapcar #'abs (remove-if-not n lst)))
>      (list #'plusp #'zerop #'minusp)))
> Something graceful like it but that will travel the list only once.
> Sorry for my confusing explanation but the ideas are still shaping in
> my mind and it usually helps when I try to explain this to somebody.
> Basically I want to use the ideas of array processing I found in APL
> family of languages, j & q and implement them as library in lispified
> form.
> If you need inspiration to understand look atwww.nsl.comespecially

> the challengehttp://www.nsl.com/papers/kisntlisp.htm
>
> This my blog post with even more confusing explanationhttp://tourdelisp.blogspot.com/2008/03/all-those-parenthesis-are-coun...
>

As I noted on your blog, you should have a look at SERIES.

Cheers
--
Marco


Slobodan Blazeski

unread,
Mar 24, 2008, 6:06:14 AM3/24/08
to
> Marco- Hide quoted text -

I did, but I disagree about how things should be done. Basically I
want a single utility, map(actually it won't be even betetr to get rid
of it too) with all the control done through controler depending on
the generators supplied.Series introduces bunch of operators. The
difference is between automagically figure by yourself utility and do
this package. Sorry because I can't explain any better.I think I will
have to figure this on my own, code it and give it for spin.


0 new messages