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
irb
like 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.14
is 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]
undefined
ornull
means nothing or no value. and they are not equalNaN
can 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)
==>99
3 % 2
==>1
3 > 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 true
or
can 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
or
has the lowest precedence- then comes
and
is
andisnt
are 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
global
environment when in interactive mode window
is the environment in the browsercoffee -r <coffee file>
is required to start interactive session with the env defined in the coffee file. otherwise even simpleprompt
orconfirm
doesn't get recognized.- an environment attaches standard values to it.
- the variables created or modified survive till the env/window is closed.
show
shows details of things in interactive envview
is useful to find what is going on in between a long expression. e.g.1+2+3+ view 4+1
returns 5 (result of view) and 11 (result of the whole expression)console.log
directs output to browser's console. not sure what is browser's console.alert
pops up a dialog box with the message when in browser.confirm
asks a yes or no question. e.g.
confirm 'are you sure?', (answer) -> show answer
prompt
gets 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
runOnDemand
creates a Run button.
prompt 'Pick a number', '', (ans) ->
theNumber = Number ans
Number
converts a value to a number.String
,Boolean
are 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()
gc
is the unit testing library used herec
is test casearbInt
is arbitrary integerguard
throws 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.arbWholeNum
could 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
qc
tries 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.