Depends if you're in an environment you control then yes - when embedding your scripts, don't do it. Create your own isolated functions and assume anything and everything can be broken e.g. Array.prototype is often modified with broken or semi incomplete functions like broken versions of indexOf
It's just a way of getting rid of the redundant "function()" syntax. Unfortunately with bind(), we have to set the scope even though it isn't always necessary. So in this case, the first parameter "this" is also probably redundant. The old PrototypeJS curry() would have been the least redundant solution:
movePlayer.curry("north")
While this can be a useful construct when you are doing meta-programming, this particular example is horrible. It's not much more readable (would be less readable in an 80x24 terminal window), and now you have an extra object sitting in memory for the lifetime of your application. If you only have a handful of options, just use switch.
The example definitely leaves a bit to be desired.
One great story for why this way might be better is that with a small tweak (to allow dynamic [de]registration of command functions) it is much more open to extension.
To continue using the somewhat creaky "text game" example, if possessing certain items or being in a particular room affects the available command set, this can be easily included: without a magic feather, "fly" returns "You don't know how to do that" but when you pick up said feather a new action is registered, and now "fly" works properly.
Now, I'm not sure I'd implement this particular game that way, but such an interface tends to be useful for building plugin systems, etc.
It's mainly for this reason that large switch statements, particularly those not doing "math" of some sort, tend to be a code smell.[1]
This is probably the part I dislike most about ruby (I know this is JS). There are some places where this trick makes a painful piece of code go away, so I appreciate why it was selected. The problem is that you now have no reference to draw_checkbox being used in your entire code base and when someone else is refactoring, they think they can remove it.
Personally, I would never elect to go this route because it only introduces overhead for refactoring and code maintenance. I would rather see a mess of procedural code, than some silly clever little tricks that will trip up all the new people.
Actually my code ends up looking pretty much like yours. I use CoffeeScript and was writing a simplified JS equivalent off the top of my head since this post was about JS. Similar to your Renderer, I have a DrawForm class that iterates through DrawField class objects which provide the checkbox(), radio() etc. methods.
My point was that in the end, you get to do dynamic function instantiation, which is pretty awesome in JS.
I'd prefer to see the functions put in a dictionary and invoked from there rather than named individually in the local scope, easier to see at least what you have to look for when you want to see if they're referenced, and you'd have dict[item] rather than "dict" + item.
Edit: taf2's seems more idiomatic, js is not my first language.
"Dispatch table"? I'm surprised everything in programming has a name associated with it. I just called these Javascript objects representing a map of functions...
Indeed, it's quite idiomatic. I would have still preferred if there was a switch/case construct that would generate a dispatch table for us (in fact, this was proposed and rejected in pep 3103[1]). A case statement would have been a nice, little addition to the expressiveness of Python, but it's not that big of a deal.
Here's another dispatch table technique that I really like[2].
Is it just me, or for this example does the "dispatch table" seem way more complex (and likely less efficient) than the switch statement? The original is not difficult at all to interpret.
The dispatch table is shorter than the switch, so there is a lot less noise. The invocation is a little clever, but overall I would consider them about equally complex. Maybe you meant unconventional?
One thing I really like about dispatch tables is that it forces the developer to only be able to handle the decision logic. The number of times I've had to cleanup a switch with 20-30 lines under each condition (sometimes including another switch) is too many to count.
> The performance is substantially different. The dispatch table is ~75% slower (in chrome).
Of course those are, they're doing very different things in that test case. Your first case is just returning a value, and the second is executing a function to return a value. Here's a better comparison, http://jsperf.com/switchvsdispatchtable/2
There's nothing inherently slow about dispatch tables, it all about how you implement them. As someone else mentioned, the OP should be using bind to reduce the # of function calls instead of executing a function which executes a function.
Yes it is just you. :) The original becomes horrible when the number of cases grows, when you want a default and can introduce subtle bugs if you forget a break. In the second example, there is a clean separation between processing commands and dispatching on the input. For example, you might want to extend processUserInput with "invalid command" handling, commands with arguments or even add commandTable as an argument to it so that you can reuse it for all your dispatching needs.
And to top it of, you can dynamically add new commands to the dispatch table which you can't to a switch.
I'd like to see you hunt for the dynamically added case to the dispatch table. Maybe then, you'll change your mind.
There is no fundamental difference between either approaches except the runtime cost. If you need conditonals, use them. If you need a lookup table, use them. Keep the code predictable.
It depends, sometimes if you have a few different context e.g. multiple click handlers that are being bound in different contexts of your app, that a table makes a lot more sense then repeating the switch or even wrapping the switch in a function...
I think the real win with a technique like this is that, if you store the bindings in a place that is globally accessible, it is open to extension.
For example, if a JSON library author implemented an encode(object) function using a dispatch table holding a set of object-type/JSON-encoding-function pairs, a client could extend the encode function by registering additional object-type/JSON-encoding-function pairs in the dispatch table.
Edit:
Furthermore, I believe this is how clojure protocols work - when a new type participates in a protocol, the type-specific function implementation gets added to a dispatch table keyed on the datatype's java Class. Then, anytime you invoke the function, the class of the first argument is identified and the corresponding type-specific function is pulled out of the dispatch table based on the class.
You have to be careful when doing this type of stuff. For instance, the switch case is actually doing both validation and switching, where as the dispatch table does no validation.
Consider:
processUserInput('toString');
That has very different behavior in the two different styles.
I don't know, in this case, with a bit of reformatting the switch can look pretty similar:
function processUserInput(command) {
switch (command) {
case "north": movePlayer("north"); break;
case "east": movePlayer("east"); break;
case "south": movePlayer("south"); break;
case "west": movePlayer("west"); break;
case "look": describeLocation(); break;
case "backpack": showBackpack(); break;
}
}
Although that's to be expected, a switch on a string value isn't that much different to a string lookup in an associative array.
I've done something similar in my form-validation library. I have a function that has three inputs that basically end up behaving like flags. So there are 8 possibilities in total. I ended up creating a function that would return a three-bit binary number based on the inputs, and I also created a jump-table that maps the three-bit binary values to specific handlers.
This example is great to point out that javascript is a dynamic language and should be used as such whenever possible. obviously he only used a handful of options and maybe a switch would work better for this exact example, but it should get the reader thinking about where else this type of pattern could be used.
For more complicated scenarios (where you find yourself making trees of conditionals), I suggest reading up on finite state machines, and for js checkout machina:
I'm guessing its just not a common thing to have a large definition of single line if statements, I'm not sure about other programmers but I don't think I could find much of this in my code.
I don't see the benefit.
it really is just a disguised switch statement,
unless you do something more dynamic with the mapping between the command name and the function to call...
so something like:
becomes: or using underscore.js(for greater browser compatibility):