Skip to content

Instantly share code, notes, and snippets.

@rpattabi
Created September 15, 2012 05:42
Show Gist options
  • Save rpattabi/3726480 to your computer and use it in GitHub Desktop.
Save rpattabi/3726480 to your computer and use it in GitHub Desktop.
CoffeeScript Study Notes

CoffeeScript study notes

references

basics

  • 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`

installation

sudo apt-get install nodejs npm
npm install -g coffee-script

values

  • 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 or null means nothing or no value. and they are not equal
  • NaN 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.

strings

  • 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

operators

  • 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.

boolean operators

  • aliases. == is same as is; != is same as isnt
  • || is same as or; && is same as or
  • ! is same as not. 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')

existential operator

? 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

precedence

  • or has the lowest precedence
  • then comes and
  • is and isnt are of higher precedence
  • this is good enough to reduce the parantheses

variables

  • imagine variables as tentacles, rather than boxes. They do not contain values, they grasp them.
  • usual naming rules. $ is also allowed. $_$ is valid variable.

environment

  • coffeescript runs in global environment when in interactive mode
  • window is the environment in the browser
  • coffee -r <coffee file> is required to start interactive session with the env defined in the coffee file. otherwise even simple prompt or confirm doesn't get recognized.
  • an environment attaches standard values to it.
  • the variables created or modified survive till the env/window is closed.

useful functions

  • show shows details of things in interactive env
  • view 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.

conversion

prompt 'Pick a number', '', (ans) ->
  theNumber = Number ans
  • Number converts a value to a number.
  • String, Boolean are other possibilities.

loop

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'

functions

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!

Unit Testing

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 here
  • c is test case
  • arbInt is arbitrary integer
  • guard 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 with shrinkedArgs.

qc reference

Sample programs / Answer to exercises of Smooth CoffeeScript book

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment