
On Thu, Oct 13, 2011 at 7:10 PM, Paul Moore <p.f.moore@gmail.com> wrote:
On 13 October 2011 09:14, Nick Coghlan <ncoghlan@gmail.com> wrote:
That's basically why I went with the leading ':' - it's jarring enough to get your attention, without being so ugly as to be intolerable. However, Georg's "this doesn't look like Python any more" criticism has serious merit - while style guidelines can mitigate that to some degree (just as they advise against gratuitous use of lambda expressions when a named function would be better), there's an inherent ugliness to the syntax in the first draft of the PEP that may make it irredeemable.
Personally, I find the leading ":" too light (to my ageing eyes :-)) so that it gets lost. Also, I am now trained by decorators to see lines starting with @ as "attached" to the following definition, in a way that other syntax isn't.
As an alternative bikeshed colour, would @: work rather than plain @?
I'm much happier with the keyword - "postdef" provides a strong hint to what it does, and also ties it in with the following function definition.
I already think there are two simplifying assumptions that should be made at least for the first iteration of the idea:
1. Leave classes out of it, at least for now. We did that with decorators, and I think it's a reasonable approach to follow.
While I don't disagree per se, I suspect that statement-local classes will be on the enhancement list from day 1 - the trick of using a class as a local namespace is just too compelling. So deferring that option may be a false economy.
It doesn't make a huge difference, as 'postdef' also works sufficiently well as the keyword for classes as well (since the class statement if more commonly known as a class definition). Including classes may nudge the forward reference syntax back towards the semantically neutral '@', though. The alternative would be to use 'def' for functions and 'class' for classes, which would be a little ugly.
2. The initial version should be an alternative to decorator syntax, not an addition to it. That is, you wouldn't be able to mix the first incarnation of a block prefix with ordinary decorators.
Agreed, and with this one I'm not sure it shouldn't stay a limitation forever. Mixing the two seems like a step too far. (And if you really need it, just call the decorator directly as part of the @: statement).
With an explicit keyword, mixing them may be OK, though. For decorator factories, the explicit calling syntax is a little clumsy.
That actually looks quite readable to me, and is fairly explicit about what it does: here's a piece of code to run after the following function has been defined. I definitely like it better than what I have in the PEP.
My instinct still prefers a form including a leading @, but I definitely like this better than the bare colon. And given that the "@ attaches to the next statement" instinct is learned behaviour, I'm sure I could learn to recognise something like this just as easily. I *don't* like using def to mark the placeholder, though - too easily lost.
It's easier to see with syntax highlighting, but yeah, I'm not as sold on the idea of using def for forward reference rather than '@' as I am on the switch from a bare colon to the postdef keyword.
With this variant, I would suggest that any postdef clause be executed *in addition* to the normal name binding. Colliding on dummy names like "func" would then be like colliding on loop variables like "i" - typically harmless, because you don't use the names outside the constructs that define them anyway.
I'm not sure why you feel that using a keyword implies that the binding behaviour should change - but as you say typically it's not likely to matter.
It's actually more that I wasn't entirely comfortable with suppressing the name binding in the first place and changing to a keyword really emphasised the "do the function definition as normal, but then run this extra piece of code afterwards" aspect. Exposing the function names by default can also help with testability of code that overuses the new construct.
- The @ as reference to the local function is mildly ugly, in a way that @ at the start of a line isn't. But I don't have any really good alternatives to offer (other than maybe a special name with double underscores, such as __this__, but I'm not convinced by that - hmm, what about a bare double underscore, __? Too "cute"?).
No, I think we want a symbol or a real keyword here. Getting too cute with names may actually make it harder to implement and understand rather than easier.
- Georg's point about this not looking like Python any more is good. I don't completely agree, and in particular I think that the semantics are sufficiently Pythonic, it's just the syntax that is jarring, but it *is* something to be careful of. Decorators felt much the same when they were introduced, though...
The leading colon to introduce the new clause was definitely far too cryptic, so I'm a lot happier with the explicit 'postdef' keyword idea. For the rest, I think it falls into the same category as lambda abuse - overusing the post definition clause would be a code smell, to be fought by the forces of style guides, code reviews and an emphasis on writing testable code. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia