Just a few odd comments... mal> The current solution to this problem lies in using a dispatch mal> table to find the case implementing method to execute depending on mal> the value of the switch variable (this can be tuned to have a mal> complexity of O(1) on average, e.g. by using perfect hash mal> tables). This works well for state machines which require complex mal> and lengthy processing in the different case methods. It does should be "does not" mal> perform well for ones which only process one or two instructions mal> per case, e.g. ... mal> The first solution has the benefit of not relying on new keywords either "not requiring new" or "not relying on adding new" mal> to the language, while the second looks cleaner. Both involve some mal> run-time overhead to assure that the switching variable is mal> immutable and hashable. ... mal> The new optimization should not change the current Python mal> semantics (by reducing the number of __cmp__ calls and adding mal> __hash__ calls in if-elif-else constructs which are affected mal> by the optimiztation). To assure this, switching can only mal> safely be implemented either if a "from __future__" style mal> flag is used, or the switching variable is one of the builtin mal> immutable types: int, float, string, unicode, etc. and not an instance of a subclass of any of them. (I think that's implied by your text, but should be explicitly stated.) mal> To prevent post-modifications of the jump-table dictionary mal> (which could be used to reach protected code), the jump-table mal> will have to be a read-only type (e.g. a read-only mal> dictionary). There was discussion once upon a time about adding a read-write flag to dictionaries to prevent modification during sensitive times. I gather lists already have such a flag to allow in-place sorting to work. ... mal> It should be possible for the compiler to detect an mal> if-elif-else construct which has the following signature: mal> if x == 'first':... mal> elif x == 'second':... mal> else:... mal> (ie. the left hand side alwys references the same variable, mal> the right hand side some hashable immutable builtin type) I don't think it is required that the right-hand sides all be of the same type. Perhaps it would be worthwhile to mention this and illustrate with an example. (Odd usage, perhaps, but still agrees with the desired constrains I think.) mal> The compiler could then setup a read-only (perfect) hash mal> table, store it in the constants and add an opcode SWITCH mal> which triggers the following run-time behaviour: I think it would be sufficient to use a read-only dictionary. Perfect has tables are fine, but who wants to implement one? mal> At runtime, SWITCH would check x for being one of the mal> well-known immutable types (strings, unicode, numbers) and mal> use the hash table for finding the right opcode snippet. And if one of the constraints isn't met, it would simply jump to the original if/elif/else code? ... mal> The compiler would have to generate code similar to this: should be "would have to compile" or "would have to convert" ... mal> Issues: mal> There have been other proposals for the syntax which reuse mal> existing keywords and avoid adding two new ones ("switch" and mal> "case"). Here's a wacky idea (probably wouldn't work syntactically, but hey, you never know): if EXPR: == CONSTANT: suite == CONSTANT: suite == CONSTANT: suite else: suite No new keywords, but I suspect the compiler would have to look too far ahead to realise that it's not compiling a regular if statement. BTW, do you mean for your "suite"s to be optional? Here are some concrete examples using each syntax variant switch EXPR: switch x: case CONSTANT: case "first": [suite] print x case CONSTANT: case "second": [suite] x = x**2 ... print x else: else: [suite] print "whoops!" case EXPR: case x: of CONSTANT: of "first": [suite] print x of CONSTANT: of "second": [suite] print x**2 else: else: [suite] print "whoops!" case EXPR: case state: if CONSTANT: if "first": [suite] state = "second" if CONSTANT: if "second": [suite] state = "third" else: else: [suite] state = "first" when EXPR: when state: in CONSTANT_TUPLE: in ("first", "second"): [suite] print state in CONSTANT_TUPLE: state = next_state(state) [suite] in ("seventh",): ... print "done" else: break # out of loop! [suite] else: print "middle state" state = next_state(state) If you allow the suites to be optional (except in the else?), I think you can avoid the need for tuples without parens in the case clauses. For example: when state: in "first": in "second": print state state = next_state(state) in "seventh": print "done" break else: print "middle state" state = next_state(state) Skip
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4