Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #56676

Re: closure = decorator?

From Jussi Piitulainen <jpiitula@ling.helsinki.fi>
Newsgroups comp.lang.python
Subject Re: closure = decorator?
Date 2013-10-11 15:01 +0300
Organization University of Helsinki
Message-ID <qotd2nckod7.fsf@ruuvi.it.helsinki.fi> (permalink)
References (2 earlier) <qot8uy1rz4l.fsf@ruuvi.it.helsinki.fi> <m2a9ihxf3a.fsf@cochabamba.vanoostrum.org> <roy-B93AED.20042310102013@news.panix.com> <qot38o88eju.fsf@ruuvi.it.helsinki.fi> <5257c3dd$0$29984$c3e8da3$5496439d@news.astraweb.com>

Show all headers | View raw


Steven D'Aprano writes:
> On Fri, 11 Oct 2013 10:14:29 +0300, Jussi Piitulainen wrote:
> > Roy Smith writes:
> >> In article <m2a9ihxf3a.fsf@cochabamba.vanoostrum.org>,
> >>  Piet van Oostrum wrote:
> >> 
> >> > I usually say that a closure is a package, containing a
> >> > function with some additional data it needs. The data usually
> >> > is in the form of name bindings.
> >> 
> >> That's pretty close to the way I think about it.  The way it was
> >> originally described to me is, "A closure is a function bundled
> >> up with it's arguments".
> > 
> > Really? It should be more like "a function bundled up with some
> > other function's arguments" and even more like "a function bundled
> > up with bindings for its free variables".
> 
> Closures have nothing to do with *arguments*. A better definition of
> a closure is that it is a function together with a snapshot of the
> environment it was called from.

Well, first, I was only trying to see something good in Piet's and
Roy's formulations.

Second, it's precisely not (a snapshot of) the environment where the
function is *called* from, it's (a snapshot of) the environment where
the function was *created* in. This is the whole *point*.

Third, to be even more pedantic, in the context where I think closures
originally appeared as an innovation, all local variables are bound by
a lambda. There the (non-global) free variables of a function *are*
arguments of *another* function. I can expand on this if you like, but
it will be in terms of another language, and not terribly relevant to
this discussion anyway.

> def func(arg):
>     y = arg + 1
>     def inner():
>         return y + 1000
>     return inner
> 
> f = func(1)
> 
> At this point, f is a closure. It needs to know the value of y (not
> the argument to func) in order to work, and the implementation is to
> store that information inside f.func_closure (or f.__closure__ in
> Python 3).  The part of the calling environment which is saved is y:
> 
> py> f.func_closure[0].cell_contents
> 2

Whether there is a y in the *calling* environment or not is
*irrelevant*.

   >>> (lambda y : func(1))('whatever')()
   1002

> > And the data that makes a function a closure is bindings always,
> > by definition, not just usually.
> 
> Its not just *any* bindings though, it is specifically bindings to
> variables in the environment from which it was called.

In the environment where it was created.

> [...]
> >> That's a closure.
> > 
> > I fail to see a closure here. I see a class. I see an implied
> > object that could as well be dict(spot=37, time=5). Other entities
> > (garage and attendants) are not made sufficiently explicit.
> 
> In general, anything you can do with a closure, you can do with an
> object explicitly recording whatever state you want. A closure is
> just one implementation of "callable object with state that can be
> set when you create it". The closure f defined above could instead
> be written as:
> 
> class Func:
>     def __init__(self, arg):
>         self.y = arg + 1
>     def __call__(self):
>         return self.y + 1000
> 
> f = Func(1)
> 
> Which is better? If you want to expose the value of y to the outside
> world to modify, the class solution is better. If you don't, the
> closure is better. Closures tend to be more compact, and I suspect
> more efficient, but there's nothing you can do with one you can't do
> with the other.

Sure.

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

closure = decorator? Tim <jtim.arnold@gmail.com> - 2013-10-10 06:51 -0700
  Re: closure = decorator? Chris Angelico <rosuav@gmail.com> - 2013-10-11 01:03 +1100
    Re: closure = decorator? Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-10-10 17:15 +0300
      Re: closure = decorator? Piet van Oostrum <piet@vanoostrum.org> - 2013-10-10 12:31 -0400
        Re: closure = decorator? Roy Smith <roy@panix.com> - 2013-10-10 20:04 -0400
          Re: closure = decorator? Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-10-11 10:14 +0300
            Re: closure = decorator? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-10-11 09:24 +0000
              Re: closure = decorator? Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-10-11 15:01 +0300
                Re: closure = decorator? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-10-11 16:44 +0000
                Re: closure = decorator? Terry Reedy <tjreedy@udel.edu> - 2013-10-11 16:51 -0400
              Re: closure = decorator? Franck Ditter <nobody@nowhere.org> - 2013-10-11 14:08 +0200
                Re: closure = decorator? Terry Reedy <tjreedy@udel.edu> - 2013-10-11 16:55 -0400
  Re: closure = decorator? Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-10-10 17:08 +0300
  Re: closure = decorator? Peter Cacioppi <peter.cacioppi@gmail.com> - 2013-10-12 13:54 -0700
    Re: closure = decorator? Tim <jtim.arnold@gmail.com> - 2013-10-14 09:39 -0700

csiph-web