From: Duane Rettig on
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
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
Correction: on _most_ others. Some other people
gave correct answers too.
From: Pascal J. Bourguignon on
"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
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


--

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13
Prev: Do as the Romans do
Next: managing large table of data