jashkenas--coffeescript/documentation/index.html.erb

224 lines
8.6 KiB
Plaintext
Raw Normal View History

2009-12-21 16:41:45 +00:00
<%
require 'uv'
def code_for(file, executable=false)
@stripper ||= /(\A\(function\(\)\{\n|\}\)\(\);\Z|^ )/
cs = File.read("documentation/cs/#{file}.cs")
js = File.read("documentation/js/#{file}.js").gsub(@stripper, '')
cshtml = Uv.parse(cs, 'xhtml', 'coffeescript', false, 'idle', false)
jshtml = Uv.parse(js, 'xhtml', 'javascript', false, 'idle', false)
append = executable == true ? '' : "alert(#{executable});"
run = executable == true ? 'run' : "run: #{executable}"
button = executable ? "<button onclick='javascript: #{js};#{append}'>#{run}</button>" : ''
"<div class='code'>#{cshtml}#{jshtml}#{button}<br class='clear' /></div>"
end
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
2009-12-21 16:41:45 +00:00
<title>CoffeeScript, briefly...</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
</head>
<body>
<div class="container">
2009-12-21 16:41:45 +00:00
<h1><sub style="font-size: 100px;">&#9749;</sub> CoffeeScript</h1>
<p>
CoffeeScript is a little language that compiles into JavaScript. Think
of it as JavaScript's simpleminded kid brother &mdash; the same genes,
2009-12-21 16:41:45 +00:00
the same accent, but a different sense of style. Apart from a handful of
bonus goodies, statements in CoffeeScript correspond one-to-one with their
JavaScript equivalent, it's just another way of saying it.
</p>
<!-- <%# code_for('intro') %>-->
<p>
<b>Disclaimer:</b><br />
CoffeeScript is just for fun and seriously alpha. <i>There is no guarantee,
explicit or implied, of its suitability for any purpose.</i> That said, it
compiles into pretty-printed JavaScript (the good parts) that can pass through
<a href="http://www.jslint.com/">JSLint</a> warning-free.
</p>
<h2>Table of Contents</h2>
<p>
<i>
This document is structured so that it can be read from top to bottom,
if you like. Later sections use ideas and syntax previously introduced.
</i>
</p>
<p>
<a href="#punctuation">Punctuation Primer</a><br />
<a href="#functions">Functions and Invocation</a><br />
<a href="#objects_and_arrays">Objects and Arrays</a><br />
<a href="#assignment">Assignment</a><br />
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br />
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br />
<a href="#expressions">Everything is an Expression</a><br />
<a href="#while">While Loops</a><br />
<a href="#array_comprehensions">Array Comprehensions</a><br />
<a href="#slice">Array Slice Literals</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a>
<a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/Case/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br />
<a href="#strings">Multiline Strings</a><br />
</p>
2009-12-21 16:41:45 +00:00
<p>
2009-12-21 16:41:45 +00:00
In all of the following examples, the source CoffeeScript is provided on
the left, and the direct compilation into JavaScript is on the right.
</p>
2009-12-21 16:41:45 +00:00
<div id="documentation">
<p id="punctuation">
<b class="header">Punctuation Primer</b>
You don't need to use semicolons to (<b>;</b>) terminate expressions, ending
the line will do just as well. So newlines can matter, but whitespace is
not otherwise significant. Instead of using curly braces (<b>{ }</b>)
to delimit blocks of code, a period (<b>.</b>) marks the end of a
function, if statement, or try/catch.
</p>
<!-- <%# code_for('punctuation') %> -->
<p id="functions">
<b class="header">Functions and Invocation</b>
Let's start with the best part, shall we? Function literals are my
absolute favorite thing about CoffeeScript.
</p>
<%= code_for('functions', 'cube(5)') %>
<p id="objects_arrays">
<b class="header">Objects and Arrays</b>
Object and Array literals look very similar. When you spread out
each assignment on a separate line, the commas are optional.
</p>
<%= code_for('objects_and_arrays', 'song.join(",")') %>
<p>
</p>
<p id="assignment">
<b class="header">Assignment</b>
All assignment in CoffeeScript, whether to a variable or to an object
property, uses a colon. Equal signs are only needed for mathy things.
</p>
<%= code_for('assignment', 'greeting') %>
<p>
</p>
<p id="lexical_scope">
<b class="header">Lexical Scoping and Variable Safety</b>
The CoffeeScript compiler takes care to make sure that all of your variables
are properly defined within lexical scope &mdash; you never need to declare
<i>var</i> yourself.
</p>
<%= code_for('scope', 'new_num') %>
<p>
Notice how the variables are declared with <i>var</i> the first time
they appear. The second reference of <b>num</b>, within the function,
is not redeclared because <b>num</b> is still in scope. As opposed
to the second <b>new_num</b>, in the last line.
</p>
<p id="conditionals">
<b class="header">Conditionals, Ternaries, and Conditional Assignment</b>
</p>
<%= code_for('conditionals') %>
<p>
</p>
<p id="expressions">
<b class="header">Everything is an Expression</b>
You might have noticed how even though we don't add return statements
to CoffeScript functions, they nonetheless return their final value.
The CoffeeScript compiler tries to make sure that every little language
construct can be used as an expression.
</p>
<%= code_for('expressions', 'eldest') %>
<p>
When compiling a function definition, CoffeeScript tries to push down
the return statement to each of the potential final lines of the function.
It uses the same mechanism to push down assignment statements. If statement
are compiled into ternary operators when possible, so that they can be used
as expressions.
</p>
<p id="while">
<b class="header">While Loops</b>
The only low-level loop that CoffeeScript provides is the while loop.
</p>
<%= code_for('while') %>
<p id="array_comprehensions">
<b class="header">Array Comprehensions</b>
Most of your looping needs should be handled by array comprehensions.
They replace (and compile into) for loops, handling
<b>each</b>/<b>forEach</b> style loops, as well as <b>select</b>/<b>filter</b>.
Unlike for loops, array comprehensions are expressions, and can be returned
and assigned.
</p>
<%= code_for('array_comprehensions') %>
<p id="slice">
<b class="header">Array Slice Literals</b>
CoffeeScript includes a literal syntax for extracting slices of arrays.
The first argument is the index of the first element in the slice, and
the second is the index of the last one.
</p>
<%= code_for('slices', 'three_to_six') %>
<p id="inheritance">
<b class="header">Inheritance, and Calling Super from a Subclass</b>
JavaScript's prototypal inheritance has always been a bit of a
brain-bender, with a whole family tree of libraries (Base2, Prototype
).
</p>
<%= code_for('super', true) %>
<p id="embedded">
<b class="header">Embedded JavaScript</b>
If you ever need to interpolate literal JavaScript snippets, you can
use backticks to pass JavaScript straight through.
</p>
<%= code_for('embedded', true) %>
<p id="switch">
<b class="header">Switch/Case/Else</b>
Switch statements in JavaScript are fundamentally broken. You can only
do string comparisons, and need to break at the end of each case
statment to prevent falling through to the default case. CoffeeScript
compiles switch statements into if-else chains, allowing you to
compare any object (via <b>===</b>), preventing fall-through, and resulting
in a returnable expression.
</p>
<%= code_for('switch') %>
<p id="try">
<b class="header">Try/Catch/Finally</b>
Try/catch statements just about the same as JavaScript (although
they work as expressions). No braces required.
</p>
<%= code_for('try') %>
<p id="try">
<b class="header">Multiline Strings</b>
Multiline strings are allowed in CoffeeScript.
</p>
<%= code_for('strings') %>
</div>
</div>
</body>
</html>