Day 9: The sweetest syntax

Thinking about syntax again, and a comment someone made to me earlier during Growl's development comes to mind:

This language is very difficult to understand to me.

In the Fizzbuzz example I was reading nested quotations and was waiting for the moment they start making sense, and by the end of the each-integer word i was like "oh, there is the if word, I have to read these two quotations again in the context of a conditional structure."

My approach to this is block application. A word can be suffixed with a colon to make it a block-applicative word, and write one or more blocks after the word, like so:

if: {
  ;; true branch
} {
  ;; false branch
}

Note that blocks use curly braces and not square brackets. Using square brackets would pose a problem, for example: is the second block in if: [...] [...] part of the block application or by itself?

You can also put code in between the word and the first colon, which lends itself nicely to organize code:

when: condition? {
  ;; do thing
}

A call like word: {} de-sugars to [] word, and a call like word: ...code {} desugars to ...code [] word.

For a not so contrived example:

#import std

def: "fizzbuzz?" {
  dup if: 3 % 0 = { drop true } { 5 % 0 = }
}

each-integer: 100 {
  1 + dup
  if: fizzbuzz? {
    keep: { when: 3 % 0 = { "Fizz" print } }
    when: 5 % 0 = { "Buzz" print }
  } {
    itoa print
  }
  "\n" print
}