[Python-ideas] Multi-statement anonymous functions

Andrew Barnert abarnert at yahoo.com
Mon Jan 13 12:13:15 CET 2014


So I assume you haven't read PEP 403 and 3150, and don't intend to, even though they directly relate to your idea?

Sent from a random iPhone

On Jan 13, 2014, at 2:23, musicdenotation at gmail.com wrote:

>> On Jan 13, 2014, at 15:21, Andrew Barnert <abarnert at yahoo.com> wrote:
> 
> 
>> From: "musicdenotation at gmail.com" <musicdenotation at gmail.com>
>> 
>> Sent: Sunday, January 12, 2014 10:48 PM
>> 
>> 
>>> Subject: [Python-ideas] Multi-statement anonymous functions
>>> 
>>> Proposed syntaxes:
>>>> let function(*args,**kwargs):
>>>>      ...body...
>>>> function2(...args...):
>>>>      ...body...
>>>> in:
>>>>      [statements]
>>> 
>>>> do:
>>>>      [statements]
>>>> where [function declarations in the same form as above]
>>> 
>>> Inspired by Haskell and Julia.
>>> 
>>> This has the advantage that declared functions aren't binded to names 
>>> outside their context.
>> 
>> 
>> I think there's something interesting here, but I'm not seeing it. What's the actual use case for this?
>> 
>> If you haven't read PEP 403 and PEP 3150, you should; they both offer similar (but not identical) features in a way that seems more readable (both more compact, and "fronting" the most important part of the construct):
>> 
>> 
>>     @in statement that uses function1
>>     def function1(*args, **kwargs):
>>         body
>> 
>>     statement that uses function1 and var1 given:
>>         def function1(*args, **kwargs):
>>             body
>>         var1 = value
>> 
>> Meanwhile, my first question for your syntax is: Why limit it to function definitions? It's worth noting that a Haskell let statement creates local bindings for any values you want; it's not restricted to functions. And that restriction is the only thing that forces the awkward block structure (which would need to be parsed differently than existing Python structures, both by the compiler and by human readers). Why not just a let statement that lets you execute _any_ statements in a local scope, then use that scope:
>> 
>>     let:
>> 
>>         def function1(*args, **kwargs):
>>             body
>>         var = value
>>         any other statement you want
>>     in:
>>         statements
>> 
>> … or, for that matter, just a local-scope statement:
>> 
>>     local:
>>         def function1(*args, **kwargs):
>>             body
>>         var = value
>>         any other statement you want
>>         statements that use those definitions
>> 
>> 
>> This has an advantage over Nick Coghlan's two proposals in that you get to run a full suite with the local scope, instead of just a single statement. (His fronting of the statement makes that restriction necessary; yours doesn't.)
>> 
>> But I'm wondering why you need a local scope. 
>> 
>> The let statement is necessary in Haskell because namespaces, like everything else, are immutable, and there are no real assignments; if you want to bind another variable, you have to create a new scope with that binding on top of the existing one. In Python, if you want to bind another variable, you just use an assignment/def/class/etc. And if you're worried about the name being accessible from outside of the namespace (e.g., if someone does a "from foo import *" on you), there are already idiomatic ways to deal with that: prefix the name with _, or give the module an __all__. Or, again: Python namespaces are mutable, so you can just del a binding after you're done with it if you really need to.
>> 
>> Coming at it from a different angle, JavaScript—which has mutable namespaces very much like Python—needs local scopes pretty frequently. But that's only because it has no modules, so everything is in one giant global namespace, which makes it hard to avoid conflicts, figure out where things are defined, etc. So that doesn't seem to apply to Python either.
>> 
>> Also, in most cases where you _do_ need a local scope, just defining and calling a function works just fine. That's what people do in Python when they need a local binding for micro-optimization purposes. And the same idiom is used all over the place in JavaScript (which, again, needs local scopes much more often than Python). Is there a use case where that isn't appropriate?
> 
> I change my proposal:
>> let:
>>     [all new variables created here are local to the let...in... scope, can use global and nonlocal]
>> in:
>>     [all new variables created here belong to the surrounding scope, but variables introduced in the let statement will be usable and reassignable]
> or:
>> do:
>>     [same semantics as in above]
>> where:
>>     [same semantics as let above]
> Or my original proposal but with variable assignment allowed.
> 
> Actually, my original proposal was because I didn't want to mess up with globals() and locals().
> And the where statement is to allow function definitions after their usage.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140113/fe8d96f4/attachment-0001.html>


More information about the Python-ideas mailing list