3 ms·
Forgive my ignorance but how is this different from a switch statement? Besides the slightly different syntax, of course. Many modern languages interpret switch
by DrJokepu 17y ago
Forgive my ignorance but how is this different from a switch statement? Besides the slightly different syntax, of course. Many modern languages interpret switch statements as lookup tables. And that in compiled languages the lookup table is generated at compile time and this approach generates the lookup table at runtime, possibly wasting expensive CPU cycles.
Basically we're dealing here with a special set of condition-action pairs. The property that makes them special is that the conditions are mutually exclusive, that is, the order of condition checks is not important. Of course, most of the time, non-exclusive conditions can be restructured to exclusive conditions as long as the conditions checks themselves don't have side effects (that it, they don't modify the state). This is a solved problem in software construction. For binary conditions, you use if statements (or the equivalent in Your Favourite Language), for simple multiple conditions, you use a switch statement and for complex state-condition check you create a class/closure that takes the state and determines if the condition evaluates to true and then another function executes the action and then you loop through the condition checkers. We're talking about concepts that have been around for almost half a century. There's no need to reinvent the wheel. Instead, read some books and learn how developers solved these basic software construction problems in the past.
The problem is, many developers are too smart for their own good. They come up with new "design patterns" while ignoring the mountains of experience and knowledge past programmers have built up. More often than not these "groundshaking new ideas" lead to huge pains one way or other later down the codebase lifecycle. This is why C++ is so hard; you can come up with many "innovative" ways to do stuff only to discover a year later that your "innovation" made your codebase completely unmaintainable. Don't get me wrong, innovation is really cool and I support it but it doesn't hurt to consult the existing knowledge (either by research or asking more experienced developers) before going down your path.
- deleted 17y ago[deleted]
- barrkel 17y agoI think you are extrapolating too far from a simple example and losing sight of the non-essential complexity that a switch and if-statement based approach creates. I've been there; it doesn't work very well, IMHO.
- nostrademons 17y agoDispatch tables give you some additional flexibility. For example, say that you want to wrap each function with some statistic-gathering in debug mode. You could implement this easily with: if(DEBUG) { for(var key in actions) { actions[key] = wrapDebug(key, actions[key]); } } In a switch or nested if-else, you would need to include that debug processing inline with each alternative, instead of factoring it out into its own closure-generating function. Similarly, compilers often use this approach for instruction generation. The set of available machine instructions is stored as a table; if you move to a different architecture, you just replace the table with one appropriate to the new architecture. This is not a new idea. SICP has a whole section on data-directed programming, and MapReduce and many other internal bits of Google infrastructure use this extensively.
- DrJokepu 17y agoCompilers are special because their input/output data is code and instructions. However the code of the compiler itself is clearly separated from the code the compiler emits. When the compiler uses the lookup table to look up the code to emit it really looks up data for output and not code to be executed (right away).
- jfoutz 17y agoAnother cool trick is runtime rebinding. Context sensitive actions come to mind. s means save when editing, or s means stop when running. This is also a common way to let users remap keys, or build their own menus.
- bricestacey 17y agoEh, this isn't new and innovative. For more information, check out SICP: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-17.html#%_sec_2.4.3 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-17.html... Also, since the logic is stored in a lookup table, these can always be changed on the fly.
- DrJokepu 17y agoThat's exactly what I was talking about. That's why I put these word within quotation marks. Maybe it's just me but I don't really like the idea of changing code on the fly. It (a) makes code a lot harder to prove for correctness (b) a lot harder to debug. There are cases when it is a good idea in some very specific algorithms but in general development, I think self modifying code is a big no-no.
- derefr 17y agoWhat about cases where you basically want the user to specify the condition at runtime, with what amounts to a Turing-complete language for writing those conditions? In the Tivo example, pretend you wanted users to be able to go up to the device and say "only record shows where one of the lexicographical permutations of the length in minutes is a prime number." The only way to avoid it is not to avoid it: to create a user-extension language with its own compiler, and a VM embedded into the program.
- DrJokepu 17y agoOh yes allowing scripting is often an excellent feature, but I wouldn't consider a scripting interface "changing code at runtime". The boundaries of the application and the scripting environment are clearly defined most of the time. Scripting is more like receiving automated control input. Of course the JIT of the scripting language might have self modifying parts in it but that's not the point.
- fleitz 17y agoWhen did CPU cycles become expensive? Most available CPU cycles are wasted by the processor being idle. I know these numbers come from VM people who are talking their book but the oft quoted number even for servers is 5% CPU utilization. Due to the scoping rules in most imperative languages a look up table implemented in this manner will generally reduce the cyclomatic complexity of a method which is a major source of bugs, also you see this pattern implemented in most functional languages as a match statement. Most statements about performance are by people talking their own book. As for how this is different than a switch statement, you are failing to realize the importance of higher level concepts, do you use only NAND statements in your logic? (or the gate of your choice capable of implementing the other gates)
- DrJokepu 17y agoI've said "potentially expensive". Surely you must agree that while most of the time CPU cycles are indeed cheap in some applications (e.g. embedded systems or performance-critical loops) performance counts. How is this any higher level than a switch statement? The syntax is slightly different but how exactly it hides complexity with abstraction?