#>  Hi! Welcome to the Nulan tutorial. After reading this, you
#>  should have a very basic idea of how to write Nulan programs.

#>  To start with, all Nulan programs are composed of zero or
#>  more expressions. Every expression must have a value. The
#>  process of taking an expression and returning a value is
#>  called "evaluation".

#>  The simplest expressions are literals, which evaluate to
#>  themself:

5

#>  Try clicking on the above expression `5`. In the lower-right
#>  panel, you can see that it evaluates to the number `5`.

#>  Another type of literal is a string:

"I'm a string"

#>  Strings start with ", contain zero or more characters, and
#>  end with ". They're used for storing text.

#>  Let's try something more complicated:

5 + 10

#>  If you click on the above expression, you'll see it evaluates
#>  to the number `15`. That expression is composed of three
#>  parts: the number `5`, the symbol `+`, and the number `10`.

#>  Now, something I haven't told you yet is that all these
#>  examples are fully interactive. To try it out, go ahead and
#>  change the expression `5 + 10` to anything you like, and the
#>  lower-right panel will automatically update with the answer.

#>  Any changes you make are automatically saved, so you can
#>  close this tab and reopen it later.

#>  If at any time you want to undo the changes you've made,
#>  click the "Reset Tutorial" button at the top of the screen.
#>  Be careful, it will wipe out your changes, and you can't get
#>  them back.

#>  Nulan also supports some more math stuff with the usual
#>  priority:

1 + 2 * 3 / 4 - 5

#>  And you can use parentheses to change the priority of any
#>  expression:

(1 + 2) * 3 / (4 - 5)

#>  Let's talk about boxes. A box is something that can hold a
#>  single value. It can then be unboxed later. To create a box,
#>  you use the `box` symbol:

box foo = 2

#>  What we've done here is taken the number `2` and placed it
#>  inside a box. We then took that box and assigned it to the
#>  symbol `foo`. We can then unbox it by simply using the symbol
#>  `foo`:

foo

#>  You might have noticed that the `box` expression evaluated to
#>  `()`. Every expression needs to return a value, but some
#>  expressions don't have anything meaningful to return, so they
#>  return `()` instead.

#>  Because everything in Nulan is an expression, symbols can
#>  be used as part of a bigger expression:

foo + 2

#>  But boxes aren't just a shorthand for referring to values.
#>  Right now, the `foo` box contains the number `2`. But we can
#>  put a different number into the box:

foo <= 5

#>  Now the `foo` box contains the number `5` rather than the
#>  number `2`. It is like as if we unboxed it, took the number
#>  out, put a new number in, and then reboxed it again.
#>  But even though the stuff inside the box changed, the box
#>  itself is the same. This will be important later on.

#>  Let's talk about functions. Functions are extremely common in
#>  Nulan, so it's important to understand them. A function is a
#>  value that can be called with multiple expressions as
#>  arguments and then returns an expression.

#>  It's okay if you didn't understand anything I just said. I'll
#>  take it slow and use lots of examples. First, to create a
#>  function, you use the `->` symbol:

-> a a

#>  The above expression returns a function which accepts a
#>  single argument called `a`. It then returns `a`. Let's try
#>  calling the function:

(-> a a) 5

#>  One way of thinking about this is to imagine that Nulan
#>  replaced the symbol `a` inside the function with the number
#>  `5`, then returned `5`.

#>  The parentheses are needed because without them, Nulan would
#>  treat it as a function that accepts two arguments and always
#>  returns `5`.

#>  Let's write a function that takes any number and adds `10` to
#>  it:

-> a (a + 10)

#>  And now let's call it:

(-> a (a + 10)) 5

#>  Nulan replaced `a` with `5`, and then returned `(5 + 10)`.

#>  This probably doesn't seem very useful. Let's make it more
#>  useful by taking the function and placing it into a box:

box add = -> a (a + 10)

#>  We created a function using `-> a (a + 10)` and then used
#>  `box` to assign it to the `add` symbol.

#>  This is common enough that Nulan has a special `def` symbol
#>  which is almost exactly like `box`, except that it works
#>  better for functions:

def add -> a (a + 10)

#>  Now let's call it:

add 5

add 10

add 15

#>  Notice that we called it three times, with a different
#>  argument each time. In the first call, `a` was replaced with
#>  `5`, in the second it was replaced with `10`, and in the
#>  third it was replaced with `15`.

#>  Let's make a function that accepts three arguments and adds
#>  them together:

def add -> a b c
  a + b + c

#>  Now let's call it:

add 1 2 3

#>  Nulan replaced `a` with `1`, `b` with `2`, and `c` with `3`,
#>  then returned `1 + 2 + 3`.

#>  That was a simple example, but functions can become quite
#>  complex. The reason why functions are so useful is that they
#>  let you easily evaluate an expression multiple times.
#>  Consider these three expressions:

1 + 2 * 3 / 10

1 + 2 * 4 / 10

1 + 2 * 5 / 10

#>  The only difference between them is that the first uses `3`,
#>  the second uses `4`, and the third uses `5`. Using boxes
#>  won't help with the code duplication. Functions to the
#>  rescue!

def foo -> a
  1 + 2 * a / 10

foo 3

foo 4

foo 5

#>  Now the parts that remain unchanged are put into the
#>  function. The only part that changes is the argument `a`,
#>  which is replaced when the function is called.

#>  And so, functions let you take the unchanging parts and put
#>  them into a single place, which makes it much much easier as
#>  your programs become bigger and more complex.

