# comments start with a hash sign

# functions are applied to their arguments within parentheses, like
(iadd 2 3)
#=> 5

# to get output, you'll always need to have an outer print statement
(isub 9 2) # won't print anything
(iprint (isub 9 2)) # prints 18

# you can nest these functions easily, like
(iadd (imul 2 3) 4)
#=> 10

# strings are delimited with double quotes (")
(sprint "Hello, world!")
#=> Hello, world!

# numbers without a decimal point are ints...
(iprint 123)
#=> 123

# ...while numbers with a decimal point are floats.
(fprint 2.3)
#=> 2.300000
(fsqrt 4.1)
#=> 2.024846

# lists can be defined through direct `cons` notation, like so:
(cons 1 (cons 2 nil))
#=> [ 1 , 2 ]

# but it is recommended to use bracket notation. all spacing must be verbatim:
[ 1 , 2 , 3 ]
#=> [ 1 , 2 , 3 ]

# booleans are true and false
(sequal "abc" "def")
#=> false
(sequal "abc" "abc")
#=> true

# boolean values can be used in if statements
(if true 1 2)
#=> 1

# lime also has support for more explicit if statments, which compile down to the above form:
(if (iequal 2 3)
	 then (sprint "something's wrong...")
	 else (sprint "all good! :)"))
# these are recommended.

# functions are defined with `function`
(function increment (x:int) -> int
          (iadd x 1))

# if a return type is specified, `null` is assumed
(function main ()
          (sprint "Hello World!"))

# lambda functions allow you to define functions and apply them inline
((lambda (a:str) (sslice 1 a)) "abc")
#=> bc

# they are also very useful in `map` expressions...
(map (lambda (a:str) (sslice 1 a)) [ "QH" , "KS" , "9C" ])
#=> [ "H" , "S" , "C" ]

# ..or filter expressions
(filter (lambda (x:int) (iequal x 2)) [ 1 , 2 , 3 , 2 ])
#=> [ 2 , 2 ]