stz revisiting bang!

stz revisiting bang!
Photo by Irham Setyaki / Unsplash

I really like prefix symbols in a programming language. Being able to write !some-boolean-test to do a 'not' is so deeply ingrained in to me and I don't want to change it.

In Smalltalk we send not to the object, eg: some-boolean-test not. It is a little weird. The literal programming idea breaks down a touch when you do things like this.

I already used the syntax ! for types to indicate we intend to modify them. Specifically that they will be treated as an 'output' of the method call rather than an 'input'. This is an important distinction - stz does not guarantee immutability and is likely not a goal I want to pursue. That might change, but for now we want to indicate the purpose of the method parameter so that someone eyeballing the API understands what it's all about.

Any argument passed by value is inherently copied and can be modified by the callee however they want. They cannot return you that value except as 'the return value' of the method. There's also the idea that you might be the one who knows the memory manager you want use but you don't want to (or the library designer didn't want to accept) pass that manager to the API constantly.

The pattern for dealing with this in the C world is to declare your output and pass it as a parameter. There is no reason we shouldn't stick with this tried and true technique for the majority of our API in stz.

As such we want people to know that's what we're doing. That leaves three kinds of parameters: a value we're giving as input, a reference we're giving as input, and a reference we're giving as output.

Right now ^ means 'return' in the method body. It means nothing to return from a type declaration. That actually makes no sense. So let's re-use ^ to indicate that a type parameter is an 'output', ie: something we're returning to you.

[ database insert: person into: people-table |
  &database-session, &person, ^database-table of: person -> database-error |
  ...do stuff... ]

It behaves exactly like a reference but it visually tells us the intention behind the API in a succinct way that also mirrors the return value itself.

It does make me question the use of the right arrow → to indicate the return type. But the arrow itself serves to break up the line so it's clear the difference between the parameters and the final output. It also ties the ^ in the code section to the return type. ^ is sort of an up arrow, as in it goes back up the stack and the → is right arrow, a product of the the method.

Now we've freed up ! to be a prefix operator. We can write code like this:

happy? = !person is-emotional-state: sad

Very contrived example, yes. And I realise 'not person' looks a little strange too. It works much like & does though in that the statement person is attached to completes before the prefix does its magic.