Prev: Do as the Romans do
Next: managing large table of data
From: slash dot on 1 Feb 2010 13:48 On Feb 1, 2:20 am, Barry Margolin <bar...(a)alum.mit.edu> wrote: > In article > <99200608-d39f-47ba-b5b3-35937ae46...(a)m16g2000yqc.googlegroups.com>, > slash dot <tynty...(a)gmail.com> wrote: > > > lisp is famous for is reflection capabilities, and, > > indeed, a function like '10+' is reported to be > > > #<FUNCTION 10+ (NUMBER) (DECLARE (SYSTEM::IN-DEFUN 10+)) > > (BLOCK 10+ (+ 10 NUMBER))> > > > in clisp. > > > (Disturbingly, this only works if I bind #'10+ to a variable and > > evaluate > > the variable, but that's a clisp implementation detail, right? RIGHT?) > > > So my question is: how can I inspect functions to find out how > > many arguments it has, for example? > > If (function-lambda-expression #'10+) returns non-NIL, the second > element of the list will be the argument list. You'll have to parse the > &keywords to turn this into a number of arguments. Thank you. This is precisely what I was looking for. clisp knows 'function-lambda-expression'. > > -- > Barry Margolin, bar...(a)alum.mit.edu > Arlington, MA > *** PLEASE post questions in newsgroups, not directly to me *** > *** PLEASE don't copy me on replies, I'll read them in the group ***
From: slash dot on 1 Feb 2010 13:49 On Feb 1, 4:09 am, p...(a)informatimago.com (Pascal J. Bourguignon) wrote: > slash dot <tynty...(a)gmail.com> writes: > > lisp is famous for is reflection capabilities, and, > > indeed, a function like '10+' is reported to be > > > #<FUNCTION 10+ (NUMBER) (DECLARE (SYSTEM::IN-DEFUN 10+)) > > (BLOCK 10+ (+ 10 NUMBER))> > > > in clisp. > > > (Disturbingly, this only works if I bind #'10+ to a variable and > > evaluate > > the variable, but that's a clisp implementation detail, right? RIGHT?) > > Wrong. > > C/USER[18]> (defun 10+ (NUMBER) (+ 10 number)) > 10+ > C/USER[19]> (function 10+) > #<FUNCTION 10+ (NUMBER) (DECLARE (SYSTEM::IN-DEFUN 10+)) > (BLOCK 10+ (+ 10 NUMBER))> > C/USER[20]> (function-lambda-expression '10+) > (LAMBDA (NUMBER) (DECLARE (SYSTEM::IN-DEFUN 10+)) (BLOCK 10+ (+ 10 NUMBER))) ; > #(NIL NIL NIL NIL > ((DECLARATION ALSO-USE-PACKAGES XLIB::CLX-VALUES VALUES OPTIMIZE > DECLARATION))) ; > 10+ > C/USER[21]> (compile '10+) > 10+ ; > NIL ; > NIL > C/USER[22]> (function-lambda-expression '10+) > (LAMBDA (NUMBER) (+ 10 NUMBER)) ; > T ; > 10+ > C/USER[23]> (load (compile-file "/tmp/10.lisp")) > ;; Compiling file /tmp/10.lisp ... > ;; Wrote file /tmp/10.fas > 0 errors, 0 warnings > ;; Loading file /private/tmp/10.fas ... > WARNING: DEFUN/DEFMACRO: redefining function 10+ in /private/tmp/10.fas, was > defined in top-level > ;; Loaded file /private/tmp/10.fas > T > C/USER[24]> (function-lambda-expression '10+) > NIL ; > T ; > 10+ > C/USER[25]> > > > So my question is: how can I inspect functions to find out how > > many arguments it has, for example? > > 1 - As Zach indicated, it is not. > > 2 - As Barry indicated, the standard function to "inspect" functions > is FUNCTION-LAMBDA-EXPRESSION, but since it's allowed to return > NIL, see point 1. > > 3- However, thanks to the homoiconicity of lisp, you can easily > implement the needed bookmarking yourself. See: > http://www.informatimago.com/develop/lisp/small-cl-pgms/ibcl/ Very sweet, but I guess I go with 'function-lambda-expression' for now. > > -- > __Pascal Bourguignon__
From: slash dot on 1 Feb 2010 13:50 On Feb 1, 10:03 am, "Captain Obvious" <udode...(a)users.sourceforge.net> wrote: > sd> So one cannot inspect a function, is that what's you're > sd> saying, Zach? > > Common Lisp standard does not require functions to be inspectable. > Because Common Lisp is supposed to be compiled and be effective, > w.r.t. memory usage too, I guess. > > But is is not a problem because you can extract information you > want via macro at time function is defined. Write your own defun-like > macro and capture whatever you want. > > E.g. if you want some functions to be accessible via RPC of some sort, > you can make a macro defun-rpc which is pretty much like defun: > > (defun-rpc 10+ (number) (+ 10 number)) > > But internally it counts parameters, publishes functions, whatever. > > That is a Common Lisp way to do it. > > sd> Have I fallen for an April fool's joke? No dice? > > Some implementations provide functionality which is not required > by standard. I thought about a macro, thanks, but do you really suggest that? Isn't that intrusive?
From: slash dot on 1 Feb 2010 13:55 On Feb 1, 2:57 pm, Pascal Costanza <p...(a)p-cos.net> wrote: > On 01/02/2010 10:59, jos...(a)corporate-world.lisp.de wrote: > > > > > On 1 Feb., 00:34, slash dot<tynty...(a)gmail.com> wrote: > >> lisp is famous for is reflection capabilities, > > > Right. Though the capabilities vary between Lisp dialects and > > implementations. > > >> and, > >> indeed, a function like '10+' is reported to be > > >> #<FUNCTION 10+ (NUMBER) (DECLARE (SYSTEM::IN-DEFUN 10+)) > >> (BLOCK 10+ (+ 10 NUMBER))> > > >> in clisp. > > >> (Disturbingly, this only works if I bind #'10+ to a variable and > >> evaluate > >> the variable, but that's a clisp implementation detail, right? RIGHT?) > > >> So my question is: how can I inspect functions to find out how > >> many arguments it has, for example? > > > If we talk about Common Lisp, the standard does not really give you > > that > > functionality. There is the function 'function-lambda-expression', > > which > > may work or not. > > > Individual Common Lisp implementations usually have a function > > to get argument lists. Historically this function was often called > > ARGLIST in some package. LispWorks calls it lw:function-lambda-list. > > A way to do this portably is by defining your own function-defining > forms. Here is a sketch (untested): > > (in-package :closer-common-lisp-user) ;; requires CLOS MOP support > > (defclass my-function (funcallable-standard-object) > ((meta-information :initarg :meta :reader meta-information)) > (:metaclass funcallable-standard-class)) > > (defmethod initialize-instance :after > ((f my-function) &key function) > (set-funcallable-instance-function f function)) > > (defmacro my-defun (name (&rest lambda-list) &body body) > `(progn > (setf (fdefinition ',name) > (make-instance 'my-function > :function (lambda ,lambda-list ,@body) > :meta ',lambda-list)) > ',name)) > > (defmacro my-lambda ((&rest lambda-list) &body body) > (make-instance 'my-function > :function (lambda ,lambda-list ,@body) > :meta ',lambda-list)) > > You can use package shadowing to make sure that you use the same names > for symbols like the original definition forms from the CL package, > which makes it easier to use this with existing code. > Thanks, but I'd prefer to refrain from CLOS for the time being. My ambition is limited to clisp for now; portability is not an issue for the moment.
From: slash dot on 1 Feb 2010 13:55
On Feb 1, 4:48 pm, "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de> wrote: > On 1 Feb., 14:57, Pascal Costanza <p...(a)p-cos.net> wrote: > > > > > On 01/02/2010 10:59, jos...(a)corporate-world.lisp.de wrote: > > > > On 1 Feb., 00:34, slash dot<tynty...(a)gmail.com> wrote: > > >> lisp is famous for is reflection capabilities, > > > > Right. Though the capabilities vary between Lisp dialects and > > > implementations. > > > >> and, > > >> indeed, a function like '10+' is reported to be > > > >> #<FUNCTION 10+ (NUMBER) (DECLARE (SYSTEM::IN-DEFUN 10+)) > > >> (BLOCK 10+ (+ 10 NUMBER))> > > > >> in clisp. > > > >> (Disturbingly, this only works if I bind #'10+ to a variable and > > >> evaluate > > >> the variable, but that's a clisp implementation detail, right? RIGHT?) > > > >> So my question is: how can I inspect functions to find out how > > >> many arguments it has, for example? > > > > If we talk about Common Lisp, the standard does not really give you > > > that > > > functionality. There is the function 'function-lambda-expression', > > > which > > > may work or not. > > > > Individual Common Lisp implementations usually have a function > > > to get argument lists. Historically this function was often called > > > ARGLIST in some package. LispWorks calls it lw:function-lambda-list. > > > A way to do this portably is by defining your own function-defining > > forms. Here is a sketch (untested): > > > (in-package :closer-common-lisp-user) ;; requires CLOS MOP support > > > (defclass my-function (funcallable-standard-object) > > ((meta-information :initarg :meta :reader meta-information)) > > (:metaclass funcallable-standard-class)) > > > (defmethod initialize-instance :after > > ((f my-function) &key function) > > (set-funcallable-instance-function f function)) > > > (defmacro my-defun (name (&rest lambda-list) &body body) > > `(progn > > (setf (fdefinition ',name) > > (make-instance 'my-function > > :function (lambda ,lambda-list ,@body) > > :meta ',lambda-list)) > > ',name)) > > > (defmacro my-lambda ((&rest lambda-list) &body body) > > (make-instance 'my-function > > :function (lambda ,lambda-list ,@body) > > :meta ',lambda-list)) > > > You can use package shadowing to make sure that you use the same names > > for symbols like the original definition forms from the CL package, > > which makes it easier to use this with existing code. > > > Pascal > > > -- > > My website:http://p-cos.net > > Common Lisp Document Repository:http://cdr.eurolisp.org > > Closer to MOP & ContextL:http://common-lisp.net/project/closer/ > > I would avoid that, since most implementations > can return function arglists already. That's needed for > any inspector/describe/IDE feature showing a function's > arglist. > > Just write a > function that calls the unportable implementation specific thing. > I would not invent a new mechanism without a real need. I will, thanks. |