On Fri, Jan 11, 2008 at 11:23:48PM -0800, [EMAIL PROTECTED] wrote:
It's not the same as the picture and the man, because in the case of
code vs. data it is entirely a matter of context rather than an inherent
property of the data.
I was just trying to say that a bunch of bits just //represents//
procedures but
are not the procedures themselves. The actual procedures are a series of
operations in space and time. For example, SWAP(registerA, registerB) only
represents the physical procedure of swapping voltages between perhaps 2
areas of metal. I won't belabor this point anymore. Not sure if it leads to
anything useful.
Functions as first-class data has _nothing_ to do with manipulation of
machine code, or even the generation of the machine code. The language can
be entirely compiled beforehand, and functions generated and manipulated at
will. Lisp macros are about manipulation the program text/structure before
it is compiled. 'eval' is about having the compiler available at runtime
so new pieces of code can be synthesized while the system is running. They
are three very distinct concepts.
Generally, in a functional language, the piece of data that represents a
function is _not_ the actual code for that function. One representation,
would be as a pointer two a pair of pointers (there are more efficient
ways, though). The first pointer would be the address of the machine code
for the operation, and the second would be to the closure the function
needs.
Let's say I write:
(define (foo x)
(lambda (y) (+ x y)))
If I invoke (foo x), I get back a function. My implementation show it as
something like #<procedure #f (y)> (the #f is because I didn't give it a
name).
This function object coming back has a pointer to a piece of generated code
(generated at compile time), and a pointer to a closure, which in this case
will contain a single value that has what was passed into foo.
Now, try:
(define addem (foo 4))
Notice that 'addem' is defined as a variable definition, not as a function
definition. It gets this function object with a pointer to the generated
code for the lambda, and a newly created closure which contains a 4.
Now we can do
(addem 5)
9
and invoke our new function. Perhaps this will be clearer if our special
function modifies the closure.
(define (bar x)
(lambda (y)
(set! x (+ x y))
x))
(define addbar (bar 4))
The behavior is a bit different here:
(addbar 5)
9
(addbar 3)
12
The copy of the '4' that was made into the new closure is now being
modified by the lambda expression. Each invocation of 'bar' will give me a
new closure, which will have it's own added.
Dave
--
[email protected]
http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg