changing switch/case to switch/when -- it's a better word

This commit is contained in:
Jeremy Ashkenas 2009-12-24 01:33:59 -08:00
parent 849f0e4192
commit 8d76f4bd3f
13 changed files with 85 additions and 38 deletions

View File

@ -3,3 +3,5 @@ launch() if ignition is on
volume: 10 if band aint spinal_tap
let_the_wild_rumpus_begin() unless answer is no
if car.speed < speed_limit then accelerate().

View File

@ -1,9 +1,9 @@
switch day
case "Tuesday" then eat_breakfast()
case "Wednesday" then go_to_the_park()
case "Saturday"
when "Tuesday" then eat_breakfast()
when "Wednesday" then go_to_the_park()
when "Saturday"
if day is bingo_day
go_to_bingo()
go_dancing().
case "Sunday" then go_to_church()
when "Sunday" then go_to_church()
else go_to_work().

View File

@ -69,7 +69,7 @@
<a href="#slice">Array Slice Literals</a><br />
<a href="#super">Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/Case/Else</a><br />
<a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br />
<a href="#strings">Multiline Strings</a><br />
<a href="#change_log">Change Log</a><br />
@ -278,6 +278,11 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<p>
You can use <tt>not</tt> as an alias for <tt>!</tt>.
</p>
<p>
Instead of a newline or semicolon, <tt>then</tt> can be used to separate
conditions from expressions, in <b>while</b>,
<b>if</b>/<b>else</b>, and <b>switch</b>/<b>when</b> statements.
</p>
<p>
As in <a href="http://yaml.org/">YAML</a>, <tt>on</tt> and <tt>yes</tt>
are the same as boolean <tt>true</tt>, while <tt>off</tt> and <tt>no</tt> are boolean <tt>false</tt>.
@ -343,15 +348,14 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<%= code_for('embedded', 'hi()') %>
<p id="switch">
<b class="header">Switch/Case/Else</b>
<b class="header">Switch/When/Else</b>
<b>Switch</b> statements in JavaScript are rather broken. You can only
do comparisons based on string equality, and need to remember to <b>break</b> at the end of
every <b>case</b> statement to avoid accidentally falling through to
the default case. CoffeeScript
compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
the default case. CoffeeScript compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
compare any object (via <b>===</b>), preventing fall-through, and resulting
in a returnable, assignable expression. To specify the default case, just
use <tt>else</tt>.
in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
<tt>when</tt> clauses, <tt>else</tt> the default case.
</p>
<%= code_for('switch') %>

View File

@ -9,4 +9,5 @@
if (!(answer === false)) {
let_the_wild_rumpus_begin();
}
car.speed < speed_limit ? accelerate() : null;
})();

View File

