Prev: Do as the Romans do
Next: managing large table of data
From: Duane Rettig on 2 Feb 2010 02:13 On Feb 1, 11:03 am, slash dot <tynty...(a)gmail.com> wrote: > 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". OK, well, I don't purport to know what people are thinking when they say things on the internet; that only causes trouble. > > 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. Yes, OK, I see that your second post on this thread answers that question. But because you kept using the word "inspect", which tends to have strong meaning in CL terminology, and in fact does indeed imply human interaction, I missed that clarification. You probably should have just used the word you titled this thread with: "introspect", because it is more generic in CL terms. Or you could use the word "access", which has clear program-related connotations in CL terminology. > > 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! Ah, but it too is implementation-dependent. The problem is that the spec allows any implementation to return nil as the result of function- lambda-expression for any function. The reason why an implementation would want to do this is that for a compiled function, it can be a great waste of space to save every function's source. Allegro CL allows you to specify whether or not to save a function's lambda- expression using the variable excl:*save-function-lambda-expression* (nil, by default) so that people who don't use the feature don't waste the space. Other implementations might not be so parameterizable; they might either force all such expressions to be saved, or they may invoke the "always return nil" allowance to save space. But you're back to implementation-dependence. Someone else also mentioned an internal function called arglist (in the implementation's internal package), and I submit that that is more likely to be of use to you if it really is the arglist you want. I recall someone (but I don't remember who it was, sorry) who posted on c.l.l. an implementation independent version of arglist for all of the CLs on which he was working, which called whatever version of arglist was appropriate for the implementation (Allegro CL's is excl:arglist, by the way). Maybe a google search (or perhaps a reminder from someone who created or who uses that definition) might be helpful here. The reason why I think it is a better bet than f-l-e is because although the lambda source is mostly expendable when a function is compiled, the argument list is not; it must be used by debuggers to decide where arguments actually reside; it allows IDEs to name argument lists while you are in the editor writing code; it allows programs to decide arity, etc., and it is also less likely to be elided from an implementation because of its necessity. So it is more likely that the tradeoffs in whether to keep the argument list or not are more in your favor than that of the entire source for the function. Duane
From: budden on 2 Feb 2010 02:34 There are so many experts there who can always explain: 1. You want the Wrong Thing. You really do not need this. Go and learn more until you are enlightened. 2. This is impossible due to some very solid reasons. 3. But you can reinvent a wheel one more time as CL is extensible. And only Rainer The Great was the one who have noticed that there is SLIME: a lisp program (sic!) which can show function arglist in a rather portable way. My congratulations to Rainer Joswig, shame on others!
From: budden on 2 Feb 2010 02:39 Correction: on _most_ others. Some other people gave correct answers too.
From: Pascal J. Bourguignon on 2 Feb 2010 03:10 "joswig(a)corporate-world.lisp.de" <joswig(a)lisp.de> writes: > 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. It is good that an API be defined for when the feature is present, but what happens when the feature is not present? You proposed a first approach, to abort and signal to the user that the action cannot be carried on with the current implementation. But if this is not acceptable, what you have to do anyways, is to provide an alternative implementation. That is, you have to do the work anyways. (if (feature-exist-p) (use-feature) (implement-feature-yourself)) Well, for me, it's simplier to just do: (implement-feature-yourself) > 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. It may be acceptable to allow for optional API when there's a human programmer or debugger at the other end of the stick. But not when it's a program. See above. I wish there wouldn't be optional APIs in a language standard. > 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'. Using function-lambda-expression may or may not give the expected result. Similarly, writing: char* buffer=malloc(10); buffer[11]='a'; may or may not give the expected result. If you're running with an implementation of the C language where malloc rounds the size to the next multiple of 8, the above code would work perfectly well. However, there are good reasons why to ostracize it. If your application depends on the availability of the list of arguments, then you cannot count on function-lambda-expression any more than you can count on buffer overflows working. (Of course, I don't say that you cannot write an application that will behave correctly, even conformingly, using function-lambda-expression, or overflowing buffers (as long as you catch segv signals, or specify the program crash)). -- __Pascal Bourguignon__
From: W. James on 2 Feb 2010 03:39
joswig(a)corporate-world.lisp.de wrote: > > 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. Matzlisp: f = lambda{|a,b,c| } ==>#<Proc:0x00000000@(irb):22> f.arity ==>3 -- |