binary line starts - caffeine-suite/caffeine-script GitHub Wiki
This is one of CaffeineScript's primary strategies for eliminating bracket-matching.
turn left || right
&& dont worry
# turn(left || right) && dont(worry)
url || defaultUrl
.split :/
# (url || defaultUrl).split("/")
ageInDays = (epochSeconds) ->
Date.now() / 1000 - epochSeconds
/ 60 * 60 * 24
# JavaScript:
# let ageInDays = function(epochSeconds) {
# return (Date.now() / 1000 - epochSeconds) / (60 * 60 * 24);
# };
The ability to start a line with a dot (.) or other binary operator reduces syntax and increases readability.
CaffeineScript's binary-operator-line-starts are:
- Predictable
- Editable - changing the order of lines has a straightforward result
- Reduces the need for ()s
- Works after all statements and expressions
Starting a line with a binary operator applies the operator to the result of the previous line. Think of it as if the previous line had ()s around the whole line.
a + b
* c + d
# (a + b) * (c + d)
When you start an indented line with a binary operator, it acts as if there was no newline. Example:
a + b
* c + d
# a + (b * (c + d))
In both cases, if the line-start-operator is Binary, everything to the right of the line-start-operator is considered to be wrapped in parentheses.
# CaffeineScript
new MyClass
.foo()
// JavaScript
new MyClass().foo();
# CaffeineScript
new MyClass
.getSomeOtherClass()
// Javascript
new MyClass.getSomeOtherClass();
# CaffeineScript
new MyClass
.a 1
.b 2
.foo "hi"
.bar "bye"
// Javascript
(new MyClass.a(1).b(2)).foo("hi").bar("bye");
It works after 'if' and all other kinds of control statements.
# CaffeineScript
if foo
foo 1
else
1
.myMethod 123
// Javascript
(foo ? foo(a) : 1).myMethod(123);
foo = bar
.fud()
# foo = bar.fud();
And the other way around:
foo = bar
.fud()
# (foo = bar).fud();
To capture the result of a more complex computation, leverage the fact that '=' can take a block for its right-hand-side value (i.e. its "r-value"):
foo =
bar + baz
.bud()
# foo = (bar + baz).bud();
The exact same logic applies to all binary operators.
# CaffeineScript - 15 tokens
encodedBitmap
|| file && readAsBinaryString file
|| sourceUrl && RestClient.get sourceUrl
|| defaultUrl
// Javascript - 24 tokens
encodedBitmap ||
(file && readAsBinaryString(file)) ||
(sourceUrl && RestClient.get(sourceUrl || defaultUrl));
When a line ends with a binary operator, one of two things can follow:
- an unindented expression is interpreted as if there was no new-line
- a value-block returns a single value or, if more than one value is provided, an implicit array
NOTE: You cannot end a line with a dot (.).
a || b ||
c
# a || (b || c)
a || b ||
c
# a || (b || c)
a || b ||
c
d
# a || (b || [c, d])
It's easier to refactor the order of a chain of lines starting with binary operators (CaffeineScript) rather than lines ending with binary operators (CoffeeScript). Usually the first line is fixed at the start of a chain of lines. It provides the anchor and context for the other lines. The lines after the first are more likely to need their order changed in some future refactor. Line-start-binary-operators let you re-order all but the first line easily. Line-end-binary-operators let you re-order all lines but the last-line - which I have found less helpful.