[Python-ideas] Enhance definition of functions

Haoyi Li haoyi.sg at gmail.com
Sat Aug 3 00:20:43 CEST 2013


PEP 3150 is actually pretty simple to implement using macros:

>>> @in(map(_, [1, 2, 3]))
... def thing(x):
...   return x + 1
...
>>> thing
[2, 3, 4]

The macro is about 5 lines long, since it's exactly the same as my 15-line
quick lambda macro (i.e. f[_ + _] -> lambda a, b: a + b); this should have
worked out of the box, requiring no additional code:

@f[map(_, [1, 2, 3]]
def thing(x):
    return x + 1

But it doesn't due to the parser not liking [] in decorators; boo for
arbitrary syntactic restrictions =( =( =(.

This only works for higher-order-functions with a single callback. As
things stand now, the status-quo solution for multi-callback functions is
to make a class and inherit from it, and fill in the methods you need to
fill in. There wasn't any PEP for this but that's what people are doing all
over the place: many many classes exist purely to let people fill in the
missing functions. Not because the class objects have any state, or you
ever intend to create objects which will live for more than one function
call:

class MyClass(BaseRequestClass):
    def print_data(d):
        print d
    def print_error(failure):
        sys.sys.stderr.write(str(failure))

result = MyClass().make_request()

# never gonna use MyClass() ever again!

Java uses this pattern too, and I do not like it. One possibility, though,
would just codify/streamline the status quo, via macros:

@in(make_request(_, _))
class result:
    def print_data(d):
        print d
    def print_error(failure):
        sys.sys.stderr.write(str(failure))

Which would desugar (using macro-magic and metaclasses) into

def print_data(d):
    print d

def print_error(failure):
    sys.sys.stderr.write(str(failure))

result = make_request(print_data, print_error)

Potential bikesheds are over whether to use `_` to leave holes, or
`print_data` and `print_error` as named arguments, as well as whether
`result` should be a class or function def. Overall, though, it looks
exactly like PEP3150 except this

public_name = ?.MeaningfulClassName(*params) given:
    class MeaningfulClassName():
        ...

becomes this:

@in(_.MeaningfulClassName(*params))
class public_name:
    class MeaningfulClassName():
        ...

Which is pretty close. I can put up the implementations of all of these
things if anyone's interested in playing around with the syntax/semantics
in the REPL.

-Haoyi


On Sat, Aug 3, 2013 at 1:46 AM, Antoine Pitrou <solipsis at pitrou.net> wrote:

> On Fri, 2 Aug 2013 09:25:05 -0700
> Andrew Barnert <abarnert at yahoo.com> wrote:
> > On Aug 2, 2013, at 9:00, Antoine Pitrou <solipsis at pitrou.net> wrote:
> >
> > >> Using "@" as the marker character is also problematic, since the
> > >> following degenerate case will probably confuse the parser (due to it
> > >> looking too much like a decorator clause):
> > >>
> > >>   @something() given:
> > >>       ...
> > >
> > > No, that would simply be forbidden. In this proposal, "@" can only mark
> > > names of parameters in function calls. We already reuse "*" and "**"
> > > for a specific meaning in front of function call parameters, so there's
> > > a precedent for such polysemy.
> >
> > That's fine if callbacks are the _only_ case you want to handle, but as
> Nick just explained, there are many other cases that are also useful. The
> middle of an if expression in a comprehension, for example, isn't a
> function parameter.
>
> There may be many other cases, but almost any time people complain
> about the lack of inline functions, it's in situations where they are
> declaring callbacks (i.e. GUI- or network-programming). So, yes, I
> don't think the other use cases should be a primary point of concern.
>
> > Also, when you have a long function call expression--as you almost always
> > do in, say, PyObjC or PyWin32 GUIs--you often want to put each
> > parameter on its own line. While that won't confuse the parser, it
> > could easily confuse a human, who will see "@callback," on a line by
> > itself and think "decorator".
>
> Even if indented, inside a parenthesis and not preceding a similarly
> indented "def"?
>
> Regards
>
> Antoine.
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20130803/52523983/attachment-0001.html>


More information about the Python-ideas mailing list