@ -6,6 +6,7 @@
};
var Snake = function(name) {
this.name = name;
return this.name;
};
Snake.prototype = new Animal();
Snake.prototype.move = function() {
@ -14,6 +15,7 @@
};
var Horse = function(name) {
this.name = name;
return this.name;
};
Horse.prototype = new Animal();
Horse.prototype.move = function() {

View File

@ -115,10 +115,10 @@ drink(bottle) for bottle, i in ['soda', 'wine', 'lemonade'] if even(i).
# Switch statements ("else" serves as a default).
activity: switch day
case "Tuesday" then eat_breakfast()
case "Sunday" then go_to_church()
case "Saturday" then go_to_the_park()
case "Wednesday"
when "Tuesday" then eat_breakfast()
when "Sunday" then go_to_church()
when "Saturday" then go_to_the_park()
when "Wednesday"
if day is bingo_day
go_to_bingo()
else

View File

@ -55,7 +55,7 @@
<a href="#slice">Array Slice Literals</a><br />
<a href="#super">Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/Case/Else</a><br />
<a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br />
<a href="#strings">Multiline Strings</a><br />
<a href="#change_log">Change Log</a><br />
@ -453,6 +453,11 @@ var eldest = 24 > 21 ? "Liz" : "Ike";
<p>
You can use <tt>not</tt> as an alias for <tt>!</tt>.
</p>
<p>
Instead of a newline or semicolon, <tt>then</tt> can be used to separate
conditions from expressions, in <b>while</b>,
<b>if</b>/<b>else</b>, and <b>switch</b>/<b>when</b> statements.
</p>
<p>
As in <a href="http://yaml.org/">YAML</a>, <tt>on</tt> and <tt>yes</tt>
are the same as boolean <tt>true</tt>, while <tt>off</tt> and <tt>no</tt> are boolean <tt>false</tt>.
@ -465,6 +470,8 @@ var eldest = 24 > 21 ? "Liz" : "Ike";
volume<span class="Keyword">:</span> <span class="Number">10</span> <span class="Keyword">if</span> band <span class="Keyword">aint</span> spinal_tap
let_the_wild_rumpus_begin() <span class="Keyword">unless</span> answer <span class="Keyword">is</span> <span class="BuiltInConstant">no</span>
<span class="Keyword">if</span> car.speed <span class="Keyword">&lt;</span> speed_limit <span class="Keyword">then</span> accelerate().
</pre><pre class="idle"><span class="Keyword">if</span> (ignition <span class="Keyword">===</span> <span class="BuiltInConstant">true</span>) {
launch();
}
@ -475,6 +482,7 @@ let_the_wild_rumpus_begin() <span class="Keyword">unless</span> answer <span cla
<span class="Keyword">if</span> (<span class="Keyword">!</span>(answer <span class="Keyword">===</span> <span class="BuiltInConstant">false</span>)) {
let_the_wild_rumpus_begin();
}
car.speed <span class="Keyword">&lt;</span> speed_limit ? accelerate() : <span class="BuiltInConstant">null</span>;
</pre><br class='clear' /></div>
<p id="while">
@ -595,6 +603,7 @@ tom.move()
};
<span class="Storage">var</span> <span class="FunctionName">Snake</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name;
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">name</span>;
};
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>();
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
@ -603,6 +612,7 @@ tom.move()
};
<span class="Storage">var</span> <span class="FunctionName">Horse</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name;
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">name</span>;
};
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>();
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
@ -620,6 +630,7 @@ Animal.prototype.move = function(meters) {
};
var Snake = function(name) {
this.name = name;
return this.name;
};
Snake.prototype = new Animal();
Snake.prototype.move = function() {
@ -628,6 +639,7 @@ Snake.prototype.move = function() {
};
var Horse = function(name) {
this.name = name;
return this.name;
};
Horse.prototype = new Animal();
Horse.prototype.move = function() {
@ -658,24 +670,23 @@ return [document.title, "Hello JavaScript"].join(": ");
;alert(hi());'>run: hi()</button><br class='clear' /></div>
<p id="switch">
<b class="header">Switch/Case/Else</b>
<b class="header">Switch/When/Else</b>
<b>Switch</b> statements in JavaScript are rather broken. You can only
do comparisons based on string equality, and need to remember to <b>break</b> at the end of
every <b>case</b> statement to avoid accidentally falling through to
the default case. CoffeeScript
compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
the default case. CoffeeScript compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
compare any object (via <b>===</b>), preventing fall-through, and resulting
in a returnable, assignable expression. To specify the default case, just
use <tt>else</tt>.
in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
<tt>when</tt> clauses, <tt>else</tt> the default case.
</p>
<div class='code'><pre class="idle"><span class="Keyword">switch</span> day
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Tuesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> eat_breakfast()
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Wednesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_the_park()
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Saturday<span class="String">&quot;</span></span>
when <span class="String"><span class="String">&quot;</span>Tuesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> eat_breakfast()
when <span class="String"><span class="String">&quot;</span>Wednesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_the_park()
when <span class="String"><span class="String">&quot;</span>Saturday<span class="String">&quot;</span></span>
<span class="Keyword">if</span> day <span class="Keyword">is</span> bingo_day
go_to_bingo()
go_dancing().
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Sunday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_church()
when <span class="String"><span class="String">&quot;</span>Sunday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_church()
<span class="Keyword">else</span> go_to_work().
</pre><pre class="idle"><span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>Tuesday<span class="String">&quot;</span></span>) {
eat_breakfast();

View File

@ -205,7 +205,7 @@
</dict>
<dict>
<key>match</key>
<string>\b(break|case|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|while)\b</string>
<string>\b(break|when|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|while)\b</string>
<key>name</key>
<string>keyword.control.cs</string>
</dict>

View File

@ -9,7 +9,7 @@ token CODE PARAM NEW RETURN
token TRY CATCH FINALLY THROW
token BREAK CONTINUE
token FOR IN WHILE
token SWITCH CASE
token SWITCH WHEN
token SUPER
token DELETE
token NEWLINE
@ -320,23 +320,23 @@ rule
IF Expression "." { result = ForNode.new(val[0], val[6], val[2], val[8], val[4]) }
;
# Switch/Case blocks.
# Switch/When blocks.
Switch:
SWITCH Expression Then
Cases "." { result = val[3].rewrite_condition(val[1]) }
Whens "." { result = val[3].rewrite_condition(val[1]) }
| SWITCH Expression Then
Cases ELSE Expressions "." { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
Whens ELSE Expressions "." { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
;
# The inner list of cases.
Cases:
Case { result = val[0] }
| Cases Case { result = val[0] << val[1] }
# The inner list of whens.
Whens:
When { result = val[0] }
| Whens When { result = val[0] << val[1] }
;
# An individual case.
Case:
CASE Expression Then Expressions { result = IfNode.new(val[1], val[3]) }
# An individual when.
When:
WHEN Expression Then Expressions { result = IfNode.new(val[1], val[3]) }
;
# All of the following nutso if-else destructuring is to make the

View File

@ -13,7 +13,7 @@ module CoffeeScript
"try", "catch", "finally", "throw",
"break", "continue",
"for", "in", "while",
"switch", "case",
"switch", "when",
"super",
"delete"]

View File

@ -594,7 +594,7 @@ module CoffeeScript
end
end
# If/else statements. Switch/cases get compiled into these. Acts as an
# If/else statements. Switch/whens get compiled into these. Acts as an
# expression by pushing down requested returns to the expression bodies.
# Single-expression IfNodes are compiled into ternary operators if possible,
# because ternaries are first-class returnable assignable expressions.

11
test/fixtures/execution/test_switch.cs vendored Normal file
View File

@ -0,0 +1,11 @@
num: 10
result: switch num
when 5 then false
when 'a'
false
when 10 then true
when 11 then false
else false.
print(result)

16
test/fixtures/execution/test_switch.js vendored Normal file
View File

@ -0,0 +1,16 @@
(function(){
var num = 10;
var result;
if (num === 5) {
result = false;
} else if (num === 'a') {
result = false;
} else if (num === 10) {
result = true;
} else if (num === 11) {
result = false;
} else {
result = false;
}
print(result);
})();