Re: Understanding #' and function variables
From: Thomas A. Russ (tar_at_sevak.isi.edu)
Date: 02/04/04
- Next message: Duane Rettig: "Re: Executables: Why all the abuse?"
- Previous message: Thomas A. Russ: "Re: State machine representation"
- In reply to: Dave Roberts: "Understanding #' and function variables"
- Next in thread: Erann Gat: "Re: Understanding #' and function variables"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 04 Feb 2004 11:23:50 -0800
Dave Roberts <ldave@re-move.droberts.com> writes:
>
> > By default, in the arguments of a function call, CL expects that symbols
> > will name ordinary variables. If you want a symbol to name the function
> > variable in the alternate namespace, then you use #'A.
> >
> > (let ((a (lambda (x) x))) ; ordinary variable binding declaration
> > (flet ((a (x) x)) ; function variable binding declaration
> > (foo a) ; A names the ordinary variable
> > (foo #'a))) ; #'A names the function variable
>
> So this brings up a good question: If these are implemented as the same
> symbol with two "slots" (not to be confused with CLOS slots), then it seems
> like this would cause problems.
I wouldn't worry too much about "implementation" issues at this stage.
What is important is to get the concept down and just assume that clever
compiler writers have figured out how to get the "magic" to work.
If you think about it, most other programming languages like Java also
have similar constructs. For example, if you have a variable named
"bar" in your Java program, you can also have a method named "bar" at
the same time. And you could also have a class named "bar" as well. In
fact you could write a class "bar" that had a method "bar" and a slot
"bar" and everything would still work.
Similarly in Common Lisp, the association between symbols and values,
functions or classes is maintained separately. Which of the
associations you get depends on the context in which the evaluation of
the name (symbol) takes place. If the symbol appears in a function
position, you use the function lookup procedure. If it appears in an
argument position, you use the value lookup procedure. If it is used as
a class name in MAKE-INSTANCE, you use the class lookup procedure.
The only time things get a little confusing is when you want to use a
non-standard lookup method on the name. The APPLY and FUNCALL methods
take arguments, and for consistency function arguments are all looked up
in the same way, namely by getting their values. If you wanted to write
a function that takes a class as an argument then you would need to
write code that explicitly gets the class:
(f (get-class 'a))
similarly if you want your function argument to be a function, you need
to do the lookup as a function:
(f (function a))
Since this happens often, Common Lisp provides #' as a shortcut to
writing (FUNCTION ...) around it. An example closer to the one above
for classes would be
(f (symbol-function 'a))
but it is not quite the same. That is because SYMBOL-FUNCTION will get
the global value of the function associated with A and not any locally
bound values from FLET or LABELS. The presence of these lexical binding
constructs for values (LET) and functions means that things are slightly
more complicated than for other lookup procedures.
The principle behind this is that an attempt is made to make the most
common programming action be the simplest to write, with shortcuts to
make other not quite so common forms also fairly compact, and only
require the most verbose solutions to the least common idioms.
For an exercise, why not examine how one would go about writing
something like a FUNCALL function in Java? That would give you some
appreciation for all of the detail in looking up various things that
Lisp makes so much easier....
> If these are really two separate symbols in
> two separate namespaces (like if I was doing name mangling internally or
> something to value-A and function-A), that would seem to be better. The
> binding for "function-A" would go away as the FLET form was exited, while
> that would still leave "value-A" around until the LET form exited. If these
> are the same symbol, "A," with just two slots, I'm not sure how it would be
> handled when the FLET form went out of scope and yet I was still in the LET
> scope.
If you insist on thinking in terms of implementations, then there must
be some connection between the variable and the value to which it is
bound. At scope exit some process (which we don't need to understand in
detail) makes the binding go away. There is no reason to suppose that
this process cares whether it needs to have a separate symbol for each
type of binding or whether it just needs to know how to undo it.
If you really insist on a Java-esque example of how this might work,
consider the following, abbreviated Java example.
Assume a class Symbol with slots value and function.
Symbol a = new Symbol();
...
Object old_value = a.value;
try {
a.value = ... // (lambda (x) x)
Function old_function = a.function;
try {
a.function = ... // (x) x
foo((Function)a.value);
foo(a.function);
} finally {
a.function = old_function;
}
// At this point the function binding is restored!
} finally {
a.value = old_value;
}
But this is much more ugly in Java :)
>
> -- Dave
>
-- Thomas A. Russ, USC/Information Sciences Institute
- Next message: Duane Rettig: "Re: Executables: Why all the abuse?"
- Previous message: Thomas A. Russ: "Re: State machine representation"
- In reply to: Dave Roberts: "Understanding #' and function variables"
- Next in thread: Erann Gat: "Re: Understanding #' and function variables"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|