[Python-ideas] Enhance definition of functions
Ron Adam
ron3200 at gmail.com
Sat Aug 3 00:04:43 CEST 2013
On 08/02/2013 07:48 AM, Nick Coghlan wrote:
> On 1 August 2013 09:17, Andrew Barnert <abarnert at yahoo.com> wrote:
>> But anyway, I think you're mostly agreeing with me. When neither lambda nor def feels right, it's usually not because you really want a multi-line expression, or a multi-line anonymous function, but because you want to get the petty details of the function "out of the way" of the important code, right?
>
> Yeah, I've been grappling with this problem for years, which is why I
> have two competing deferred PEPs about it :)
>
> For certain kinds of problem, the natural way to think about them is
> as "I want to do X", and as an incidental part of doing X, you need to
> define a function that does Y. Sorting, complex comprehensions,
> various flavours of event driven programming (especially GUI
> programming, where the yield-driven approach of PEP 3156 may not be
> appropriate, as well as the low level transport code for PEP 3156
> style systems). Lambda isn't a great solution because it embeds all
> the complexity of the function directly in the main expression,
> obscuring the fact that the overall operation is "do X".
I'm not sure how much a function adds to complexity. Generally they
simplify things by moving the complexity to within the function. But short
one off functions are a different thing.
In most cases they are in the following situations:
1. Reuse a small bock of code over and over again locally.
2. Capture a value now, to be used later with that code block later.
3. Be sent into or out of a context so it can be used with values
that can't be accessed locally or presently.
> Using up another precious symbol would be a big call, but it's
> starting to feel more like something of sufficient power to justify
> new syntax.
My feelings is that this type of thing requires a lower level solution,
rather than a higher level abstraction.
All of the above cases could be handled nicely if we could define a code
block without a signature and call it with separately defined dictionary.
It might look something like...
seq = []
for i in range(10):
ns = dict(i=i)
co = def: i
seq.append(ns with co)
assert [expr() for expr in seq] == list(range(10))
It could be shortened to...
seq = [({'i':i} with def:i) for i in range(10)]
assert [expr() for expr in seq] == list(range(10))
The 'def:..' expression could return a code object. Which by itself
wouldn't be callable. To make it callable, you would need to combine it
with a signature object, or a name space. (Some sanity checks could be
made at that time.)
A signature object would return a name space constructor. This part is the
part we don't need in many cases. (*) So being able to use an already
constructed dictionary (or a yet to be constructed dictionary) as a name
space has some advantages.
The 'with' keyword is used here to combine two objects together. At least
one of them would need to know what to do with the other. In this case
it's the dictionary object that knows how to take a code object and return
a callable frame like object. Probably it has a __with_code__ method.
It may be too general of a definition of 'with', but possibly that can also
be a good thing. If it always results in a callable object, then it would
have just enough consistency to be easy to figure out when you come across
them later without being too restrictive. But this part is just an option
as a dictionary could just have a method..
callable_frame = {'i':i}.callable_with(def: i)
Cheers,
Ron
More information about the Python-ideas
mailing list