PEP 3150 (statement local namespaces) updated based on April discussion
The rationale and proposed semantics sections of PEP 3150 have been heavily modified based on the various discussions on the topic back in April. http://www.python.org/dev/peps/pep-3150/ (Note that the PEP is still officially Deferred - this entire idea still intrigues me, but I'm also still not convinced it's worth the additional language complexity). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Nick Coghlan dixit (2011-06-13, 01:44):
The rationale and proposed semantics sections of PEP 3150 have been heavily modified based on the various discussions on the topic back in April.
http://www.python.org/dev/peps/pep-3150/
(Note that the PEP is still officially Deferred - this entire idea still intrigues me, but I'm also still not convinced it's worth the additional language complexity).
Still +3 from me for PEP 3150 :) *j
On 6/12/2011 11:44 AM, Nick Coghlan wrote:
The rationale and proposed semantics sections of PEP 3150 have been heavily modified based on the various discussions on the topic back in April.
http://www.python.org/dev/peps/pep-3150/
(Note that the PEP is still officially Deferred - this entire idea still intrigues me, but I'm also still not convinced it's worth the additional language complexity).
I tried to read this with an open mind, but I still strongly dislike it. I think it would make Python harder to learn and read and would lead to more confusion and questions on python-list. I think having a different rule for function compilation makes the proposal even worse, as people would come to expect early binding (outside the given context) even more than now. If one does not like default args, one can either use class instances or closures. The latter were explicitly introduced as an alternative to using default args. Do we really need a fourth solution to the same problem? I do not see comprehensions, which are *expressions*, as a precedent for out-of-order *statements*. Nested expressions are not left-to-right either, nor are assignments: "a[3] = b*f(c+d)". 'Given' or 'where' constructs are sometimes used in mathematical writings, especially formula exposition, but they typically, if not always, are isolated (like the examples in the PEP), and not part of a code sequence. So this is notreally a precedent to me. Example: fv = p * (1 + i/12)**t... , where fv = present value p = principle i = nominal annual interest rate t = time in months -(1+whatever) -- Terry Jan Reedy
On Sun, Jun 12, 2011 at 2:20 PM, Terry Reedy <tjreedy@udel.edu> wrote:
On 6/12/2011 11:44 AM, Nick Coghlan wrote:
The rationale and proposed semantics sections of PEP 3150 have been heavily modified based on the various discussions on the topic back in April.
http://www.python.org/dev/peps/pep-3150/
(Note that the PEP is still officially Deferred - this entire idea still intrigues me, but I'm also still not convinced it's worth the additional language complexity).
I tried to read this with an open mind, but I still strongly dislike it. I think it would make Python harder to learn and read and would lead to more confusion and questions on python-list.
I think having a different rule for function compilation makes the proposal even worse, as people would come to expect early binding (outside the given context) even more than now. If one does not like default args, one can either use class instances or closures. The latter were explicitly introduced as an alternative to using default args. Do we really need a fourth solution to the same problem?
I do not see comprehensions, which are *expressions*, as a precedent for out-of-order *statements*. Nested expressions are not left-to-right either, nor are assignments: "a[3] = b*f(c+d)".
'Given' or 'where' constructs are sometimes used in mathematical writings, especially formula exposition, but they typically, if not always, are isolated (like the examples in the PEP), and not part of a code sequence. So this is notreally a precedent to me. Example:
fv = p * (1 + i/12)**t... , where fv = present value p = principle i = nominal annual interest rate t = time in months
-(1+whatever)
I've historically been in favor of this kind of proposal specifically because I'd like to be able to write the above code, but I have to admit that many of the examples given in the PEP terrify me. The point of exposition like this is to enhance readability by making the flow of information (defined by the equation on the first line) extremely clear; tucking functions and classes with their own flow into the out-of-order block just makes it really hard to figure out what's happening where and when. Geremy Condra
On 6/13/2011 12:59 PM, geremy condra wrote:
On Sun, Jun 12, 2011 at 2:20 PM, Terry Reedy<tjreedy@udel.edu> wrote:
'Given' or 'where' constructs are sometimes used in mathematical writings, especially formula exposition, but they typically, if not always, are isolated (like the examples in the PEP), and not part of a code sequence. So this is notreally a precedent to me. Example:
fv = p * (1 + i/12)**t... , where fv = present value p = principle i = nominal annual interest rate t = time in months
-(1+whatever)
I've historically been in favor of this kind of proposal specifically because I'd like to be able to write the above code,
Part of my point is that the above is not *code* (and hence not an argument for formatting code that way). It is a text definition. Someone who wrote something like the above might very well then write a *code* version the equivalent of p = input("principle: ") i = input("nominal annual interest rate: ") t = input("time in months: ") print("Future value of ${} at {}% after {} months is ${}" .format(p, i, t, p*(1+i/12)**t
but I have to admit that many of the examples given in the PEP terrify me. The point of exposition like this is to enhance readability by making the flow of information (defined by the equation on the first line) extremely clear; tucking functions and classes with their own flow into the out-of-order block just makes it really hard to figure out what's happening where and when.
I obviously agree with all this. -- Terry Jan Reedy
On Mon, Jun 13, 2011 at 1:09 PM, Terry Reedy <tjreedy@udel.edu> wrote:
On 6/13/2011 12:59 PM, geremy condra wrote:
On Sun, Jun 12, 2011 at 2:20 PM, Terry Reedy<tjreedy@udel.edu> wrote:
'Given' or 'where' constructs are sometimes used in mathematical writings, especially formula exposition, but they typically, if not always, are isolated (like the examples in the PEP), and not part of a code sequence. So this is notreally a precedent to me. Example:
fv = p * (1 + i/12)**t... , where fv = present value p = principle i = nominal annual interest rate t = time in months
-(1+whatever)
I've historically been in favor of this kind of proposal specifically because I'd like to be able to write the above code,
Part of my point is that the above is not *code* (and hence not an argument for formatting code that way). It is a text definition. Someone who wrote something like the above might very well then write a *code* version the equivalent of
p = input("principle: ") i = input("nominal annual interest rate: ") t = input("time in months: ") print("Future value of ${} at {}% after {} months is ${}" .format(p, i, t, p*(1+i/12)**t
Meh, semantics. I could, hypothetically, write the following: y = sqrt(z**2 + x**2) given: z = get_adjacent_side_length() x = get_opposite_side_length() and in terms of exposition style it would be basically the same as what you put up earlier, and is (to me) more readable than: z = get_adjacent_side_length() x = get_opposite_side_length() y = sqrt(z**2 + x**2) for the same reasons. The question is whether the (admittedly arguable) gain in readability offered in situations like this is worth the extra complexity of implementation and the risk of seeing code like the examples from the PEP in practice. Also, just to make sure I'm being clear- Nick, I'm not trying to bash your code. I just think that right now this lends itself to some really hard-to-understand constructions. Geremy Condra Geremy Condra
On Tue, Jun 14, 2011 at 6:37 AM, geremy condra <debatem1@gmail.com> wrote:
Also, just to make sure I'm being clear- Nick, I'm not trying to bash your code. I just think that right now this lends itself to some really hard-to-understand constructions.
There's a reason PEP 3150 has two sections ("PEP Deferral" and "Key Concern") devoted to explaining why it's current state is Deferred rather than Draft. When *I'm* not convinced it's a good idea, I'm not at all inclined to take offense when people see serious problems with the concept :) With PEP 343, we managed to find a sweet spot that allowed a great deal of flexibility without unduly encouraging obfuscated code. I've yet to find a similar sweet spot with PEP 3150 or related ideas. I feel there's a seed of a useful concept in there somewhere, but mostly it just creates two ways to do too many things. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Terry Reedy wrote:
Part of my point is that the above is not *code* (and hence not an argument for formatting code that way).
A couple of things about that: 1) Mathematicians often write things informally that, in a program, would need to be spelled out formally in code. They get away with it because they're writing for humans, not computers. 2) Very often they *do* write out the subsequently-defined terms formally. I came across an example just the other day. From "Elementary Numerical Analysis, an Algorithmic Approach" by Samuel D. Conte and Carl de Boor, 3rd edition, page 364: <quote> Runge-Kutta method of order 4: y[n+1] = y[n] + (1/6) * (k1 + 2*k2 + 2*k3 + k4) where k1 = h*f(x[n], y[n]) k2 = h*f(x[n + h/2], y[n] + k1 / 2) k3 = h*f(x[n + h/2], y[n] + k2 / 2) k4 = h*f(x[n], y[n] + k3) </quote> -- Greg
Greg Ewing writes:
2) Very often [mathematicians] *do* write out the subsequently-defined terms formally.
It strikes me that this is just the tension between the declarative style of coding, and the imperative style of doing the same thing. *The same code ends up being written* (modulo a bit of syntactic sugar like "where:" or "given:"), just the statement order is permuted. I have nothing against the declarative style. But at least for these simple examples including this syntax in Python violates TOOWTDI, and my experience in Lisp is that indeed the extra flexibility hinders readability because whichever style one personally favors, lots of folks use the other one. Python already allows you to (verbosely) use this style, anyway. def behavior_of_experimental_subject (subject): def behavior(now, later): return now + later now = subject.randomness() later = subject.perversity() return behavior(now, later) My feeling here is that if the declarative order is not sufficiently important to justify the local function and the extra return statement, using the imperative order won't be that costly in readability terms.
There are some bugs in the code example in the PEP's section "Detailed Semantics #1: Early Binding of Variable References": There is: assert seq == ... ...and should be: assert map(lambda x: x(), seq) == ... (3 times) There is: def f(_i=i): return i ...and should be: def f(_i=i): return _i Cheers. *j
participants (6)
-
geremy condra
-
Greg Ewing
-
Jan Kaliszewski
-
Nick Coghlan
-
Stephen J. Turnbull
-
Terry Reedy