a different module syntax

a different module syntax
Photo by JESHOOTS.COM / Unsplash

One of the guiding features of stz is compile time scripting to help produce the runtime. That has meant allowing code at the top level of a file. That has also meant that the syntax for declaring a method needed to work anywhere, as regular syntax.

But what if we had a different syntax for the top level. With keywords, or specific messages that can be sent to the compilation context:

module: 'foo'
import: 'bar'

| a add-with: b
| a: int, b: int -> r: int
  r <- a + b

This is a first brush. The | indicates a method. That would mean that | is special syntax and cannot be used to mean 'or' anywhere in the language. Another approach would be to use brackets:

module: 'foo'
import: 'bar'

a add-with: b [ a: int, b: int -> r: int |
  r <- a + b ]

That fits perfectly with block closures. We could format it differently too since after the signature must be a block of code.

module: 'foo'
import: 'bar'

a add-with: b
[ a: int, b: int -> r: int |
  r <- a + b ]

One interesting thing about lists is - newlines are equivalent to , so we could write it out in a 'long' form when the types are complex:

module: 'foo'
import: 'bar'

a add-with: b
[   a: int
    b: int
 -> r: int |
  r <- a + b

A curious thought occurred. What if we specify the return type first and flip its arrow?

// vertical layout
a add-with: b
[ r: int <-
  a: int
  b: int
| r <- a + b ]

// horizontal layout
a add-with: b
[ r: int <- a: int, b: int | r <- a + b ]

// type inference compact layout
a add-with: b [ r <- a, b | r <- a + b ]

I'm not sure flipping the return order around is worth the convolutions in my brain. I also enjoy this symmetry:

a add-with: b [ a, b -> r | r <- a + b ]

I like this approach. We'd need special stuff for module name, importing, and structures (classes) and any other meta information, but the rest is fairly straightforward and there's less weird syntax.

The bad though: we lose the ability to easily define a method with signature inside a method. Methods inside methods can be very useful. Yes we can create a code block and assign it to a variable - but we also lose method signatures doing that.

We could add a special way of doing it. If we borrow the 'signature' syntax from the previous post we could write this:

a add-with: b [ a, b -> r |
  <a do-the-add: b> [ a, b -> r | r <- a, b ]
  r <- a do-the-add: b ]

May be that's the way to go. The <> is implicit at the top level because there is, mostly, methods. We could also add scripting in to the top level too:

module: 'foo'

run: [ ... ]