Skip to content
refractalize edited this page Oct 31, 2012 · 2 revisions

Why spaces indeed!

My first encounter with spaces was when I was working on a small project with @joshski. He got excited as he usually does and wrote a small language and parser that allowed spaces in variable names. Weird I thought, but cool. Definitely cool.

We didn't finish what we were doing, but I got to thinking about programming languages again as usual, and developer-defined syntax in particular, as usual. I had attempted to use parser expression grammars (PEGs) before, allowing a very rich form of language extension, but I found the power and flexibility to be too complicated for regular language extension tasks. Lisp on the other hand allows language extensibility, but somehow it isn't complicated. Ruby too has become an excellent language for DSLs, but in Ruby there's not a macro in sight.

The quality that both Lisp and Ruby share is a good foundational syntax. A syntax that is uniform, yet able to be reused in different ways. With Ruby it's the block syntax:

define_my_thingo do
    it_has :stuff
end

With Lisp it's the SEXPs - they double as the language syntax and its most native data type, the list:

(define my-thingo
    (it-has 'stuff))

Either way, we didn't need to spend a ton of time redefining the grammar, we're just reusing the existing grammar in a new way. PogoScript needed that kind of grammar.

The other thing that had been bugging me was the fact that functions don't describe their arguments very well. Perhaps I'd been writing a bit too much Objective-C at the time but the named arguments were very appealing.

There were probably dozens of styles I messed around with. I had even been thinking about this on my previous programming language tycho. E.g.

file-system (move-file-from: 'c:\temp\some-file.txt', to: 'c:\some-file.txt')

Fortunately I settled on allowing spaces in the function or method name. The next task was to extend this concept into the multi-line control structures like try/catch/finally: could that just be a function too? How would the parser know to keep parsing the catch and then the finally? Turns out it's not too hard, we just assume there not to be an empty line between the body and the catch. A slight compromise but worth it.

So if this language was designed for macros, where are they?

Good question. That's next on my agenda.

Clone this wiki locally