On 6/25/06, Ka-Ping Yee <[EMAIL PROTECTED]> wrote: > On Sun, 25 Jun 2006, Guido van Rossum wrote: > > In your eagerness to > > rule out surprises, you're creating the biggest surprise of all: the > > restriction to literals is certainly a surprise! > > I disagree. Perhaps what we mean by "surprise" is different.
Apparently. I would find it very surprising if a language as dynamic as Python didn't allow expressions for cases. User learning a language generalize from examples. They see that expressions can be used whenever constants can be used. When they find that one particular context doesn't allow an expression, they will surely be surprised. I'm utterly unconvinced by Raymond's arguments for his proposal. Disallowing names goes against half a century of programming wisdom. Here's an argument for allowing names (this argument has been used successfully for using names instead of string literals in many APIs): if there is a spelling error in the string literal, the case will silently be ignored, and who knows when the bug is detected. If there is a spelling error in a NAME, however, the error will be caught as soon as it is evaluated. > In Raymond's design, there is a simple rule for what's allowed in a case. > The whole statement can be described in very few words: > > Each case is a literal integer, string, or tuple of integers > or strings. Execution jumps to the first case that matches the > value of the switch expression (or to 'default' if no match). > > That's it. The simpler the rule, the less surprising it is. It would > take a lot more words to explain the behaviour of something like Nick's > 'once'-based proposal. Here's an attempt: > > Each case consists of an arbitrary expression, but the expression > may not refer to any local variables or arguments of the immediately > surrounding function definition. The value of each case is computed > when the surrounding function definition is compiled. If any two > cases have the same value, an exception is thrown at compile time. > At runtime, execution jumps to the case whose previously fixed value > matches the value of the switch expression (or to 'default' if no > match). > > Not only is that longer to describe, it's also more difficult for a > beginning programmer to understand, since it requires knowing when > different parts of a program are compiled (and what happens if the > same part is compiled more than once). But beginning programmers don't read descriptions like that. They generalize from examples. It's the experts who need to have the complete unambiguous rules so they can know where the boundaries of safe code are. Beginners tend not to get near the boundaries at all. The experts can handle the unvarhished truth. (Hey, they can handle metaclasses. :-) Here's how I envision beginners learning about the switch statement (after they're utterly familiar with if/elif). We show them a few examples, some involving literals, some involving manifest constants (either defined locally at the module level, or imported). We give them *one* simple rule: "the cases must be run-time constants" (an intentionally vague term). Then let them loose. I expect that the results will be total satisfaction. I expect that the same approach should work for users who are beginning Python programmers but who are experienced in other languages (say, Java). The most likely problem a newbie will run into if they forget about the "cases must be constants" rule is trying to use a locally computed value as a case expression. This will most likely involve a local variable, and the proposed switch semantics specifically disallow these. So it'll be a compile time error -- better than most rookie mistakes! Yes, it's possible that someone has a global variable that really varies between function invocations, and they might use it in a switch. This will fail (give the wrong answer) silently (without an immediate error). But I think it's pretty unlikely that someone will try this -- they must not have been paying attention in two different classes: first when it was explained that variable globals are usually a bad idea; second when it was explained that switch cases must be (run-time) constants. Note that the entire class of well-known problems (which surprise almost every ne Python programmer at least once) that are due to one-time evaluation of mutable initializers (both parameter defaults and class variables) is ruled out here, by the requirement that switch cases be hashable, which in practice means immutable. Now, I'm not convinced that we need a switch statement. There are lots of considerations, and I sympathize with those folks who argue that Python doesn't need it. But I'd rather have no switch statement than Raymond's castrated proposal. -- --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