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.
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, it’s 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, it’s 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, it’s 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, it’s 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.