Page 1 of 1

Determine number of arguments for a function

Posted: Sat Sep 16, 2017 1:05 pm
by White_Owl
I need to find out how many arguments a function expects.

Code: Select all

(args? #'eql) -> 2
(args? #'length) -> 1
(args? (lambda (a b c) (+ a b c))) ->3
Where to start?

Re: Determine number of arguments for a function

Posted: Sat Sep 16, 2017 4:41 pm
by sylwester
What do you expect the result for these are?

Code: Select all

(lambda (a &rest rest) rest)

(lambda (a &optional b) b)

(lambda (a &key (a 4) b c) c)
Also, the name args? seems like you are doing a predicate and like Scheme naming conventions.

Re: Determine number of arguments for a function

Posted: Sat Sep 16, 2017 6:12 pm
by White_Owl
Only the necessary arguments should be counted. Optional and rest can be ignored.

Re: Determine number of arguments for a function

Posted: Sun Sep 17, 2017 12:17 pm
by David Mullen
In Clozure CL:

Code: Select all

(defun required-parameters (function)
  (loop for thing in (ccl:arglist function)
        until (member thing lambda-list-keywords)
        collect thing))

Re: Determine number of arguments for a function

Posted: Sun Sep 17, 2017 1:35 pm
by White_Owl
Thank you.
That is a perfect solution.

Re: Determine number of arguments for a function

Posted: Mon Sep 18, 2017 2:58 am
by sylwester
No it's not.. It locks you in to one implementation. Thus you are no longer writing Common Lisp but CCLs superset of Common Lisp. It's very unfortunate!

BTW: Are you sure this is not a XY problem? What are you going to use this for?

Re: Determine number of arguments for a function

Posted: Mon Sep 18, 2017 4:38 am
by White_Owl
sylwester wrote:No it's not.. It locks you in to one implementation. Thus you are no longer writing Common Lisp but CCLs superset of Common Lisp. It's very unfortunate!
The only change required for making it a proper CLISP is to remove ccl prefix from arglist function

Re: Determine number of arguments for a function

Posted: Mon Sep 18, 2017 6:26 am
by sylwester
Proper CLISP??? CLISP is not a synonym for Common Lisp. CLISP is one of many Common Lisp implementations and just like SBCL or CCL. As with all implementations they might be a superset and sure enough arglist is defined in it, but it doesn't make it more portable.

Code: Select all

[1]> (defpackage :test (:use :cl))
#<package test>
[2]> (in-package :test)
#<package test>
test[3]> #'arglist

*** - function: undefined function arglist
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of (fdefinition 'arglist).
RETRY          :R2      Retry
STORE-VALUE    :R3      Input a new value for (fdefinition 'arglist).
ABORT          :R4      Abort main loop
Break 1 test[4]> 
See?
arglist is the symbol arglist, lies in #<package ext>, is accessible in 6 packages COMMON-LISP-USER,
CS-COMMON-LISP-USER, EXT, POSIX, SCREEN, SYSTEM, names a function, has 1 property system::doc
Not portable! Not Common Lisp.

See this answer in SO

Re: Determine number of arguments for a function

Posted: Mon Sep 18, 2017 2:55 pm
by White_Owl
sylwester wrote:Proper CLISP??? CLISP is not a synonym for Common Lisp. CLISP is one of many Common Lisp implementations and just like SBCL or CCL. As with all implementations they might be a superset and sure enough arglist is defined in it, but it doesn't make it more portable.

Code: Select all

[1]> (defpackage :test (:use :cl))
#<package test>
[2]> (in-package :test)
#<package test>
test[3]> #'arglist

*** - function: undefined function arglist
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of (fdefinition 'arglist).
RETRY          :R2      Retry
STORE-VALUE    :R3      Input a new value for (fdefinition 'arglist).
ABORT          :R4      Abort main loop
Break 1 test[4]> 
See?
Sorry, what should I see? You forcibly switched to a different package, did not find a function in it, and conclude that the function is not defined in the implementation???
Then look here:

Code: Select all

C:dev>clisp -on-error abort                                         
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo      
  I I I I I I I      8     8   8           8     8     o  8    8     
  I  \ `+' /  I      8         8           8     8        8    8     
   \  `-+-'  /       8         8           8      ooooo   8oooo      
    `-__|__-'        8         8           8           8  8          
        |            8     o   8           8     o     8  8          
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8          
                                                                     
Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>      
                                                                     
Copyright (c) Bruno Haible, Michael Stoll 1992, 1993                 
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997                 
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998   
Copyright (c) Bruno Haible, Sam Steingold 1999-2000                  
Copyright (c) Sam Steingold, Bruno Haible 2001-2010                  
                                                                     
Type :h and hit Enter for context help.                              
                                                                     
[1]> #'arglist                                                       
#<COMPILED-FUNCTION ARGLIST>                                         
[2]> (arglist #'eql)                                                 
(#:ARG0 #:ARG1)                                                      
[3]> (arglist #'length)                                              
(#:ARG0)                                                             
[4]> (defpackage :test (:use :cl))                                   
#<PACKAGE TEST>                                                      
[5]>  (in-package :test)                                             
#<PACKAGE TEST>                                                      
TEST[6]>  #'arglist                                                  
*** - FUNCTION: undefined function ARGLIST                           
                                                                     
TEST[7]>                                                             
See? :)