Re: A question (confusion) about closure



On May 2, 11:02 am, "xah...@xxxxxxxxx" <xah...@xxxxxxxxx> 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.

Let's look inside:

? (describe (make-thing "Red Chair"))
#<COMPILED-LEXICAL-CLOSURE LOCAL-FUNCTION #x2AA04BE>
Name: LOCAL-FUNCTION
Inner lfun: #<Compiled-function LOCAL-FUNCTION (Non-Global)
#x2A9AFD6>
Closed over values
(0): "Red Chair"

? (describe (make-thing "Blue Chair"))
#<COMPILED-LEXICAL-CLOSURE LOCAL-FUNCTION #x2AA3C6E>
Name: LOCAL-FUNCTION
Inner lfun: #<Compiled-function LOCAL-FUNCTION (Non-Global)
#x2A9AFD6>
Closed over values
(0): "Blue Chair"

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))

Hi, I am B
Hi, I am B

Too, bad. Doesn't work. No closures.

? (describe (make-thing :A))
#<Compiled-function LOCAL-FUNCTION (Non-Global) #x2ADD4D6>
Name: LOCAL-FUNCTION
Arglist (analysis): (CCL::ARG-0 &REST CCL::THE-REST)

Again, no closure.


Above is btw. Common Lisp, which uses lexical binding by default
(different from Emacs Lisp)
and thus supports closures directly.


--------------

Note: The terminology “Closure” is actually a very bad terminology. It
spreads endless confusion and non-understanding. See:

Your usual FUD. If you study the above example, you can end your
confusion.

...

.