<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><blockquote type="cite"><span style="-webkit-text-size-adjust: auto;">On Jan 13, 2014, at 15:21, Andrew Barnert <<a href="mailto:abarnert@yahoo.com">abarnert@yahoo.com</a>> wrote:</span></blockquote></div><div style="-webkit-text-size-adjust: auto;"><br></div><blockquote type="cite" style="-webkit-text-size-adjust: auto;"><div><span>From: "<a href="mailto:musicdenotation@gmail.com">musicdenotation@gmail.com</a>" <<a href="mailto:musicdenotation@gmail.com">musicdenotation@gmail.com</a>></span><br><span></span><br><span>Sent: Sunday, January 12, 2014 10:48 PM</span><br><span></span><br><span></span><br><blockquote type="cite"><span>Subject: [Python-ideas] Multi-statement anonymous functions</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Proposed syntaxes:</span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span> let function(*args,**kwargs):</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> ...body...</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> function2(...args...):</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> ...body...</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> in:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> [statements]</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span> do:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> [statements]</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span> where [function declarations in the same form as above]</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Inspired by Haskell and Julia.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>This has the advantage that declared functions aren't binded to names </span><br></blockquote><blockquote type="cite"><span>outside their context.</span><br></blockquote><span></span><br><span></span><br><span>I think there's something interesting here, but I'm not seeing it. What's the actual use case for this?</span><br><span></span><br><span>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):</span><br><span></span><br><span></span><br><span> @in statement that uses function1</span><br><span> def function1(*args, **kwargs):</span><br><span> body</span><br><span></span><br><span> statement that uses function1 and var1 given:</span><br><span> def function1(*args, **kwargs):</span><br><span> body</span><br><span> var1 = value</span><br><span></span><br><span>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:</span><br><span></span><br><span> let:</span><br><span></span><br><span> def function1(*args, **kwargs):</span><br><span> body</span><br><span> var = value</span><br><span> any other statement you want</span><br><span> in:</span><br><span> statements</span><br><span></span><br><span>… or, for that matter, just a local-scope statement:</span><br><span></span><br><span> local:</span><br><span> def function1(*args, **kwargs):</span><br><span> body</span><br><span> var = value</span><br><span> any other statement you want</span><br><span> statements that use those definitions</span><br><span></span><br><span></span><br><span>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.)</span><br><span></span><br><span>But I'm wondering why you need a local scope. </span><br><span></span><br><span>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.</span><br><span></span><br><span>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.</span><br><span></span><br><span>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?</span><br></div></blockquote><br>I change my proposal:<div><blockquote type="cite">let:</blockquote><blockquote type="cite"> [all new variables created here are local to the let...in... scope, can use <i>global</i> and <i>nonlocal</i>]</blockquote></div><blockquote type="cite"><div>in:</div><div> [all new variables created here belong to the surrounding scope, but variables introduced in the let statement will be usable and reassignable]</div></blockquote><div>or:</div><div></div><blockquote type="cite"><div>do:</div><div> [same semantics as <i>in</i> above]</div><div>where:</div><div> [same semantics as <i>let</i> above]</div></blockquote>Or my original proposal but with variable assignment allowed.<div><br></div><div>Actually, my original proposal was because I didn't want to mess up with <u>globals()</u> and <u>locals()</u>.</div><div>And the <i>where</i> statement is to allow function definitions after their usage.</div></body></html>