#>  Moving on, let's look at this program:

w/box temp = 5
  if temp
    temp + 1

w/box temp = 10
  if temp
    temp + 2

#>  The `w/box` symbol is like `box` but the box it creates can
#>  only be accessed inside the `w/box` expression.

#>  The `if` symbol checks if its first argument is true. If it
#>  is, then it will evaluate the second argument. Otherwise
#>  it will evaluate the third argument.

#>  This pattern of creating a temporary box and using `if` is
#>  quite common. Let's try using a function to get rid of the
#>  code duplication:

def if-box -> x y
  if x
    x + y

if-box 5  1
if-box 10 2

#>  This works, but it's not very flexible. What if we wanted to
#>  subtract the numbers, or divide the numbers, or do something
#>  else? The `if-box` function will only add, nothing else.

#>  One of the cool things about functions is that because they
#>  are values, they can be used as arguments to other functions:

def if-box -> x f
  if x
    f x

if-box 5  -> x (x + 1)
if-box 10 -> x (x + 2)

#>  Here's what happened. We called `if-box` with two arguments:
#>  the number `5` and the function `-> x (x + 1)`, which were
#>  then replaced like usual.

#>  This works, but it's a bit verbose. Let's use a macro to
#>  remove the verbosity! You've already seen a bunch of macros,
#>  but you didn't realize it. These are all macros:
#>  `+` `-` `*` `/` `box` `=` `<=` `->` `def` `w/box` `if`

#>  What is a macro? Well, a function has arguments, which are
#>  replaced with values, and the function then returns a value.
#>  A macro is a special kind of function that has arguments,
#>  which are replaced with code, and the macro then returns
#>  code.

#>  First, to create a macro, we use the `$mac` macro:

$mac if-box ->

#>  The above expression took the empty function `->`, converted
#>  it into a macro, and then assigned it to the symbol `if-box`.
#>  But this macro doesn't do anything yet. Let's start by
#>  copying in our original program:

$mac if-box ->
  w/box temp = 5
    if temp
      temp + 1

#>  We can't use this macro just yet, though. Remember when I
#>  said that macros are given code and return code? Well, right
#>  now the macro is returning a value, not code. If we use the
#>  `'` macro, we tell Nulan to treat it as code rather than a
#>  value:

$mac if-box ->
  'w/box temp = 5
     if temp
       temp + 1

#>  Oops, Nulan is saying that the symbol `temp` is undefined.
#>  What happened?!

#>  Well, do you remember when I said earlier that you can change
#>  the value of a box without changing the box itself? The `'`
#>  macro returns boxes, not symbols. And the `temp` box isn't
#>  defined.

#>  To fix this, we'll need to assign `temp` to a box. To create
#>  a box, we can use the `w/uniq` macro:

$mac if-box ->
  w/uniq temp
    'w/box temp = 5
       if temp
         temp + 1

#>  And now it works just fine. But it only works for the first
#>  use case, not the second. Let's figure out the parts that
#>  change: those parts will need to be arguments to the macro.

#>  Well, the expression `5` changes, so let's replace that with
#>  an argument:

$mac if-box -> x
  w/uniq temp
    'w/box temp = x
       if temp
         temp + 1

#>  And the expression `1` changes too, so let's add another
#>  argument:

$mac if-box -> x y
  w/uniq temp
    'w/box temp = x
       if temp
         temp + y

#>  And now we can use it like so:

if-box 5  1
if-box 10 2

#>  But wait a minute, this looks just like earlier, when we were
#>  using a function. The reason for using a macro is so that we
#>  don't hardcode the `+` symbol, so let's start by getting rid
#>  of that:

$mac if-box -> x y
  w/uniq temp
    'w/box temp = x
       if temp
         y

#>  Now, you might be tempted to use it like this:

if-box 5
  temp + 1

if-box 10
  temp + 2

#>  But as you can see, that doesn't work. The reason is because
#>  inside the macro, we used `w/uniq` to create a new box, but
#>  that box is only accessible *inside* the macro. Instead,
#>  let's use a symbol:

$mac if-box -> x y
  w/box temp = sym "it"
    'w/box temp = x
       if temp
         y

#>  We used the `sym` function to create a new symbol and then
#>  inserted that rather than a box. And now we can use the macro
#>  like this:

if-box 5
  it + 1

if-box 10
  it + 2

#>  Inside the `if-box` expression, you can use the symbol `it`
#>  to refer to the first argument of `if-box`. As you can see,
#>  this is indeed shorter than using a function.

#>  Because macros always return code, anything you can do with
#>  macros, you can do by manually writing the code yourself.

#>  The benefit of macros is that you don't *have* to write the
#>  code yourself: you can have the macro write the code for you.
#>  And so, by using macros wisely, you can write shorter, more
#>  readable code.

#>  Now, with that out of the way, let's do something fun!

div
  style
    border-radius    "5px"
    opacity          "1"
    width            "50px"
    height           "50px"
    background-color "green"

  on "click" ->
    alert "I'm green!"


div
  style
    border-radius    "5px"
    opacity          "0.5"
    width            "50px"
    height           "50px"
    background-color "red"

    position         "relative"
    top              "-25px"
    left             "25px"

  on "click" ->
    alert "I'm red!"

#>  If you look in the upper-right panel, you should see two
#>  boxes. If you click on them, they'll tell you what color they
#>  are. Both of the boxes were generated with the above code.
#>  If you change the code, it'll change the boxes. Try it out!