I have a confusion regarding closure and its definition. As per Paul Graham:
When a function refers to a variable defined outside it, its called a free variable. A function that refers to free lexical variable is called a closure.
However as per CLHS a closure or lexical closure is:
lexical closure n. a function that, when invoked on arguments, executes the body of a lambda expression in the lexical environment that was captured at the time of the creation of the lexical closure, augmented by bindings of the function's parameters to the corresponding arguments.
lexical environment n. that part of the environment that contains bindings whose names have lexical scope. A lexical environment contains, among other things: ordinary bindings of variable names to values, lexically established bindings of function names to functions, macros, symbol macros, blocks, tags, and local declarations (see declare).
There is no universal definition of the concept of closure in the context of programing languages.
Basically, if your language can define a function, and maitain a permanent internal variable inside, it's closure.
For example, if you define a global var, and your function use access and or set that global var, your function will be able to maintain a state.
However, we all know global vars are bad because, for example, you have this big pool where everyone and every function accesses... it's hard to maitain and could be over-ridden by mistake...
So, a crude way to remedy this, is by following a convention, such that any global var who's name starts with a 2 underscore is meant to for special use. So, this way, you can have global vars __this , __that , __x, etc, and your function can call them. Now your function can maintain a state, while the typical problem with using global vars is avoided by a naming convention.
Now, effectively, your function is said to have closure. Typically, that word is used when the language provide means to allow function to have a state without the above hackish method. However, it's no more complicated than that. In fact, it is effectively the only means to implement closure. If the language hides such global vars from user, and provide transparent ways when you create or access them inside your function without the __ prefix, that's closure.
Once a functional language's funtion's has states, that is, having closure, it is natural to extend the concept to become objects as in Object Oriented Programing.
When you start to program in a way of closures, that is, a function uses permant internal variables to maintain states, and you have many functions like that, naturally, you might systematically explore this paradigm. Namely, instead of just one or two permanent internal variables, each of your function uses tens of such permanent internal vars. This is the starting concept of so-called Object Oriented Programing.
> I have a confusion regarding closure and its definition. As per Paul > Graham:
> When a function refers to a variable defined outside it, its called a > free variable. A function that refers to free lexical variable is > called a closure.
> However as per CLHS a closure or lexical closure is:
> lexical closure n. a function that, when invoked on arguments, > executes the body of a lambda > expression in the lexical environment that was captured at the time of > the creation of the lexical closure, augmented by bindings of the > function's parameters to the corresponding arguments.
> lexical environment n. that part of the environment that contains > bindings whose names have lexical scope. A lexical environment > contains, among other things: ordinary bindings of variable names to > values, lexically established bindings of function names to functions, > macros, symbol macros, blocks, tags, and local declarations (see > declare).
> I have a confusion regarding closure and its definition. As per Paul > Graham:
> When a function refers to a variable defined outside it, its called a > free variable. A function that refers to free lexical variable is > called a closure.
> However as per CLHS a closure or lexical closure is:
> lexical closure n. a function that, when invoked on arguments, > executes the body of a lambda > expression in the lexical environment that was captured at the time of > the creation of the lexical closure, augmented by bindings of the > function's parameters to the corresponding arguments.
> lexical environment n. that part of the environment that contains > bindings whose names have lexical scope. A lexical environment > contains, among other things: ordinary bindings of variable names to > values, lexically established bindings of function names to functions, > macros, symbol macros, blocks, tags, and local declarations (see > declare).
(let ((val const)) (defun func (...) (setf val ...) ...))
Func sees val but outside the scope it doesn't. The trick is that the lexical environment survives the oldest function referring to it. This becomes particularly interesting when returning a anonymous function. (let ((val const)) (defun func (...) (setf val ...) (lambda (...) ...)))
Where lambda too knows val.
For a practical example study study the CL-PPCRE library.
> I have a confusion regarding closure and its definition. As per Paul > Graham:
> When a function refers to a variable defined outside it, it's called a > free variable. A function that refers to free lexical variable is > called a closure.
I'm not clear on what you are asking about. Are your concerns about Common Lisp or English?
Graham's first sentence clunks. The fault is the use of the pronoun "it" twice, with different referents. The sentence should be
When a function refers to a variable defined outside it, we call the variable a free variable.
One reason that it is important to write is that one learns how hard it is to express oneself clearly. Armed with this knowledge one can take a realistic attitude to other authors writings. Graham was not entirely clear. Diagnose the problem using the skills one has developed for making ones own writing clear to others. Work out what he meant and move on.
Notice the use of assignment, directly with setf, and lurking inside incf
CL-USER> (macroexpand-1 '(incf x)) (LET* ((#:G1626 1) (#:G1625 (+ X #:G1626))) (SETQ X #:G1625))
The use of assignment is essential.
Your state machine example in your blog post does no assignment and only accidently appears to work. I found it very confusing. I'll explain why.
Consider the following state machine; it has two states S0 (represented as 0) and S1 (represented as 1). Here is the logic that it performs, if the current state of the machine is S0 and input is 0 it remains in S0 else machine goes to state S1. If the current state of the machine is S1 and input is 0 it changes the state to S0 else it remains in state S1. This machine accepts 1 and 0 as input. Also note that this machine initializes at state S0.
Here is the code:
(let ((s0 0) (s1 1) (state 0)) (defun input-action(in) (if (eq state in) state (if (eq state s0) s1 s0))))
(I'm no expert on HTML but I've put the indentation back in. I think that you need to use the <pre> tag to preserve the leading white space. Is there another tag that does the job?)
What confused me was trying to reconcile the description with the code
(let ((s0 0)(s1 1) ....
What pops into my head is that you have two state variables s0 and s1 and four states.
With an extra function, to directly examine the state, you can see that it doesn't change. The point is covered up because you are encoding the input as a set of numbers {0, 1} and encoding the states as a set of numbers {0, 1}, and, oh look, its the same set.
Sometimes you have a particular encoding handed to you, for example, by the designers of a microprocessor, but this is rather specialised. In Common Lisp, it is best to use symbols directly.
CL-USER> (let ((state 'off)) (declare (type (member on off) state)) (defun input-action (input) (declare (type (member push nil) input)) (setf state (case input (push (case state (on 'off) (off 'on))) ((nil) (case state (on 'on) (off 'off)))))))
Notice my use of declarations. They are not necessary. If you were writing real code you would either leave them out or use a deftype to abbreviate them. However they are better than comments as decoration for code posted online because they have a formal meaning.
Notice that CASE clauses are headed by lists of things, which is just what you want for state machines. A symbol works as a designator for a list with one item, that symbol. Which is very convenient, except that NIL is the empty list and doesn't match anything. You can abbreviate ((push) ...) as (push ...), but you cannot abbreviate ((nil) ...) as (nil ...)
Your example and my example both suffer from the problem of being too simple. Since they don't really do anything it is hard for the reader to get the point and see how they do what they do. The example needs to be more complicated. But just a tiny bit more complicated, or the complications will conceal the point. I'm going to drop out at this point. Writing is hard. Writing requires practise. Please feel encouraged to write another blog post.
> I have a confusion regarding closure and its definition. As per Paul > Graham:
> When a function refers to a variable defined outside it, its called a > free variable. A function that refers to free lexical variable is > called a closure.
> However as per CLHS a closure or lexical closure is:
> lexical closure n. a function that, when invoked on arguments, > executes the body of a lambda > expression in the lexical environment that was captured at the time of > the creation of the lexical closure, augmented by bindings of the > function's parameters to the corresponding arguments.
> lexical environment n. that part of the environment that contains > bindings whose names have lexical scope. A lexical environment > contains, among other things: ordinary bindings of variable names to > values, lexically established bindings of function names to functions, > macros, symbol macros, blocks, tags, and local declarations (see > declare).
> Can any pro lisper kindly help me?
;; John's example: (let ((val const)) ; local, lexical variable (defun func (...) ; lexical closure (setf val ...) ; val is free in func ...))
(defvar *val* 'value) ; global, dynamic variable (defun gunc (...) ; a closure too! (setf *val* ...) ; *val* is free in gunc. ...)
Now, technically, in Common Lisp a function whose free variables are all global, dynamic variables wouldn't be called a closure, since these variable are not really enclosed in an environment with the function: they just lie in the global environment, along these functions, and since it's considered a closed universe, there's no outside to be considered enclosed. When everybody is something, there's no point in naming it.
Even a function without free variables could be considered a closure, if the implementation encloses it in an empty environment, just for the sake of homogeneity with the other closures. But CL leaves the implementations free to optimize this case out.
On May 2, 11:02 am, "xah...@gmail.com" <xah...@gmail.com> wrote:
> There is no universal definition of the concept of closure in the > context of programing languages.
Fortunately there is. You just have to look it up.
> Basically, if your language can define a function, and maitain a > permanent internal variable inside, it's closure.
> For example, if you define a global var, and your function use access > and or set that global var, your function will be able to maintain a > state.
Closures have nothing to do with global vars. Your attempt to explain it does not help.
We can have different closures with the same function and each has different variable bindings. Your global-variable-model does not provide that.
(defun make-thing (name) (flet ((local-function (message &rest args) (case message (:print (format t "Hi, I am ~a" name)) (:rename (setf name (first args)))))) #'local-function))
(make-thing "Red Chair") returns a closure. (make-thing "Blue Chair") returns another closure.
From the identifier you can see that both closures use the same 'Inner lfun' #x2A9AFD6. From the identifier you can see that both closures are different: #x2AA04BE and #x2AA3C6E The closures list different 'closed over values: "Red Chair" and "Blue Chair".
Both closures have the same inner function (it is just one function) but different variable bindings. So, we have two closures, but only one inner function and two different bindings.
Do you see the difference to your 'explanation'? It is not sufficient that a function has its own (uniquely named) global variables. You would need new variables every time a closure gets created.
Let's try your version:
(defparameter __name nil)
(defun make-thing (name) (setf __name name) (flet ((local-function (message &rest args) (case message (:print (format t "Hi, I am ~a" __name)) (:rename (setf __name (first args)))))) #'local-function))
(let ((a (make-thing :a)) (b (make-thing :b))) (funcall a :print) (terpri) (funcall b :print))
> I have a confusion regarding closure and its definition. As per Paul > Graham:
> When a function refers to a variable defined outside it, its called a > free variable. A function that refers to free lexical variable is > called a closure.
> However as per CLHS a closure or lexical closure is:
> lexical closure n. a function that, when invoked on arguments, > executes the body of a lambda > expression in the lexical environment that was captured at the time of > the creation of the lexical closure, augmented by bindings of the > function's parameters to the corresponding arguments.
> lexical environment n. that part of the environment that contains > bindings whose names have lexical scope. A lexical environment > contains, among other things: ordinary bindings of variable names to > values, lexically established bindings of function names to functions, > macros, symbol macros, blocks, tags, and local declarations (see > declare).
Hi Samik,
I'm no pro, but Graham's explanation does not square with everything else I've been learning about closures. The definitions you provided are correct, but they are difficult to understand for people who are unfamiliar with the terms they use. The big "aha" moment for me occurred when I realized the "lexical environment" was a THING. It's essentially something like an association table that matches symbols to values.
Think of it this way: in a Lisp without closures, a procedure is just a procedure. In a lisp with closures, a procedure is data- structure that has two parts: 1) code that does something, and 2) something like an association table that captures the state of all the variables when the function is called. So every time a function is run in a Lisp with closures, a new lexical environment is manufactured to go along with it.
When Lispers talk about how closures can be used to implement objects and object-oriented programming, they are talking about using techniques to coax the procedure part of the procedure-data-structure into manipulating the lexical environment part of the procedure-data- structure.
i don't quite understand what you were saying, perhaps largely due to your use of Common Lisp and jargons specific to it.
If you would, defend your thesis using plain English with good effort at technical writing, or perhaps with emacs lisp code, then we can start a debate.
if you think hard about closures, as if turning the concept into a mathematical definition (aka formalization or codification), and further, if you like, take a survey of say the top 10 major langs, about their concept of closure (if any), further, then i think you'll agree, that what i said about closures is perfect. Note the word _perfect_ here. Its not _approximately right_, nor _helpful analogy_, nor _insightful_. Perfect.
world.lisp.de> wrote: > On May 2, 11:02 am, "xah...@gmail.com" <xah...@gmail.com> wrote:
> > There is no universal definition of the concept of closure in the > > context of programing languages.
> Fortunately there is. You just have to look it up.
> > Basically, if your language can define a function, and maitain a > > permanent internal variable inside, it's closure.
> > For example, if you define a global var, and your function use access > > and or set that global var, your function will be able to maintain a > > state.
> Closures have nothing to do with global vars. Your attempt > to explain it does not help.
> We can have different closures with the same function > and each has different variable bindings. Your global-variable-model > does not provide that.
> (defun make-thing (name) > (flet ((local-function (message &rest args) > (case message > (:print (format t "Hi, I am ~a" name)) > (:rename (setf name (first args)))))) > #'local-function))
> (make-thing "Red Chair") returns a closure. > (make-thing "Blue Chair") returns another closure.
> From the identifier you can see that both closures use the same 'Inner > lfun' #x2A9AFD6. > From the identifier you can see that both closures are different: > #x2AA04BE and #x2AA3C6E > The closures list different 'closed over values: "Red Chair" and "Blue > Chair".
> Both closures have the same inner function (it is just one function) > but different variable bindings. > So, we have two closures, but only one inner function and two > different bindings.
> Do you see the difference to your 'explanation'? It is not sufficient > that a function > has its own (uniquely named) global variables. You would need new > variables > every time a closure gets created.
>i don't quite understand what you were saying, perhaps largely due to >your use of Common Lisp and jargons specific to it.
Rainer could have explained the concept without resorting to Lisp, but apart from the lame attempt to relate closures to state, your explanation was completely useless.
>If you would, defend your thesis using plain English with good effort >at technical writing, or perhaps with emacs lisp code, then we can >start a debate.
>if you think hard about closures, as if turning the concept into a >mathematical definition (aka formalization or codification), and >further, if you like, take a survey of say the top 10 major langs, >about their concept of closure (if any), further, then i think you'll >agree, that what i said about closures is perfect. Note the word >_perfect_ here. Its not _approximately right_, nor _helpful analogy_, >nor _insightful_. Perfect.
Your explanation was so off the mark as to be totally meaningless ... not even just confusing ... totally meaningless.
>On May 2, 4:11 pm, "jos...@corporate-world.lisp.de" <jos...@corporate- >world.lisp.de> wrote: >> On May 2, 11:02 am, "xah...@gmail.com" <xah...@gmail.com> wrote:
>> > There is no universal definition of the concept of closure in the >> > context of programing languages.
>> Fortunately there is. You just have to look it up.
>> > Basically, if your language can define a function, and maitain a >> > permanent internal variable inside, it's closure.
>> > For example, if you define a global var, and your function use access >> > and or set that global var, your function will be able to maintain a >> > state.
>> Closures have nothing to do with global vars. Your attempt >> to explain it does not help.
>> We can have different closures with the same function >> and each has different variable bindings. Your global-variable-model >> does not provide that.
>> (defun make-thing (name) >> (flet ((local-function (message &rest args) >> (case message >> (:print (format t "Hi, I am ~a" name)) >> (:rename (setf name (first args)))))) >> #'local-function))
>> (make-thing "Red Chair") returns a closure. >> (make-thing "Blue Chair") returns another closure.
>> From the identifier you can see that both closures use the same 'Inner >> lfun' #x2A9AFD6. >> From the identifier you can see that both closures are different: >> #x2AA04BE and #x2AA3C6E >> The closures list different 'closed over values: "Red Chair" and "Blue >> Chair".
>> Both closures have the same inner function (it is just one function) >> but different variable bindings. >> So, we have two closures, but only one inner function and two >> different bindings.
>> Do you see the difference to your 'explanation'? It is not sufficient >> that a function >> has its own (uniquely named) global variables. You would need new >> variables >> every time a closure gets created.
>I have a confusion regarding closure and its definition. As per Paul >Graham:
>When a function refers to a variable defined outside it, its called a >free variable. A function that refers to free lexical variable is >called a closure.
>However as per CLHS a closure or lexical closure is:
>lexical closure n. a function that, when invoked on arguments, >executes the body of a lambda >expression in the lexical environment that was captured at the time of >the creation of the lexical closure, augmented by bindings of the >function's parameters to the corresponding arguments.
>lexical environment n. that part of the environment that contains >bindings whose names have lexical scope. A lexical environment >contains, among other things: ordinary bindings of variable names to >values, lexically established bindings of function names to functions, >macros, symbol macros, blocks, tags, and local declarations (see >declare).
Closures aren't really complicated. There is a technical definition of closure in terms of bound and free variables, but essentially closures are about capturing non-local, lexically scoped variables at the time the function is defined.
I assume you are familiar with lexical scoping. Cribbing John Thingstad's example:
(let ((val init)) (defun func (...) (setf val ...) ...))
we see the definition of a function 'func' which references (indeed modifies) a non-local variable 'val'.
In Lisp (and some other languages), functions are allowed to use variables which are in scope at the point of definition even if those same variables are not in scope at the point of execution. This feature is useful, for example, for preserving private data between executions of a function.
In John's example, the variable 'val' cannot simply disappear after 'func' is defined - as lexical scoping would imply - because it will be needed when the function is executed.
To accomplish this, the compiler creates a data structure which associates the function's code with bindings for the non-local variables needed by the function. This data structure is known as a closure. [In reality there are ways to do this that do not actually create a new data structure. The term "closure" can refer to any runtime mechanism that associates a function with its non-local variables.]
Technically, any function definition creates a closure regardless of whether there are non-local variables involved (thus technically, most programming languages have closures), but the non-local variable case is the only interesting one. It also isn't necessary for the function to modify a non-local variables to preserve it in the closure - that just guarantees preservation - variables which are only read accessed also have to be preserved if their values are not atomic.
To everybody who is dissatisfied with this explanation, my intent is not to be perfectly correct wrt Lisp or indeed any particular language implementation, but rather to explain the concept in general terms. Feel free to comment on anything you think is too simplistic.
You and Rainer, are the epitomy of what i'd call the tech geeking morons (or just tech geekers), in my eyes. That's the type of people in computing industry, who can't see the gist of things, the context of things, the purpose of things, but perpetually bury their heads deep in technical obscurity.
(one quick way to picture this class of folks is to think of linuxers, in the context of software usability (imagine, the worse scenario, if your grandma calls in tech support asking about some problems with the computer, and a tech geeker on the other end is yelling about jumpers and drivers and kernel spaces running out of patience, quite frustrated and aghast at the level of igorance and stupidity of people in the world))
This class of folks, typically are slightly above average programers, and some are academics. Most have been in the industry for a while. Also, a significant percentage of them are a subset of studious college students studying computer science. Put it in another way, these tech geekers are a certain subset of elite programers, who pride in calling themselfs hackers.
The tech geekers, their thinking and views are inline with orthodox wisdom. They are also keen with the latest thinkings and trends and thoughts, and pride themselfes in this fact of fashionability. However, they have very little ability in creativity, or perspicacity. Their IQ is often above average, but typically are not outstanding. Also, their ability to analyze mathematically is low, possibly below average among their intellectual peers. They never possess the acumen typical of a mathematician.
However, a notable ability of tech geekers, is their tolerance for dense, incomprehensible, obscure, technicalities. (perhaps that's is also why they are good in their profession: coding) Specifically, the ability to drill down dense technical details, often at the expense of forgetting, discarding, or not understaning the context, whole design, or original purpose. More often than not, a hallmark of their foolhardiness caused by their tech drilling propensity, is that they often create the most unusable software.
i have posted here actively for a month or so few months back. You knew me, i knew you, we knew each other to some degree. So, instead of starting another perhaps ultimately tiresome and useless argumentation here about some computer science or programing subject, i thought i'd write something else, just to be fresh, about what i think of your cohorts as a class.
The usenet newsgroup comp.lang.* hierachy, are in fact a mecca for this tech geeker class i speak of. In contrast, the tech geekers are also almost never mathematicians, inventors, scientists. (For that matter, nor ever sociologists, historian, good philosopher, or great writers. O, and never artists of any standing.) I think a good alternative epithet to convey the characteristics of this class of people, is: Engineers. Of the nerdy, uncreative, brute force, ones.
Another tech geeker who was a regular here comes to mind. His name is Christopher Brown. I wrote of him, in 2001, here:
On May 2, 10:47 pm, George Neuner <gneuner2/@/comcast.net> wrote: On Fri, 2 May 2008 18:07:31 -0700 (PDT), "xah...@gmail.com"
<xah...@gmail.com> wrote: >Dear joswig, >i don't quite understand what you were saying, perhaps largely due to >your use of Common Lisp and jargons specific to it.
Rainer could have explained the concept without resorting to Lisp, but apart from the lame attempt to relate closures to state, your explanation was completely useless.
>If you would, defend your thesis using plain English with good effort >at technical writing, or perhaps with emacs lisp code, then we can >start a debate. >if you think hard about closures, as if turning the concept into a >mathematical definition (aka formalization or codification), and >further, if you like, take a survey of say the top 10 major langs, >about their concept of closure (if any), further, then i think you'll >agree, that what i said about closures is perfect. Note the word >_perfect_ here. Its not _approximately right_, nor _helpful analogy_, >nor _insightful_. Perfect.
Your explanation was so off the mark as to be totally meaningless ... not even just confusing ... totally meaningless.
On May 3, 10:34 am, "xah...@gmail.com" <xah...@gmail.com> wrote:
...
> i have posted here actively for a month or so few months back. You > knew me, i knew you, we knew each other to some degree. So, instead of > starting another perhaps ultimately tiresome and useless argumentation > here about some computer science or programing subject, i thought i'd > write something else, just to be fresh, about what i think of your > cohorts as a class.
> The usenet newsgroup comp.lang.* hierachy, are in fact a mecca for > this tech geeker class i speak of. In contrast, the tech geekers are > also almost never mathematicians, inventors, scientists. (For that > matter, nor ever sociologists, historian, good philosopher, or great > writers. O, and never artists of any standing.) I think a good > alternative epithet to convey the characteristics of this class of > people, is: Engineers. Of the nerdy, uncreative, brute force, ones.
...
Lisp is a programming language. That means it is thought for writing software and communicating ideas through software. All kinds of software. There is no limit.
This means that others will read code. I find the idea of using Lisp as a way to communicate ideas to be very important. This is assumes that the target audience makes some effort to understand the language and the author makes some effort to communicate clearly.
For me this means that comp.lang.lisp is a place where Lisp users discuss all kinds of problems related to Lisp programming (technical, social, ideas, ...). So in my postings I try not to abstractly talk about Lisp, but give real code examples and discuss real code examples. Not that my code is the best, but others can look at it and think about it - either it helps them or they can give me feedback about my own understanding. Actually I try less to write about social problems - others are doing this already. ;-)
If you ever want to be productive with Lisp (opposed to say, script Emacs or write Mathematica code), you should start thinking and writing in Lisp code. Your attempts at scripting Emacs is a useful start.
Rainer provided a very concise and clear explination of why your definition was overly simplistic and failed to really explain closures. He gave a clear high level english explination which was not overly burdened with what you mistakenly call tech geek speak and he provided clear examples using CL of both his more comprehensive explination and why yours was insufficient.
Instead of reverting to attacking him on a personal basis, why not address what he wrote? Is that because you know he is correct or is it because you don't have the intelect to understand his clear explination? You claim your 'perfect'and your definition was perfect, then why not prove it? Rainer provided a very simple example of where your definition fails - address that and prove your claims.
In fact, here is a challenge for you. You claim there are too many 'tech geeks' who insist on confusing everyone and making explinations too technical in order to show off their superiority and create an elitist style of environment that mainly aims to shut out the less technically oriented etc. Well, here is your chance to prove your point. Provide a clear and concise explination of closures that doesn't have the obvious wholes that Rainer pointed out and do so in a clear and concise manner that doesn't have the tech geek orientation you typically accuse others of when they challenge you. Rather than immediately becoming defensive as soon as your criticised, especially when that criticism comes with constructive and clear explination, consider what they have written in an objective and less emotional manner and improve your definition.
If you can do that, not only will you add to yor credibility, but you will also provide something valuable for those you claim to be attempting to help. Put your ego aside and see what truely positive contribution you can make. I would also suggest you get a native english speaker to help as your written communication is quite poor despite its overwhelming quantity. Clear writing is a difficult skill to master and even the very best have to work at improving their skills. You are a long way from perfect. The first step to getting better is to realise that.
> From: "xah...@gmail.com" <xah...@gmail.com> > Basically, if your language can define a function, and mai[n]tain a > permanent internal variable inside, it's closure.
But in a closure, the *same* private variable ("binding" in Lisp jargon) can be *shared* between two or more blocks/functions. Thus a closure allows *shared* own/static variables, so that the *shared* latest-value is preserved across entries to *either* block and accessible equally from each: (let ((x 42)) (defun setx (newx) (setq x newx)) (defun getx () x) "Done: Defined SETX with one arg and GETX with no args") It works with first-class anonymous functions just the same: (let ((x 42)) (values (function (lambda (newx) (setq x newx))) (function (lambda () x)))) And of course you can mix the two if you want. (let ((x 42)) (defun setx (newx) (setq x newx)) (function (lambda () x)))
Note that technically the name is "lexical closure" for the mechanism used in Lisp, where we use a lexical binding such as LET or LAMBDA or even PROG to temporarily create an environment with one or more lexical variables temporarily created, in which several functions can be created/defined, each sharing that temporary environment, hence all of them sharing those particular lexical bindings, except that because of the functions closing over variables in that lexical environment, the bindings become permanent in the sense that the lexical-binding environment is preserved indefinitely, to be used by those defined/created functions as long as those functions continue to exist. (Or just define/create ONE function in that lexical environment, which reduces to OWN/STATIC variables from Algol/WikiPedia.)
For a koan-like explanation: A set of one or more "lexical closure(s)" is/are a set of functions defined inside of a lexical context of bindings, thereby achieving the effect of those bindings becoming privately shared own/static variables.
> Note: The terminology =E2=80=9CClosure=E2=80=9D is actually a very > bad terminology. It spreads endless confusion and non-understanding.
I agree. The correct Lexical Closure also leads to some confusion among people who haven't read a decent explanation yet. I hope my explanations above are close to what would be needed to un-confuse newbies. Maybe somebody can re-word it to flow easier? My wording is somewhat clumsy but maybe Kent can clean it up to be *perfect*?
One really neat thing about Common Lisp's lexical closures, compared to C++'s and Java's classes with static variables, is that in CL our lexical environment doesn't require a name (the name of the C++ or Java *class*) and doesn't need to be defined in a separate file whose name matches the name of the *class*.
I feel like i'm a genius, even though i'm really not, but now it appears here, there are 4 against me now, and who are these 4 people? they are (mostly) experienced lisp programers.
If there are 4 lisp programers, most or all of which i think are experienced, and all claim that i was wrong, how can i be right?
<<Laughs out loud to myself a nervous laugh>>
So, logic must dictate, that i'm a real genius, that my thoughts are, as they say, beyond the times, transcents the common.
At this point, i have maybe 2 choices. (1) to continue my aloof existance, and keep exuding heightened phantasmagorical writings. (2) to be down to earth, and explain in earnest, technically, my positions in a humble way, with the consequences of (A) utterly proven myself to be the biggest idiot who made a big splash but shown to be wrong, at the end. (B) proven my distractors wrong, and hence earns the admiration and respect with mystic qualities.
This is a dire decision to make. I seems to be unable to make this decision. Could this be a false dilemma?
I'm guessing my problem has to do with my personality. A normal person, would probably just discuss the issue in earnest. Like, we all human beings, some knows some areas better, and we all make mistakes. A discussion can just carry on in its course, and everyone can just learn something or simply enjoy the conversation.
But Noooo! I can't be like that. People have wronged me. Not because i'm wrong, because they are cocks (and comparatively stupid?). Look at Rainer's reply to my message, he called me FUD!! He called me FUD, everybody! Look there!!!
He sayz: «Fortunately there is. You just have to look it up. »
Now that tone is not pleasant on the ear! I said «There is no universal definition of the concept of closure in the context of programing languages.» and he retorted me and denied me the pleasure to be correct!
He continues: «Closures have nothing to do with global vars. Your attempt to explain it does not help.»
Woot! Perhaps his writing skill at the precision aspect needs improving, but i don't think my writing claimed that closures has to do with global vars (nay, i knew i didn't). He sayz my attempt to help didn't help. He sullied me! I got sullied. Wrongfulness accused. Incompetence of fact-checking charged. I got WRONGED AND SULLIED. DENIED the pleasure of helping! A fundamental pleasure of life, denied to me, by one tech geeker.
I refused to believe this, and i kindly told Rainer that he should think about the issue, to formalize the concept, to take a survey, and i'm perfect. Now, one George tech geeker ganged on me and propound that i'm a perfect imbecile!
Witnesses, you have seen the above. The sequence of affairs is not unlike a pack of dogs barking for supremacy. I imagine i still have the upper hand though.
Still, it troubles me deeply, how could a patently simple explanation, a simple concept, a penetrating view, be not clearly grasped by a gaggle of lispers? In this thread, there are 15 messages. Not one reply, seems to indicate that what i said is correct. Almost half of them actually pointed out that i was incorrect, and even unhelpful. I'm greatly troubled by this. To me, this is like going into a bar, and when the subject of 1+1 comes up, my nonchalant remark of 2 suddently made everybody stare. This can be a terrifying experience. Like, in a bar you suddenly realized all the people around you are not humans but aliens. Or, you realized it's a gay bar and you are not gay. Or, they are all black and you are the only white. Or, you are standing out like a sole genius.
Suppose, in such a situation, you have some choices. A rational one, is to calmly explain, in earnest, your views. And, you think, truth will prevail. But nuuuuu! What if they will have none of it? I mean, for all you know, these aliens might be cannibals. And remember, you are out numbered. Just imagine, 50 bucks on a doe; the lord of the flies. A alternative course of action, is to ply the art of subterfuge. Feign left and right, give a smile and a nod. Acknowledge, that 1+1 can be 3, under the circumstances. Tech geek with them. Win a friend.
> Rainer provided a very concise and clear explination of why your > definition was overly simplistic and failed to really explain > closures. He gave a clear high level english explination which was not > overly burdened with what you mistakenly call tech geek speak and he > provided clear examples using CL of both his more comprehensive > explination and why yours was insufficient.
> Instead of reverting to attacking him on a personal basis, why not > address what he wrote? Is that because you know he is correct or is it > because you don't have the intelect to understand his clear explination? > You claim your 'perfect'and your definition was perfect, then why not > prove it? Rainer provided a very simple example of where your definition > fails - address that and prove your claims.
> In fact, here is a challenge for you. You claim there are too many 'tech > geeks' who insist on confusing everyone and making explinations too > technical in order to show off their superiority and create an elitist > style of environment that mainly aims to shut out the less technically > oriented etc. Well, here is your chance to prove your point. Provide a > clear and concise explination of closures that doesn't have the obvious > wholes that Rainer pointed out and do so in a clear and concise manner > that doesn't have the tech geek orientation you typically accuse others > of when they challenge you. Rather than immediately becoming defensive > as soon as your criticised, especially when that criticism comes with > constructive and clear explination, consider what they have written in > an objective and less emotional manner and improve your definition.
> If you can do that, not only will you add to yor credibility, but you > will also provide something valuable for those you claim to be > attempting to help. Put your ego aside and see what truely positive > contribution you can make. I would also suggest you get a native english > speaker to help as your written communication is quite poor despite its > overwhelming quantity. Clear writing is a difficult skill to master and > even the very best have to work at improving their skills. You are a > long way from perfect. The first step to getting better is to realise > that.
xah...@gmail.com wrote: > It's deja vu all over again.
> I feel like i'm a genius, even though i'm really not, but now it > appears here, there are 4 against me now, and who are these 4 people? > they are (mostly) experienced lisp programers.
> If there are 4 lisp programers, most or all of which i think are > experienced, and all claim that i was wrong, how can i be right?
> <<Laughs out loud to myself a nervous laugh>>
> So, logic must dictate, that i'm a real genius, that my thoughts are, > as they say, beyond the times, transcents the common.
> At this point, i have maybe 2 choices. (1) to continue my aloof > existance, and keep exuding heightened phantasmagorical writings. (2) > to be down to earth, and explain in earnest, technically, my positions > in a humble way, with the consequences of (A) utterly proven myself to > be the biggest idiot who made a big splash but shown to be wrong, at > the end. (B) proven my distractors wrong, and hence earns the > admiration and respect with mystic qualities.
> This is a dire decision to make. I seems to be unable to make this > decision. Could this be a false dilemma?
> I'm guessing my problem has to do with my personality. A normal > person, would probably just discuss the issue in earnest. Like, we all > human beings, some knows some areas better, and we all make mistakes. > A discussion can just carry on in its course, and everyone can just > learn something or simply enjoy the conversation.
> But Noooo! I can't be like that. People have wronged me. Not because > i'm wrong, because they are cocks (and comparatively stupid?). Look at > Rainer's reply to my message, he called me FUD!! He called me FUD, > everybody! Look there!!!
> He sayz: «Fortunately there is. You just have to look it up. »
> Now that tone is not pleasant on the ear! I said «There is no > universal definition of the concept of closure in the context of > programing languages.» and he retorted me and denied me the pleasure > to be correct!
> He continues: «Closures have nothing to do with global vars. Your > attempt to explain it does not help.»
> Woot! Perhaps his writing skill at the precision aspect needs > improving, but i don't think my writing claimed that closures has to > do with global vars (nay, i knew i didn't). He sayz my attempt to > help didn't help. He sullied me! I got sullied. Wrongfulness accused. > Incompetence of fact-checking charged. I got WRONGED AND SULLIED. > DENIED the pleasure of helping! A fundamental pleasure of life, denied > to me, by one tech geeker.
> I refused to believe this, and i kindly told Rainer that he should > think about the issue, to formalize the concept, to take a survey, and > i'm perfect. Now, one George tech geeker ganged on me and propound > that i'm a perfect imbecile!
> Witnesses, you have seen the above. The sequence of affairs is not > unlike a pack of dogs barking for supremacy. I imagine i still have > the upper hand though.
> Still, it troubles me deeply, how could a patently simple explanation, > a simple concept, a penetrating view, be not clearly grasped by a > gaggle of lispers? In this thread, there are 15 messages. Not one > reply, seems to indicate that what i said is correct. Almost half of > them actually pointed out that i was incorrect, and even unhelpful. > I'm greatly troubled by this. To me, this is like going into a bar, > and when the subject of 1+1 comes up, my nonchalant remark of 2 > suddently made everybody stare. This can be a terrifying experience. > Like, in a bar you suddenly realized all the people around you are not > humans but aliens. Or, you realized it's a gay bar and you are not > gay. Or, they are all black and you are the only white. Or, you are > standing out like a sole genius.
> Suppose, in such a situation, you have some choices. A rational one, > is to calmly explain, in earnest, your views. And, you think, truth > will prevail. But nuuuuu! What if they will have none of it? I mean, > for all you know, these aliens might be cannibals. And remember, you > are out numbered. Just imagine, 50 bucks on a doe; the lord of the > flies. A alternative course of action, is to ply the art of > subterfuge. Feign left and right, give a smile and a nod. Acknowledge, > that 1+1 can be 3, under the circumstances. Tech geek with them. Win a > friend.
> Sirs, would you like to have a piece of my mind?
I thought we just did. And it was great. Post on, O Mighty Xah!
I am fascinated by the evidence of soaring social IQ, so high now that the question of how best to react to reactors distracts from the OQ of closures. Computers are easy to figure out, but people? Omigod! Now there is a challenge for any genius in one domain but not others (Gardner found six).
If I want to improve my lot the most lucrative field of study will be the one in which I am most deficient: it would be much easier for me to improve my unicycling than my Lisp never having been on a unicycle. But with people the stakes are higher than the unicycle.
Above we hear one option to "continue my aloof existence", below we have another -- "Win a friend.". The evidence I spoke of is these even being considered. The monk (perhaps wisely!) has taken the easy way out, abandoning the challenge altogether and at the extreme retiring to a monastery where one does not speak. But I hear a yearning in the word "aloof" and in the conjunction of "win" and "friend" and why does "vow of silence" and "Xah Lee" sound so wrong?
I went woodshed (its a jargon thing) on stand-up recently, found two things: the audience is all that matters and (2) never mind the audience, you are right, they are wrong. Reconciliation below.
Most people were disapoointed by my talk at ECLM 2008, a fumbling walkthru of Cells and a quick look at my Algebra app. Apparently they were all primed for a dancing bear, and I just talked about the single most powerful software library one could use. Six liked it and wanted to talk afterwards, ninety hated it. The organizers want the airfare back.
Otoh, the folks lucky enough to be at the stern of boat #1 and the great crowd that heeded my ensuing pied piper procession to the bar nearest the dock got the show.
The moral?
(1) The audience is all that matters, but they respond only to truth. I have to get the audience, but I must use non-subterfuging subterfuge. This is the actors problem, to act and be real at once. Brando dumbfounded Cavett for an hour trying to convince him that Cavett -- simply by being a person -- was as great an actor as anyone.
(2) Next time Kenny yells "Let's go drinking!" at the end of the night, go drinking.
>Still, it troubles me deeply, how could a patently simple explanation, >a simple concept, a penetrating view, be not clearly grasped by a >gaggle of lispers? In this thread, there are 15 messages. Not one >reply, seems to indicate that what i said is correct. Almost half of >them actually pointed out that i was incorrect, and even unhelpful. >I'm greatly troubled by this. To me, this is like going into a bar, >and when the subject of 1+1 comes up, my nonchalant remark of 2 >suddently made everybody stare. This can be a terrifying experience. >Like, in a bar you suddenly realized all the people around you are not >humans but aliens. Or, you realized it's a gay bar and you are not >gay. Or, they are all black and you are the only white. Or, you are >standing out like a sole genius.
You _are_ incorrect. Following some factually correct but irrelevant information about naming conventions, you said:
"If the language hides such global vars from user, and provide transparent ways when you create or access them inside your function without the __ prefix, that's closure."
Conceptually, closures create a parameterized instance of a function by capturing the values of the function's free variables. As a technical matter, closures were specifically created to address the problem of "non-local" lexically scoped variables. Globals are free variables but they are not considered to be "non-local" in the lexical sense.
There is no technical reason why closures could not also capture globals (the top-level is a lexical scope after all), but there is a semantic reason not to. The variables in each lexical scope can be thought of as out-of-band communication channels for parts of the program contained within the scope. If all free variables were to be captured, there would be no way to communicate out-of-band data[*]. Globals, in particular, are considered to be for communication between different parts of the program, so globals are treated specially and are not captured by closures. [*] some people would consider that a Good Thing(tm).
George Neuner wrote: > Conceptually, closures create a parameterized instance of a function > by capturing the values of the function's free variables.
Not sure this matters, but it is not just the values being captured, it is the variables themselves, for I can assign to them and might share them with other closures.
Ken Tilton <kennytil...@optonline.net> writes: > George Neuner wrote: > > Conceptually, closures create a parameterized instance of a function > > by capturing the values of the function's free variables.
> Not sure this matters, but it is not just the values being captured, > it is the variables themselves, for I can assign to them and might > share them with other closures.
The point you make is valid, but I'm not sure if it matters either, but mostly only because Xah's writing is just so hard to read that it's hard to tell WHAT is relevant.
It saddens me actually, because it sounds like he actually thinks about a bunch of issues, and has a lot of energy that is frittered away in unproductive fashion. I think it's very hard for people to agree with him when they can't tell what he's saying--at least, I can't. I think he sometimes covers for less strong English composition skills by smokescreens built of personality flair, but he'd benefit from some honest self-reflection on whether confronting the communication problem more directly wouldn't help him. I don't think people would mind talking to him as much if he were less flippant about the fact that he's just plain unintelligible a lot, and less willing to blame that on other people.
In the end, people fail to agree with him, and he mistakes that for them disagreeing with him, which is a subtle wording difference, but not at all the same thing in practice. And he often appears sure that what he MEANS is right, which it might be, for all I can tell. If he can't express it well enough to tell, though, it's hard to go much farther.
To the point in this thread, he's made some remarks about global variables that may be reasoned or may not, but that are certainly not clearly enough presented to know what in fact he is saying. Then he makes fun of and offers active annoyance at people who've gone out of their way to engage him rather than dismiss him, trying to ferret out what he might be saying.
His remarks on closures vs object-oriented systems might be general confusion about what happens presently, or might just be speaking abstractly about concepts, and in the latter situation, might or might not be reasonable observations. It's just hard to tell.
To Kenny's comment above, the relevance seems to be that (defun foo (x) y) means more than (subst <some-value> 'y '(defun foo (x) y)) but indeed means that should y be given a new value through program execution, foo will see that new value. I'm pretty sure that Xah as much as said this.
I couldn't figure out what the __ stuff was about. It might have been a restatement of the *...* idea. Or it might have been saying that a closure was only ever used like: (defun foo (y) (setq x y)) (defun bar () x) (list (foo 3) (bar) (foo 4) (bar)) => (3 3 4 4) and that globals would live in __x and that other variables would be created locally, as if in the FOO definition above, the x would be created locally to FOO, not globally, because it had no special marker saying he wanted the global variable, as if it meant (defun foo (y) (let ((x y)) x)) but then again... he might not have meant that. His writing doesn't allow me to tell.
It's an open question whether he can tell whether (defun foo (x) (lambda () x)) gives a function where the x storage location is new each time foo is called, because at least one reading of his writing is that he thinks the free x in (lambda () x) might somehow [as a closure variable] refer to some __x secret global place that variables get put. This would be kind of like a weird gosub kind of thing I think I've seen in some old BASIC variants where function arguments weren't really "bound" but were rather names of global variables to set on entry to the function, so that defining (defun foo (x) (+ x 3)) (defun bar () (foo 4)) and then calling (bar) was really the same as writing: (defun foo () (+ __x 3)) (defun bar () (setq __x 4) (foo)) (bar) I don't think this is what Xah means, mostly because I think he's smarter than to think this. But his wording is vague enough that I think it would support some odd readings in this area. And under this reading, he'd be missing the point that (defun foo (x) (lambda () x)) means that (foo 3) and (foo 3) actually return closures over a different x, not over a common x.
I will say that many years back, I was talking to Bob Kerns (RWK) when we were both working at Symbolics [he and I also worked together at MIT and he taught me a great deal about Lisp in my formative years] and the topic of the day was a function called dw:accept-2 or something like that, I'm not sure I'm remembering the name right... it was part of the internals of the accept substrate of Dynamic Windows. He had identified it as the largest single function definition in Symbolics Genera. It had clearly gotten out of hand. He said to me that if he had it to do over again, he'd have written it as a flavor [i.e., a "class" in CLOS terminology; DW was written in Zetalisp, which was based on Flavors--probably New Flavors by the time of this discussion, but it was the same basic idea]. This took me aback because I had never clearly understood that a closure was really just a vague kind of anonymous, opaque class. Probably I should have noticed this ages before, since I had at that point been programming in CL for 10 years or so, but I hadn't ever really thought about it in such concrete terms. I understood instantly what he was saying, though, and it was quite an epiphany. It would never have occurred to me to rewrite something involving closures as something involving flavors/classes, but it seemed obviously right when he mentioned it.
Closures offer variables that hold (as Xah seems to be alluding to, if I can understand what he's running on about) state. And classes have the additional feature that the state is more "out in the open", if you will, especially since in CL one can always get in and use WITH-SLOTS [as opposed to languages like Java and C# where you can find yourself "locked out" of your class if you were not there at time of definition and didn't make something public. I had the vaguest sense that Xah was using the term "closed" to mean "encapsulated", and if you make this relation between closures and classes, then you can sort of see the analogy, even though it is syntactically different than how Lisp texts usually talk about it. So maybe this is the observation that Xah is making. Or maybe it's related. Or maybe not. Who can tell? It's a pity.
As a matter of practice, one cannot credit another with being right in an academic or technical discussion merely because they have said something vague and that vague thing is not inconsistent with an epiphany. If one could get such credit, then I would say things like "We need to invent a better power supply." and then claim credit for solving a major piece of the climate change problem, while meanwhile just chiding people all along for not understanding the detail of my remark... The credit goes to the first person to describe how to do that in a clear manner that can be executed upon unambiguously by more than one person working in isolation, not to the first person who says something so vague that it merely spans the relevant problem space.
But what's a worse pity is that Xah can't acknowledge others' attempts to engage him for what those attempts are--a friendly act. He seems to feel compelled to bat back the very people who are doing the most work to treat him like a human being. Much more than he sometimes gives the impression he's doing for them. I fully expect he'll explain to me why I'm a loser for writing this piece, which is intended not to make him feel bad, but rather to encourage him to take constructive action that would improve his overall ability to interact with the community constructively. All of this just my personal opinion, of course. Your (and his) mileage may vary. Ah well. At least I tried.
På Mon, 05 May 2008 09:06:50 +0200, skrev Kent M Pitman <pit...@nhplace.com>:
> I couldn't figure out what the __ stuff was about. It might have been > a restatement of the *...* idea. Or it might have been saying that a > closure was only ever used like:
Well __variable is a technique in Python to make class variables (appear) hidden. So he might see a closure as equivalent to a class declaration of a singleton pattern which makes all attributes private.
> > George Neuner wrote: > > > Conceptually, closures create a parameterized instance of a function > > > by capturing the values of the function's free variables.
> > Not sure this matters, but it is not just the values being captured, > > it is the variables themselves, for I can assign to them and might > > share them with other closures.
> The point you make is valid, but I'm not sure if it matters either, > but mostly only because Xah's writing is just so hard to read that > it's hard to tell WHAT is relevant.
In this case he gave an explanation attempt for closures which was going in the wrong direction. Trying to explain closures and mentioning global variables (and a naming scheme) is not a good idea.
What's useful is that he wrote down his idea what a closure is. It is a start to discuss whether this particular mental model is useful or not (or if it is not clearly enough defined to talk about it). That's why I tried to answer his post. I also try to 'drag' the discussion from the fuzzy to real code. Programming concepts are learned differently by different people - some have the ability to learn abstract concepts, other need to see code, others need to write that code and see how it works, again other people will need to see a picture (I mean a picture that visualizes the concept ;-) ), ...
> It saddens me actually, because it sounds like he actually thinks > about a bunch of issues, and has a lot of energy that is frittered > away in unproductive fashion. I think it's very hard for people to > agree with him when they can't tell what he's saying--at least, I > can't. I think he sometimes covers for less strong English > composition skills by smokescreens built of personality flair, but > he'd benefit from some honest self-reflection on whether confronting > the communication problem more directly wouldn't help him. I don't > think people would mind talking to him as much if he were less > flippant about the fact that he's just plain unintelligible a lot, and > less willing to blame that on other people.
It's not even that I don't agree with all technical things he says. Even when it is a unpopular message among hackers. For example I agree that many parts of Emacs are a total usability nightmare. Fixing keybings would be on my list to fix Emacs (that's one reason I prefer other Lisp environments, since they often have (slightly) better/simpler keybindings and interaction mechanisms).
(Lately I was using a very loud and noisy train (the inner doors were defect). I can use that train and I did because it was still the fastest way to get home - but it was sure no pleasure. Emacs is like that, sometimes.)
> In the end, people fail to agree with him, and he mistakes that for > them disagreeing with him, which is a subtle wording difference, but > not at all the same thing in practice. And he often appears sure that > what he MEANS is right, which it might be, for all I can tell. If he > can't express it well enough to tell, though, it's hard to go much > farther.
Usually I respond sometimes, when he has some interesting technical content and it is posted to a relevant newsgroup. The technical content has not to be correct - it just should be possible to discuss it. I have my share of wrong (false, not precise, vague, misleading) stuff posted to comp.lang.lisp, too. But there are a lot of readers who will catch that and provide help to correct me (and others). That's part of the posting experience of comp.lang.lisp - there is a lot of community knowledge/knowhow - more than a single person has. One of the first things to learn is that others are a) not stupid and know quite a lot and b) everybody cooks with water. ;-)
> I will say that many years back, I was talking to Bob Kerns (RWK) when > we were both working at Symbolics [he and I also worked together at > MIT and he taught me a great deal about Lisp in my formative years] > and the topic of the day was a function called dw:accept-2 or > something like that, I'm not sure I'm remembering the name right... it > was part of the internals of the accept substrate of Dynamic > Windows. He had identified it as the largest single function > definition in Symbolics Genera. It had clearly gotten out of hand. > He said to me that if he had it to do over again, he'd have written it > as a flavor [i.e., a "class" in CLOS terminology; DW was written in > Zetalisp, which was based on Flavors--probably New Flavors by the time > of this discussion, but it was the same basic idea]. This took me > aback because I had never clearly understood that a closure was really > just a vague kind of anonymous, opaque class. Probably I should have > noticed this ages before, since I had at that point been programming > in CL for 10 years or so, but I hadn't ever really thought about it in > such concrete terms. I understood instantly what he was saying, > though, and it was quite an epiphany. It would never have occurred to > me to rewrite something involving closures as something involving > flavors/classes, but it seemed obviously right when he mentioned it.
I don't like closures as a way to create datastructures. I know that one can use closures to get near an object system, but I don't think that's a good idea.
If I see this:
(defun make-point (x y) (lambda (message) ...))
or similar things, I really prefer a plain object system (like CLOS). There is usually no way to differentiate different closures (which is a point? which is a line?). A CLOS object is self identifying and I have standard ways to associate functions with different types of objects. It makes debugging easier. In the debugger I see a bunch of objects and I can see what is an instance of a point and what is an instance of a class. Closures don't have this property in the usual Lisp implementation.
But there are uses of closures that I would not want to be replaced by classes/methods/objects:
Passing down (or up) logic (functions) is useful. Then often I don't want to assemble all the arguments into a data structure, but I'm happy that the environment will hold all necessary variables and their values.
>George Neuner wrote: >> Conceptually, closures create a parameterized instance of a function >> by capturing the values of the function's free variables.
>Not sure this matters, but it is not just the values being captured, it >is the variables themselves, for I can assign to them and might share >them with other closures.
>kt
Yes, the bindings are captured. Sorry ... Xah gets me so riled sometimes that I can hardly see straight. I really should know better.
i'm rather quite surprised how my exposition of the closure concept turn up so many messages, many claiming it being even unhelpful or useless. And now, Kent, the rhetoric master, began his verbose elaboration with my name repeatedly embeded. (i feel, rather, elated by that) (lol)
in the beginning, 'was just Rainer and George Neuner. Their problem, is simply not seeing the over all picture, but drilling on Common Lisp technicality and terminology. I point this out but, but as i said, sometimes something so obvious and clear to me but can't get other programers to see. (lisp's cons and list problem, is another example, we've discused at length around Jan) Robert Maas came in too. So silly.
People, closures is effectively just function using global vars, alright?
You want functions to share env? create a naming scheme like _contextA_var1, _contextA_var2, ... then functions can share _contextA_* vars.
You want 2 different env? have it _contextA_*, _contextB_* ... etc.
You want nesting? Have it _contextA_ContextA_*..., _contextA_ContextB_*..., _contextA_ContextA_ContextA*, _contextA_ContextA_ContextB*, ..., etc.
No, the prefix _ isn't alluding to Python's object whatnot or anything. It just any random string as a naming convention so it could be programatically identified and hidden from user. (think how you would implement closure)
In this way, you have closures, or what closures is supposed to achieve in a program, in just about any language.
Closures, function with a state, OOP, are basically the same thing. They just have slightly different perspective, slightly different connotation, and defined and implemented differently in different langs.
When you formalize them into mathematics, they amount to the same thing.
People, stop tech geeking. Get ya heads out of sand. Stop drilling on definitions and terminologies, or burying yourself deep inside Common Lisp. The originall poster of this thread is perhaps asking about terminologies in CL context and i hijacked the thread to discuss the concept of closure itself in general. At least i wished you could see that.
The Kent Pitman fella is a pest. He is the circular priest. Writes long and carefully, and very difficult to deal with. Whatever he didn't like, will become the lamb to be put up for slaughter when the time comes.
The Rainer fella insists his posting of Common Lisp code as a way to put the discussion on firm grounds. What a meritable fellow. Try Emacs Lisp Rainer, or Mathemtica. If you have a question on the latter, i can help you.
Tim X, shuddap and go do your school work.
Kenny!!!!!! I saw your vid on google. On the beach babbling about the wonders of Common Lisp. You crazy!!!!
xah...@gmail.com wrote: > i'm rather quite surprised how my exposition of the closure concept > turn up so many messages, many claiming it being even unhelpful or > useless. And now, Kent, the rhetoric master, began his verbose > elaboration with my name repeatedly embeded. (i feel, rather, elated > by that) (lol)
> in the beginning, 'was just Rainer and George Neuner. Their problem, > is simply not seeing the over all picture, but drilling on Common Lisp > technicality and terminology. I point this out but, but as i said, > sometimes something so obvious and clear to me but can't get other > programers to see. (lisp's cons and list problem, is another example, > we've discused at length around Jan) Robert Maas came in too. So > silly.
> People, closures is effectively just function using global vars, > alright?
Possibly not. It depends on how you mean this naming scheme of yours to work (the meta-problem being you not accepting CL as the way to make concrete hence comprehensible normally incomprehensible natural language, but let's soldier on with sign language and see what can be achieved)...
> You want functions to share env? create a naming scheme like > _contextA_var1, _contextA_var2, ... then functions can share > _contextA_* vars.
> You want 2 different env? have it _contextA_*, _contextB_* ... etc.
If you at least show us the actual Python code we could understand you better. What I would be looking for is...well, lemme ask: Do you mean that "different env" would be achieved by generating unique names /on each dynamic entry/ into the same block of code, by mucking with the Python dictionary?
(map nil 'funcall (loop for x below 2 collecting (let ((yvar (concatenate 'string (symbol-name (gensym)) "-var1"))) (setf (gethash yvar *xah-space*) x) (lambda () (print `(y is ,(gethash yvar *xah-space*)))))))
-> (Y IS 0) (Y IS 1)
Or did you mean "different env" would be achieved by hard-coding _contextA_var1 one place in the code and hard-coding _contextB_var1 another place in the code?
The latter (hardcoding differently prefixed "var1"s) does not cut it, but in the former you are Greenspunning closures (but need to work out when to GC the unique names or in a sufficiently heavy-hit function your Python dictionary will explode).
You have mentioned Emacs Lisp as a satisfactory form of communication, perhaps someone could offer this in Emacs form:
(map nil 'funcall (loop for x below 2 collecting (let ((y x)) (lambda () (print `(y is ,y))))))
-> (Y IS 0) (Y IS 1)
Again, you can Greenspun that with a dictionary and GCing the globals (much harder--when does the anonymous function itself get GCed?), but maybe you did not mean that.
> You want nesting? Have it _contextA_ContextA_*..., > _contextA_ContextB_*..., _contextA_ContextA_ContextA*, > _contextA_ContextA_ContextB*, ..., etc.
> No, the prefix _ isn't alluding to Python's object whatnot or > anything. It just any random string as a naming convention so it could > be programatically identified and hidden from user. (think how you > would implement closure)
> In this way, you have closures, or what closures is supposed to > achieve in a program, in just about any language.
> Closures, function with a state, OOP, are basically the same thing. > They just have slightly different perspective, slightly different > connotation, and defined and implemented differently in different > langs.
> When you formalize them into mathematics, they amount to the same > thing.
> People, stop tech geeking. Get ya heads out of sand. Stop drilling on > definitions and terminologies, or burying yourself deep inside Common > Lisp. The originall poster of this thread is perhaps asking about > terminologies in CL context and i hijacked the thread to discuss the > concept of closure itself in general. At least i wished you could see > that.
> The Kent Pitman fella is a pest. He is the circular priest. Writes > long and carefully, and very difficult to deal with. Whatever he > didn't like, will become the lamb to be put up for slaughter when the > time comes.
> The Rainer fella insists his posting of Common Lisp code as a way to > put the discussion on firm grounds. What a meritable fellow. Try Emacs > Lisp Rainer, or Mathemtica. If you have a question on the latter, i > can help you.
> Tim X, shuddap and go do your school work.
> Kenny!!!!!! I saw your vid on google. On the beach babbling about the > wonders of Common Lisp. You crazy!!!!