Prev: Do as the Romans do
Next: managing large table of data
From: slash dot on 1 Feb 2010 14:03 On Feb 1, 6:11 pm, Duane Rettig <du...(a)franz.com> wrote: > On Jan 31, 3:34 pm, 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? > > I'm not sure why others on this thread are beating around the bush. > One person asked why you don't know it already, This is probably a misunderstanding. You read that as "Why don't you, the programmer, know how to do this in common lisp already?" The author probably meant "How come that you don't know how many arguments a function has, since it was you who declared it". > but perhaps others are > just toying with you, or perhaps being overly conservative with their > answers for fear of it not working on a particular implementation. I'm a tinkerer. > But you asked how to inspect a function, and the answer is "use the > cl:inspect function". This is another misunderstanding, because it is not me who wants to inspect functions to learn how to call them. My code at run-time wants to know how to call one of many lambdas, something like an array of lambdas. > How much information you get is implementation- > dependent, and perhaps the problem here is how people interpret the > relationship between cl:inspet and cl:describe, but since their > actions are both implementation dependent, implementations are free to > diverge them as much as is necessary to achieve the intuitive result. I guess it's okay to diverge here, because both functions are for human consumption, and people are more flexible than code when it comes to understanding "output". But, again, it's not me who wants to look up function arguments. It is my computer program that could automate some chores by navel-gazing. I need a navel-gazing function so that the code can learn about itself. 'function-lambda- expression' is the ticket! > On Allegro CL: > > CL-USER(1): (defun foo (a b c) (list a b c)) > FOO > CL-USER(2): (inspect #'foo) > A NEW #<Interpreted Function FOO> > lambda-list: (A B C) > 0 excl-type ----> Bit field: #x88 > 1 flags --------> Bit field: #x48 > 2 start --------> Bit field: #x00000010000011bb > 3 hash ---------> Bit field: #x0000000000008649 > 4 symdef -------> The symbol FOO > 5 code ---------> (LAMBDA (A B ...) ...), a proper list with 3 > elements > 6 formals ------> (A B C), a proper list with 3 elements > 7 cframe-size --> fixnum 0 [#x0000000000000000] > 8 immed-args ---> fixnum 0 [#x0000000000000000] > 9 locals -------> fixnum 0 [#x0000000000000000] > [1i] CL-USER(3): (compile 'foo) > FOO > NIL > NIL > [1i] CL-USER(4): (inspect #'foo) > A NEW #<Function FOO> > lambda-list: (A B C) > 0 excl-type ----> Bit field: #x88 > 1 flags --------> Bit field: #x88 > 2 start --------> Bit field: #x000000100095bef8 > 3 hash ---------> Bit field: #x000000000000864a > 4 symdef -------> The symbol FOO > 5 code ---------> short simple CODE vector (31) = #(33608 30956 > 35148 ...) > 6 formals ------> (A B C), a proper list with 3 elements > 7 cframe-size --> fixnum 0 [#x0000000000000000] > 8 immed-args ---> fixnum 0 [#x0000000000000000] > 9 locals -------> fixnum 0 [#x0000000000000000] > [2i] CL-USER(5): I tried that. Totally works, thanks...
From: slash dot on 1 Feb 2010 14:07 On Feb 1, 6:59 pm, "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de> wrote: > On 1 Feb., 18:17, p...(a)informatimago.com (Pascal J. Bourguignon) > wrote: > > > "jos...(a)corporate-world.lisp.de" <jos...(a)lisp.de> writes: > > > 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. > > > Well, it would depend if you want to write programs running on "most > > implementations" or on any Common Lisp implementation, I'd guess... > > Isn't that usually pretty useless? I would prefer to think task > oriented: I want to solve problem FOO and for that I need capability > BAR. > > The requirement to solve it in any Common Lisp implementation on the > planet under any circumstance sounds artificial to me. There > are many capabilities of Common Lisp implementations that are > not standardized, but still useful and used. If for a certain > capability there is a standard version, I would use it. If there > are non-standard capabilities for other stuff (like getting argument > lists from functions) I still use them - instead of inventing my > own. This also depends on the phase in the project. The order of ambitions, as I've learned after the war, is - make it work - make it right - (make it fast) I'm in the "make it work" phase right now. A portable macro-based solution is attractive, but 'function-lambda-expression' is simpler, because the implementation is doing all the leg-work (you score a point there). > > There are several ways to get portability. For function arglists, > there is this capability already in many popular Common Lisp > implementations in a very similar way. Here it is sufficient > to have a function that just calls the implementation specific > version. In fact that is what many Lisp programs do. > > From some SLIME/SWANK for CLISP: > > (defimplementation arglist (fname) > (block nil > (or (ignore-errors > (let ((exp (function-lambda-expression fname))) > (and exp (return (second exp))))) > (ignore-errors > (return (ext:arglist fname))) > :not-available)))
From: Pascal J. Bourguignon on 1 Feb 2010 14:11 slash dot <tyntyfax(a)gmail.com> writes: > On Feb 1, 2:02�am, Paul Donnelly <paul-donne...(a)sbcglobal.net> 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?) >> >> > So my question is: how can I inspect functions to find out how >> > many arguments it has, for example? >> >> Isn't that the sort of thing you should already know? > > My code needs a largish number of very similar lambdas. > Right now the code does what you suggest. It maintains > the information on its arguments in an extra data structure. > The argument information is put into the data structure > when the lambda is declared. This DOES work, but I was > curious about automating this. If your code already does it, then it is already automated. What more automation do you want? Unless your code does (read) and you have to type manually the argument list of each function when your code needs it... -- __Pascal Bourguignon__
From: Pascal J. Bourguignon on 1 Feb 2010 14:13 slash dot <tyntyfax(a)gmail.com> writes: > Very sweet, but I guess I go with 'function-lambda-expression' > for now. Good. So you're also the kind to go with buffer overflows since they work 90% of the time anyways... -- __Pascal Bourguignon__
From: joswig on 1 Feb 2010 14:56
On 1 Feb., 20:13, p...(a)informatimago.com (Pascal J. Bourguignon) wrote: > slash dot <tynty...(a)gmail.com> writes: > > Very sweet, but I guess I go with 'function-lambda-expression' > > for now. > > Good. So you're also the kind to go with buffer overflows since they > work 90% of the time anyways... Pascal, sorry this is bullshit. Your comparison is faulty. Generally try not so much to tell people what they should do. Give the information what is available, what are useful practices - but in the end, they have to make an educated choice. Try out the alternatives and get a deeper understanding. Maybe they have reasons why they want to do things in a certain way. Maybe they make a mistake, but they get the chance to learn from the mistake. The function 'function-lambda-expression' is not in ANSI CL, to provide the mental equivalent of 'buffer overflows'. It is meant to provide a stable interface to a functionality that might be there or might not be there - depending on the development environment or deployment situation. The availability of this functionality is not 'random'. It is based on choices the implementation developers have made and on choices the application developer can make. I wish Common Lisp would specify more like this. Functions that are standardized, but their working is optional - like the ability to retrieve arglists, which usually every development environment will provide, but which in a deployment/delivery situation might not work, for example when during delivery debug information has been removed from the application. For example in Allegro CL the function BUILD-LISP-IMAGE has the option :DISCARD-ARGLISTS . So it is under programmer control whether in Allegro CL arglists are available in an image or not. There is nothing random or dangerous about it. This really has nothing to do with 'buffer overflows'. |