Core Improvements - caffeine-suite/caffeine-script GitHub Wiki
The most significant improvements over CoffeeScript.
I count tokens in many examples below, to show how CaffeineScript improves over CoffeeScript and JavaScript ES6. Learn more about Counting Tokens.
Core Improvements
(I'm factoring this page out into multiple, focused pages.)
- Blocks Instead of Brackets
- Extract
- Strings
- Array and Object Literals
- CommonJs
- Include
- Binary Operator Line Starts
Block method invocation
Invoke a method by following it with an indented list of arguments on separate lines:
# CaffeineScript
method
arg1
arg2
arg3
arg4
# CoffeeScript
method arg1,
arg2
arg3
arg4
# Javascript
method(arg1, arg2, arg3, arg4);
Other Improvements / Refinements
Auto 'do'
Do you ever have bugs because you forgot a "do"? I do all the time. I think defaulting to 'do' will cause less bugs.
(This needs performance testing and semantic refinement.)
# CoffeeScript
for a in b
do (a) ->
-> a
# CaffeineScript
# for-block is an implicit closure
# If a function is created in the for-block, wrap all variables
# in a closure so each iteration gets its own copy.
# Only capture variables first-assigned in the for-block and not used outside.
for a in b
-> a
Smart '@' binding
Basically, make '->' work more consistently with other languages. Most the time we shouldn't have to think about '@' binding for instance variables. Only in rare occasions should we have to override the default.
- In class definitions and not inside other explicit functions, -> works like CoffeeScript
- Inside an explicit function definitions, -> binds '@' to its enclosing scope. (like => in CoffeeScript)
- Overrides
- ~> is always unbounded (-> in CoffeeScript)
- => is always bounded (just like in CoffeeScript)
# CoffeeScript
class Foo extends Art.Foundation.BaseObject
@setter
baz: (a) -> ...
bar: (list) ->
list.each (a) =>
@baz = a
# CaffeineScript
class Foo extends Art.Foundation.BaseObject
@setter
baz: (a) -> ...
bar: (list) ->
list.each (a) ->
@baz a
map, each and for loops
CoffeeScript's 'for' loop is actually a 'map' operation. Sometimes you don't want that. Unwanted creation and population of an array is both a performance problem and a semantic problem.
# CoffeeScript
# create and return new array
(list) ->
for element in list
element.foo
# return list; doesn't create a new array
(list) ->
for element in list
@add element
list
# CaffeineScript
# create and return new array
(list) ->
array element from list
element.foo
# return list; doesn't create a new array
(list) ->
each element in list
@add element
Extended unquoted labels:
# CoffeeScript
foo: 1
'foo.bar': 2
'foo-bar': 3
# CaffeineScript
foo: 1
foo.bar: 2
foo-bar: 3