Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #56676
| 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> |
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 | Next — Previous in thread | Next in thread | Find similar | Unroll 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