[Python-checkins] python/nondist/peps pep-0309.txt,NONE,1.1

goodger@users.sourceforge.net goodger@users.sourceforge.net
2003年2月10日 06:51:47 -0800


Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1:/tmp/cvs-serv7836
Added Files:
	pep-0309.txt 
Log Message:
Built-in Closure Type, by Peter Harris
--- NEW FILE: pep-0309.txt ---
PEP: 309
Title: Built-in Closure Type
Version: $Revision: 1.1 $
Last-Modified: $Date: 2003年02月10日 14:51:45 $
Author: Peter Harris <scav@blueyonder.co.uk>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 08-Feb-2003
Python-Version: 2.4
Post-History:
Abstract
=========
This proposal is for a built-in closure type for Python that allows a
new callable to be constructed from another callable and a partial
argument list (including positional and keyword arguments). A concise
syntax shorthand for closures is suggested (tentatively).
Motivation
===========
Closures are useful as functional 'sections' or as convenient
anonymous functions for use as callbacks.
In some functional languages, (e.g. Miranda) you can use an expression
such as ``(+1)`` to mean the equivalent of Python's ``(lambda x: x +
1)``.
In general, languages like that are strongly typed, so the compiler
always knows the number of arguments expected and can do the right
thing when presented with a functor and less arguments than expected.
Python has more flexible argument-passing, and so closures cannot be
implicit in the same way. Instead of using them, a Python programmer
will probably either define another named function or use a lambda.
But lambda syntax is horrible, especially when you want to do
something complex.
We need something better.
Rationale
==========
Here is one way to do closures in Python::
 class closure(object):
 def __init__(self, fn, *args, **kw):
 self.fn, self.args, self.kw = (fn, args, kw)
 def __call__(self, *args, **kw):
 d = self.kw.copy()
 d.update(kw)
 return self.fn(*(self.args + args), **d)
Note that when the closure is called, positional arguments are
appended to those provided to the constructor, and keyword arguments
override and augment those provided to the constructor.
So ``closure(operator.add,1)`` is a bit like ``(lambda x: 1+x)``, and
``closure(Tkinter.Label,fg='blue')`` is a callable like the Tkinter
Label class, but with a blue foreground by default.
I think a built-in type called ``closure``, that behaves the same way
but maybe implemented more efficiently, would be very useful.
Tentative Syntax Proposal
==========================
I know syntax proposals have the odds stacked against them, and
introducing new punctuation characters is frowned upon, but I think
closures are a sufficiently powerful abstraction to deserve it.
I propose the syntax ``fn@(*args,**kw)``, meaning the same as
``closure(fn,*args,**kw)``. I have no idea what havoc this would
wreak on the parser.
At least there are no backwards-compatibility issues because the @
character isn't a legal operator in any previous versions of Python.
The @ sign is used in some assembly languages to imply register
indirection, and the use here is also a kind of indirection.
``f@(x)`` is not ``f(x)`` , but a thing that becomes ``f(x)`` when you
call it.
Examples of Use
---------------
Using closures as callbacks with bound arguments::
 def handler(arg1, arg2, opt=0):
 #whatever...
 button1 = Button(window, text="Action A",
 command=handler@('A','1'))
 button2 = Button(window, text="Action B",
 command=handler@('B','2',opt=1))
Convenience functions ::
 nextarg = sys.argv.pop@(0)
Copyright
=========
This document has been placed in the public domain.

..
 Local Variables:
 mode: indented-text
 indent-tabs-mode: nil
 sentence-end-double-space: t
 fill-column: 70
 End:

AltStyle によって変換されたページ (->オリジナル) /