Costanza <costa...@web.de> wrote: > > Now, where is that guy who made a statement a few days ago to the > > effect that a closure preserves the bindings, not the values.
> > To me they seem to be essentially the same thing.
> > Wonder what he meant?
> Try the following:
> (defvar k) > (defvar setx) > (defvar sety)
> (let ((x 'big) (y 'daddy)) > (setq k #'(lambda () (list x y))) > (setq setx #'(lambda (value) (setq x value))) > (setq sety #'(lambda (value) (setq y value))))
> ? (funcall k) > (big daddy)
> ? (funcall sety 'mummy) > mummy
> Try to guess what (funcall k) will print now.
Thanks for the help.
I can see now that the binding remains "preserved", i.e. variable k still persists, even though the value associated with variable k has been changed to a different value.
<g...@jpl.nasa.gov> wrote: > > I feel that if I could understand the subtle differences between the > > meanings of "binding" and "value", that might have something to do with > > figuring out why the above example code above works as it does.
> Try this:
> A binding is a memory location.
> A value is what is stored in that memory location.
> So what is going on in the example above is:
> (let ((x 1)) ; Establish a binding (i.e. a memory location) for X.
> (defun x () x) ; Return the value in the binding (i.e. the memory > location) > ; established above
> (defun set-x (new) ; Change the value in the binding (the memory location) > (setf x new)) ; of X to NEW > )
Mark Conrad <nos...@iam.invalid> writes: > In article <u7wuh8gicn....@snapdragon.csl.sri.com>, Fred Gilham > <gil...@snapdragon.csl.sri.com> wrote:
> > But, as you saw, the binding for X can still be accessed by the > > functions in the closure that captured them, because the binding has > > infinite extent.
> Yes, I am going to have to be satisfied with that, and stop looking for > other dark hidden meanings for the word "binding".
> Namely, can a binding still exist when no value is assigned to the > binding.
> My knee-jerk reaction is that any binding, in order to *be* a > binding, has to have a value assigned to the binding.
How about this. In Lisp, one possible value to put in a binding is
| ---
a.k.a. "bottom". Bottom is the invalid value.
So a variable is "unbound" when Lisp looks at the binding (note, for the sake of argument I didn't say "looks in the binding") and finds bottom.
I think that's mostly the way it's implemented.
That also makes it possible to think of a binding as a place that can have values stuffed in it. Regardless of what people say, this is the way to think about it that makes the most sense operationally. Or, "Thinking about it like this won't steer you wrong."
By the way, why do my followups to your messages always wind up with
Cc: nobody
in the header?
-- Fred Gilham gil...@csl.sri.com The amazing thing is, back when I was a C++ programmer, I thought that [Design Patterns] was SUCH a great book. And I guess it was, in a way: it made it possible to use C++ and get something done. In the long run, of course, that may have been a disservice... - Alain Picard
* Fred Gilham wrote: > So a variable is "unbound" when Lisp looks at the binding (note, for > the sake of argument I didn't say "looks in the binding") and finds > bottom.
Well, specifically, a lexical variable binding can never have no value associated with it, while a dynamic binding can (witness PROGV). The spec is explicit about this somewhere. I presume the (or a) reason is efficiency - a lexical binding is likely to be compiled away to a much greater extent than a dynamic one. There's no way of finding out if a lexical binding exists, either (other than the obvious: is it lexically visible...)
> Does that mean if I don't explicitly place a value in the box, that I > do not have a real "binding"?
> Can a variable-binding "exist" independent of any value?
CL-USER 53 > (defvar no-value) NO-VALUE
CL-USER 54 > no-value Error: The variable NO-VALUE is unbound. 1 (continue) Try evaluating NO-VALUE again. 2 Return the value of :NO-VALUE instead. 3 Specify a value to use this time instead of evaluating NO-VALUE. 4 Specify a value to set NO-VALUE to. 5 (abort) Return to level 0. 6 Return to top loop level 0.
Type :b for backtrace, :c <option number> to proceed, or :? for other options
CL-USER 55 : 1 >
Clear as mud for you now, eh? :) (Note continuation number 4, this is where you could create a binding.)
+--------------- | Mark Conrad <nos...@iam.invalid> wrote: | > I feel that if I could understand the subtle differences between the | > meanings of "binding" and "value", that might have something to do with | > figuring out why the above example code above works as it does. | | Try this: | A binding is a memory location. | A value is what is stored in that memory location. +---------------
Actually, here's one area where IMHO the Scheme folk seem to have the terminology about right. From R5RS 3.1 "Variables, syntactic keywords, and regions":
An identifier may name a type of syntax, or it may name a location where a value can be stored. ... An identifier that names a location is called a variable and is said to be bound to that location. The set of all visible bindings in effect at some point in a program is known as the environment in effect at that point. The value stored in the location to which a variable is bound is called the variable's value.
Note that they also warn:
By abuse of terminology, the variable is sometimes said to name the value or to be bound to the value. This is not quite accurate, but confusion rarely results from this practice.
Except in discussions like this thread... ;-} ;-}
+--------------- | So what is going on in the example above is: | (let ((x 1)) ; Establish a binding (i.e. a memory location) for X. +---------------
Actually, *three* things logically happen here [assuming a lexical binding]: 1. A new location is allocated; 2. The variable "x" is bound to (caused to name) that location; and 3. The location is initialized with the value "1".
In CL terms, one may treat "location" as equivalent to "place", so that one may use a bound variable as the destination of a SETQ or SETF.
+--------------- | (defun x () x) ; Return the value in the binding (i.e. the memory | ; location) established above | (defun set-x (new) ; Change the value in the binding (the memory location) | (setf x new)) ; of X to NEW | ) +---------------
Close enough, I guess, but if I was being picky I'd say "return/change the contents of the location the variable 'x' is bound to".
-Rob
----- Rob Warnock, PP-ASEL-IA <r...@rpw3.org> 627 26th Avenue <URL:http://rpw3.org/> San Mateo, CA 94403 (650)572-2607
In article <u7r87ehjx0....@snapdragon.csl.sri.com>, Fred Gilham
<gil...@snapdragon.csl.sri.com> wrote: > That also makes it possible to think of a binding as a place that can > have values stuffed in it. Regardless of what people say, this is the > way to think about it that makes the most sense operationally. Or, > "Thinking about it like this won't steer you wrong."
Yeah, I finally wound up thinking of a binding the same way also.
> By the way, why do my followups to your messages always wind up with
> Cc: nobody
> in the header?
Oh, it is the way this Thoth newsreader handles things.
I have not really learned how to set up the newsreader yet, so anything that looked like it might throw spam into my email, I set to "antisocial" settings.<g> "nobody" was the recommended setting for one part of the newsreader, so I entered it. (I don't know what Cc refers to in the newsreader)
I certainly am happy that folks here straightened out my thinking about bindings. I believe knowing about bindings is necessary, absolutely necessary.
Now that I have bindings more-or-less under my belt, I can concentrate on the flow-of-control terms, catch, throw, unwind-protect, etc.
Once I can use *all* the abnormal-flow-of-control terms to my satisfaction, I will then create some "practice-programs" really loaded with every flow-of-control term I can think of - - - tagbody, block, return-from, go, return, prog, and all the rest of them including catch/throw etc.
Then I will try to replace *all* those terms with continuations, just as an exercise to learn how to use continuations.
Paul Graham's continuations are not easy to use in regular CL code, because to get them to work one has to write CL code in a rather hard-to-understand fashion. That makes any subsequent debugging hard to do.
Fortunately, there are very few times that continuations are called for in everyday CL programming.
* Mark Conrad wrote: > Paul Graham's continuations are not easy to use in regular CL code, > because to get them to work one has to write CL code in a rather > hard-to-understand fashion. That makes any subsequent debugging hard > to do.
Well, CL people would probably say that Scheme continuations are not easy to use in regular Scheme code, because to get them to work one has to write Scheme code in a rather hard-to-understand fashion. That makes any subsequent debugging hard to do.
But the language is smaller and purer, which is all that really counts, of course. I myself am working on reducing my English vocabulary to 400 words.
Tim Bradshaw <t...@cley.com> writes: > But the language is smaller and purer, which is all that really > counts, of course. I myself am working on reducing my English > vocabulary to 400 words.
We do not need the weasely `double' - plusplusgood is enough for us. Indeed, why bother with `plus', when we can just use `+'. ++good, what could be better? And those multiple-letter words, who needs them, ++g should be enough.
> It is yet another exception to the general behavior of CL that has > to be memorized and allowed for so it won't bite me later.
No, it is the defined behavior of Common Lisp. Not only that, it is defined behavior of any language that supports lexical scope and mutable bindings.
> Lisp gurus somehow learn the exceptions to general rules, (as those > rules are laid down in the books), but the only way I had to learn > about the nasty behavior above was to make a rash statement about how I > thought the cookie crumbled, then sit back and wait for agreement or > disagreement to my rash statement.
You could read the computer science literature.
> At the worst, something is broken somewhere in the CL implementation or > in the CL hyperspec, and should be changed.
You might want to look back at the messages posted by one `ilias'.
You seem to have overlooked the possibility that it is your *understanding* of CL that is broken and should be changed.
> Now let's make small changes in my above code to demonstrate the > unexpected nasty behavior, nasty behavior that is *not* explained in > any of the books that have been recommended to me in this NG.
This is the *essence* of lexical bindings. The bindings are of indefinite extent --- they remain in effect as long as necessary.
This is *very* elementary stuff, and you need to go back to the books and re-learn them.
> I don't want to "piss people off" so this will likely be my last post > in this NG.
Right......
> I can see now why there are so few new newbies adopting CL as their > preferred language, when it is apparent how cantankerous and downright > ornery people are in this NG.
> But the language is smaller and purer, which is all that really > counts, of course. I myself am working on reducing my English > vocabulary to 400 words.
> --tim
Well, there was a person in "Twenty Armchairs" by I. Ilf and E. Petrov. She was able to use 30 words only...