CoffeeScript study notes
- compiles into javascript
- encourages good use of javascript's good parts
- functional programming
- takes some good ideas from other languages such as ruby
irblike interactive console:coffee# this is a comment###is block comment
###
I can write anything I want
More and more
some more
###
- no need to have ; for each line. but just like ruby if we want to have two statements in a line, we can use ;
- to break a line that belongs to one line place
\at the end and continue on next - program is indentation sensitive. indentation is what decides a piece of code belongs to a particular block or not. similar to python?
- it is possible embed javascript in coffeescript code. use backtick. e.g.
show `null === undefined`
show `'' === 0`
sudo apt-get install nodejs npm
npm install -g coffee-script
- 2.88e4 ==> 2.88 x 104 ==> 28800
- fractional number's precision is not reliable. they are only
approximations.
3.14is not exactly 3.14?? [1..10]is the range. note in ruby range is(1..100). similar to ruby three dots excludes the last value.[1...1000]undefinedornullmeans nothing or no value. and they are not equalNaNcan result in arithmetic operations where there is a non number value. It means 'not a number'. also NaN == NaN is false. use isNaN instead.
- string
'this is a string','this is "also"',"It's double quoted","and the #{ruby} like" - line breaks in the string are not shown in the ouput
- here docs are done between
'''or""". Again"""allows#{2=4}sort of interpolated values. this seems simpler than ruby. \is for escaping as usual'cata' + 'log'==>'catalog'. but no multiplication possible like ruby
typeof 4.5==>number-(100 - 1)==>993 % 2==>13 > 2==>true- works for strings as well.
'And' < 'But'==>true. comparison is case sensitive. based on unicode. - within interval check.
0 < 5 < 10==>true. comparison chaining. cool.
- aliases.
==is same asis;!=is same asisnt ||is same asor;&&is same asor!is same asnot. e.g.!true==>not trueorcan be used for giving default value. e.g.
prompt 'whats your name', '', (input) ->
show 'Well hello ' + (input or 'dear')
? is existential operator. it is really cool.
show a_something if a_something? # similar to ruby's a_something.nil?
a_something ?= 'something' # similar to ruby's a_something ||=
'something'
if a_something?.has_anything
do_something
orhas the lowest precedence- then comes
and isandisntare of higher precedence- this is good enough to reduce the parantheses
- imagine variables as tentacles, rather than boxes. They do not contain values, they grasp them.
- usual naming rules. $ is also allowed.
$_$is valid variable.
- coffeescript runs in
globalenvironment when in interactive mode windowis the environment in the browsercoffee -r <coffee file>is required to start interactive session with the env defined in the coffee file. otherwise even simplepromptorconfirmdoesn't get recognized.- an environment attaches standard values to it.
- the variables created or modified survive till the env/window is closed.
showshows details of things in interactive envviewis useful to find what is going on in between a long expression. e.g.1+2+3+ view 4+1returns 5 (result of view) and 11 (result of the whole expression)console.logdirects output to browser's console. not sure what is browser's console.alertpops up a dialog box with the message when in browser.confirmasks a yes or no question. e.g.
confirm 'are you sure?', (answer) -> show answer
promptgets one info from the user. e.g.
prompt 'tell me one thing', 'default value for that one thing',
(answer) -> show 'one thing you told me is: ' + answer
runOnDemandcreates a Run button.
prompt 'Pick a number', '', (ans) ->
theNumber = Number ans
Numberconverts a value to a number.String,Booleanare other possibilities.
while
while i < 100
i = i + 5
show i
while i < 100 then i = i + 5
for
for i in [0..12] by 2
show i
for i in [0..12] by 2 then show i
for i in [0...100] then show i
if
if number % 2 is 0
show number + ' is even'
if number % 2 isnt 0
show number + ' is odd'
if number % 2 is 0
show number + ' is even'
else
show number + ' is odd'
if number is 0
show 'it is a legendary number'
else if number is 13
show 'legendary unlucky number'
else
show 'just another number'
if number % 3 is 0 and number % 2 is 0
show number
unless
fun = on
show 'Fun is on!' unless fun is off
until (if not --> unless; while not --> until)
i = 5
i++ until i < 10
show i
loop (equivalent to while true)
loop
show 'do this endlessly until break'
pure functions don't have side effects. they take some inputs and return back something. they don't monkey around with anything else. (what about cache?)
add = (a, b) -> a + b
add 2, 5
just like ruby, last executed statement's value is the value returned.
return can also be used. if return is used without a value, it
returns undefined.
power = (base, exponent) ->
result = 1
for i in [0...exponent]
result *= base
result
power 2, 10
functions have their own environment. they have access to outside variables. but the variables within them are exclusive to them.
reptile = 'ding dong'
func = (input) ->
show reptile
junk = input
show reptile
show junk # exception since junk doesn't exist outside
this is problematic since it is easy to accidentally use the same name of the variable within a function. this will change that variable which is visible to outside!
runOnDemand ->
test_absolute = (name, property) ->
testPure absolute, [arbInt], name, property
testAbsolute 'returns positive integers', (c, args, result) ->
result >= 0
testAbsolute 'positive returns positive', (c, args, result) ->
c.guard args >= 0
result is args
testAbsolute 'negative returns positive', (c, args, result) ->
c.guard args < 0
result is -args
test()
gcis the unit testing library used herecis test casearbIntis arbitrary integerguardthrows away invalid inputs for the given test case. in the example above it throws away negative numbers, in another case it throws aways positive numbers since they are invalid inputs.arbWholeNumcould have been used which would give only the positive integers.test()is required to be called in order to trigger the tests.testPure-- ??- when a test fails
qctries to find a simpler way to reproduce a problem. thats where it comes up withshrinkedArgs.
Pick a lucky number from 1 to 6 then keep rolling a simulated die, until your lucky number comes up.
prompt 'pick a lucky number', '', (lucky_number) ->
loop
roll = Math.floor Math.random() * 6 + 1
show roll
break if roll is Number lucky_number
Write a function called absolute, which returns the absolute value of the number it is given as its argument.
absolute = (number) ->
if number >= 0
number
else
-number # sugarrr!
absolute 5
absolute -5
absolute 0
show is the example of non-pure function since it has the side effect
of leaving something on the screen printed out. so sometimes it is
necessary to have non-pure functions.