My ECMA Proposal : make switch useful

The Switch
The Switch

[update 2014 Nov 04]

Please read this post in conjunction with:  https://dbj.org/dbj-cond/

[end of update]

The other day on jQuery forum, I spotted a code like this one:
(first published 06JUN09)

jQuery('a').each(function(){
 switch(x) {
  case 1: $(this).css({ color:'blue'});
    break ;
  case 2: $(this).css({ color:'red'});
    break ;
  default : $(this).css({ color:'green'});
 }
});


Unfortunately, for some, this is “too many keystrokes” … And peculiarly (then very young and rushed) Mr B. Eich forgot to make a result of the switch available, so this was not possible in JavaScript:

//
var color =
switch(x) {
case   1: 'blue' ; break ;
case   2: 'red'  ;  break ;
default : 'green' ;
};
// above is or was an unexpected token error
// 2018JUL17 : "Unexpected token switch"
// in Chrome and Opera, "Syntax Error" in Edge
//

As far as JavaScript parsers (some of them) are concerned “switch” above is an “unexpected token” error.

Update 2017-10-24

For my browser this (of course) is no longer the case and switch behaves as it should do.  My browser user agent string is this:

navigator.userAgent

"Mozilla/5.0 
(Windows NT 10.0; WOW64) 
AppleWebKit/537.36 
(KHTML, like Gecko) 
Chrome/59.0.3071.86 
Safari/537.36"

Back to distant past. Added peculiarity is that the following code parses OK,

var x = 2 ;
switch(x) {
case   1: 'blue' ; break ;
case   2: 'red'  ;  break ;
default : 'green' ;
};

The latest statement is the switch and it returns “red”, indeed. And yes You are free to try and “give it” to the return statement. That might not work too.

var x = 2 ;
function swtch(x) {
// this might be an
// "unexpected token error"
   return switch(x) {
   case   1: 'blue' ; break ;
   case   2: 'red'; break ;
   default : 'green' ;
 };
}
//

One roundabout way is to get to the return value of the switch, with eval(), like this :

var color =
 eval(
 'switch(x){'
+ 'case 1: "blue"; break;'
+' case 2: "red"; break;'
+' default: "green" } '
 ) ;
//
// this works
// but is almost useless
// as a solution
//

The issue is that switch; statement, after all, returns the value, but it is not a legal ‘rvalue’ in some JavaScript engines. At the moment. The eval() trick is not very useful and looks somewhat dodgy. So some developers have concluded they “must help” everyone with the function similar to this:

//
//return the value if x matches the case
//case and value must be in pairs
//the last argument if given is the default value
//
//cond( input,
//  case1, value1,
//  case2, value2,
//  ..... ,
//  otherwise_value )
//
//example :
//
cond( x, 1, "blue", 2, "red", /*otherwise*/ "green" ) ;
//

It has to be said that this is directly inspired by the LISP (COND …) construct. And, by now the excitement in the forum is high indeed because one can safely write this:

$(this).css({ color:
   cond( x,
         1,"blue",
         2,"red",
/*otherwise*/ "green"
} ) ;

Also much cleaner and shorter than the very first snippet in this post. Quick and dirty, and very workable, cond function is this:

//last argument is default value
function cond( v ) {
    var j = 1 ;
    for ( ; j < arguments.length; j+=2 ) {
       if ( cond.cond(v,arguments[j]) )
           return arguments[j+1];
    }
    return (!arguments[j-2])
        ? undefined
        : arguments[j-2] ;
}
// allow users to change the condition
// operator used to match the value given
// default condition is 'deep equality',
// aka 'exact match'
cond.cond= function (a,b) { return (a) === (b) ; }

Example usage:

cond( 1, 2, "apples", 1, "pears", "none" )
/*
returns: "pears"
*/

For some, this is “Awesome”, while for others this is “obfuscation”. Personally, I like it but I vote for ECMA to simply allow assignment with the ‘switch’ statement to be a legal “rvalue”. That is: make the return value of the switch statement available for assignment:

//My ECMA proposal
var color = switch(x) {
  case 1: "blue"; break;
  case 2: "red";  break;
  default: "green"
} ;
//make this possible
//by making switch act as an rvalue too

Although. (It has to be said) I rather like cond() and I think it delivers much more readable robust code. Thus I have added this for everyone to use, to the NPM in the form of dbj.cond() .

Enjoy
–DBJ

Update 2010.Jan.10

Ben Alman made this idea into a useful jQuery plugin, here: http://benalman.com/projects/jquery-cond-plugin/

8 thoughts on “My ECMA Proposal : make switch useful”

Comments are closed.