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-integerword i was like "oh, there is theifword, 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
}