Hi all, I would like to observe that there is already a way to bind names in an expression:
a = (lambda b: [b, b])(b=f()) Currently this is not so performant, but there is nothing stopping the compiler from special-casing such an IIFE (Immediate Invoked Function Expression), to use the Javascript terminology. It would then be fast in, say, Python 3.8, but still work in earlier versions. Stephan 2018-03-02 14:26 GMT+01:00 Paul Moore <p.f.mo...@gmail.com>: > On 2 March 2018 at 12:48, Nick Coghlan <ncogh...@gmail.com> wrote: > > The design intent related rationale stems from the fact that closed over > > references can live for an arbitrarily long time (as can regular function > > locals in a generator or coroutine), and I think statement locals should > be > > as reliably ephemeral as we can reasonably make them if they're going to > be > > different enough from function locals to be worth the hassle of adding > them. > > > > So that means asking a bunch of questions and deliberately giving the > > *opposite* answer for statement locals than I would for function locals: > > > > * Visible in locals()? Yes for function locals, no for statement locals > > * Visible in frame.f_locals? Yes for function locals, no for statement > > locals > > * Prevents access to the same name in outer scopes? Yes for function > locals, > > no for statement locals > > * Can be closed over? Yes for function locals, no for statement locals > > > > Answer "no" to all those questions is only reasonable if statement local > > references *look* different from regular variable names. But I also > think we > > need to proposing answering "No" to all of them to make statement locals > > potentially interesting enough to be worth considering. > > OK, that argument makes sense to me. At least in the sense that it > makes a good case for how statement-local names should work *if* we > adopt them. I reserve the right to change my mind, as I haven't > thought this through fully, but at least superficially I'm with you > this far. > > I will note that I don't see this as a compelling reason for *having* > them, just a good analysis of how they might behave if we do. > > > Neither PEP 527 nor 3150 *needs* the syntactic markers - the compiler can > > figure out what is going on because it does the symbol table analysis > pass > > before the code generation pass, and hence can tag names appropriately > based > > on what it finds. > > > > My concern is for people reading the code, where omitting a syntactic > marker > > also forces *humans* to read things in two passes to make sure they > > understand them correctly. Consider this example: > > > > x = 10 > > data = [x*x for i in range(10)] > > > > This will give you a 10 item list, where each item is 100. > > > > But now consider a world with statement locals, where statement locals > use > > the same reference syntax as regular locals: > > > > x = 10 > > data = [x*x for i in range(10) if (12 as x)] > > > > That's a deliberately pathological example (and you can already write > > something similarly misleading using the "for x in [12]" trick), but the > > fact remains that we allow out of order evaluation in expressions in a > way > > that we don't permit for statements. > > OK. That's my concern as well. But my conclusion is different - I view > this as a pretty strong argument that the complexity cost is too high > to justify the feature, rather than as a difficulty we need to > mitigate in order to make the feature usable. > > > With a syntactic marker though, there's typically going to be less > ambiguity > > about where a name comes from: > > > > x = 10 > > data = [.x*.x for i in range(10) if (12 as .x)] > > > > It's not a panacea (since you may still be shadowing a name from an outer > > statement), and adapting it for PEP 3150 isn't without it's problems > > (specifically, you need to allow ".x = 12" in the given clause to make > the > > names match up), but it should be less confusing than allowing a new > > subexpression to interfere with name resolution semantics folks have been > > relying on for years. > > On my screen right now, I can barely see the dots. That's in email > with a proportional font, so not "real coding", but it's surprising > (and somewhat depressing :-() to think that probably the majority of > code I read these days is in emails. > > So I don't think that this is a good enough fix to warrant making > Tim's screen look gritty. > > > If statement locals behave just like function locals, then there's no > reason > > to add them to the language in the first place - "(expr as name)" would > just > > become a confusing second way to spell "name = expr". > > Well, the whole reason this debate keeps coming up is because people > keep finding places they want to type "name = expr" but they can't, > because their context isn't a statement. We're basically trying to > design a replacement for "name = expr" that can be used in an > expression. And the status quo is "refactor your expression into > multiple statements". Doing so isn't always ideal (and particularly > grates on people coming from languages where assignments are > expressions, like C/C++) but it is always possible. > > Adding "mustn't just be another way to spell name = expr" to the > requirements is an extra requirement - and arguably one that > contradicts the original requirement which was "find a way to allow > name = expr in expressions". > > Designing a broader feature which solves the original problem is a > good goal, but we need to take care not to introduce scope creep or > over generalisation. In this case, IMO, we're not doing that (yet!) > but we are hitting design problems which are orthogonal to the > original requirement. > > > It's only potentially worthwhile if statement locals offer us something > that > > function locals don't, and the clearest potential candidate for that > > differentiation is to provide a greater level of assurance regarding > > locality of use than regular name binding operations do. > > I disagree. It's *still* potentially worthwhile if it just offers a > clean resolution for people who want to name complex sub-parts of a > comprehension. But the bar for "clean" in that case is higher, because > the benefit is pretty limited. I don't think it reaches that higher > bar, but I also am not sure that the benefits of the wider proposal > are sufficient to warrant the amount of lowering of the bar that is > needed. (That metaphor got way too strained. I hope it still made > sense). > > > >> I guess I remain -1 on the proposal, and nothing that's getting said > >> about how we can make it work is doing anything to persuade me > >> otherwise (quite the opposite). > > > > Yep, that's fair, as there are *lots* of viable alternatives to inline > > naming of subexpressions (each with various trade-offs). The question at > > hand is whether we can come up with semantics and syntax that folks > actually > > like well enough to put to python-dev for a yes/no decision, with the > pros > > and cons consolidated in one place. > > Precisely. > > And the usual proviso that "status quo wins" applies strongly here, > where (as noted in Chris' PEP) there are already *many* existing > solutions. > > Paul > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/