On 6/22/06, Phillip J. Eby <[EMAIL PROTECTED]> wrote: > >>[Phillip] > >>1. "case (literal|NAME)" is the syntax for equality testing -- you can't > >>use an arbitrary expression, not even a dotted name. > >[Guido] > >But dotted names are important! E.g. case re.DOTALL. And sometimes > >compile-time constant expressions are too. Example: case sys.maxint-1. > [Phillip] > True - but at least you *can* use them, with "from re import DOTALL" and > "maxint_less_1 = sys.maxint-1". You're just required to disambiguate > *when* the calculation of these values is to be performed.
Yeah, but the result is a quite crippled case expression that's not like anything in Python. > >>2. NAME, if used, must be bound at most once in its defining scope > > > >That's fine -- but doesn't extend to dotted names. > > Right, hence #1. Which I don't like. (I know, I'm repeating myself here. Better than contradicting myself. :-) > >>3. Dictionary optimization can occur only for literals and names not bound > >>in the local scope, others must use if-then. > > > >So this wouldn't be optimized?! > > > >NL = "\n" > >for line in sys.stdin: > > switch line: > > "abc\n": ... > > NL: ... > > This would result in a switch dictionary with "abc\n" in it, preceded by an > if line==NL test. So it's half-optimized. The more literals, the more > optimized. If you put the same switch in a function body, it becomes fully > optimized if the NL binding stays outside the function definition. That still seems really weird, especially if you consider the whole thing already being inside a def(). It would optimize references to non-locals but not references to locals...? > Note that you previously proposed a switch at top level not be optimized at > all, so this is an improvement over that. I don't particularly care about top-level switches; I don't expect they'll be used much and I don't expect people to care about their speed much. A for loop using some local variables is also quite slow outside a function; if anybody complains we just tell them to put it in a function. I do care about switch/case being easy to use and flexible in likely use cases, which include using constants defined in a different module. > >I like it better than const declarations, but I don't like it as much > >as the def-time-switch-freezing proposal; I find the limitiation to > >simple literals and names too restrictive, and there isn't anything > >else like that in Python. > > Well, you can't "def" a dotted name, but I realize this isn't a binding. You could have left that out of your email and we'd all have been happier. :-) > >I also don't like the possibility that it > >degenerates to if/elif. I like predictability. > > It is predictable: anything defined in the same scope will be if/elif, > anything defined outside will be dict-switched. But that's pretty subtle. I'd much rather see a rule that *effectively* rules out non-constant cases completely. IMO the def-time-switch-freeze proposal does this. > >I like to be able to switch on dotted names. > >Also, when using a set in a case, one should be able to use an > >expression like s1|s2 in a case. > > ...which then gets us back to the question of when the dots or "|" are > evaluated. My proposal forces you to make the evaluation time explicit, > visible, and unquestionably obvious in the source, rather than relying on > invisible knowledge about the function definition time. At the cost of more convoluted code. It means in many cases I'd probably continue to use if/elif chains because refactoring it into a switch is too much effort. Thereby relegating switch to something only used by speed freaks. While I want my switch to be fast, I don't want it to be a freak. > "First time use" is also a more visible approach, because it does not > contradict the user's assumption that evaluation takes place where the > expression appears. The "invisible" assumption is only that subsequent > execution will reuse the same expression results without recalculating them > -- it doesn't *move* the evaluation somewhere else. Have you made up your mind yet where the result of the first-time evaluated value should be stored? On the function object? That implies that it doesn't help for inner defs that are called only once per definition (like certain callback patterns). > I seem to recall that in general, Python prefers to evaluate expressions in > the order that they appear in source code, and that we try to preserve that > property as much as possible. Both the "names and literals only" and > "first-time use" approaches preserve that property; "function definition > time" does not. But first-time has the very big disadvantage IMO that there's no safeguard to warn you that the value is different on a subsequent execution -- you just get the old value without warning. > Of course, it's up to you to weigh the cost and benefit; I just wanted to > bring this one specific factor (transparency of the source) to your > attention. This whole "const" thread was just me trying to find another > approach besides "first-time use" that preserves that visibility property > for readers of the code. Summarizing our disagreement, I think you feel that freeze-on-first-use is most easily explained and understood while I feel that freeze-at-def-time is more robust. I'm not sure how to get past this point except by stating that you haven't convinced me... I think it's time to sit back and wait for someone else to weigh in with a new argument. -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com