I started programming in the early 80's. One of my first programs was something like
Aside from being immature, it also used the primitive execution flow control
GOTO. I expect most of you have heard tales of what code using goto's was like to write and debug. It was every bit as ugly and painful as you've heard. But even by that time, the so called "goto wars" were over and block-structured programming was ascendant. Which is not to say it was all sweetness and light. As painful as using goto's was, many argued vodiferously that they could not be removed. That they were an essential part of programming. The goto was an abstraction of the underlying hardware that leaked through and popped up in the higher level languages.
Plugging that leak cut a tie to the lowest levels of abstraction that kept us from writing higher-level code and ultimately limited the size of the software we could write. Today, it's time to cut the last tie.
A boolean value only carries a single bit of information. This is an echo of the fact that fundementally, computers only operate on 1's and 0's. The associated language feature, the
if statement is a blight on our ability to reason about our code and responsible for all the present ills in our industry. (hyperbolic sarcasm alert!)
But seriously, when I read about boolean blindness, the idea captured my imagination. What would a language without booleans look like? Would there be a benefit? Once I got over the (small) initial hump, I actually found it easier to program without booleans,
cond. It's early days yet, so I'm very interested in other people's experience.
Maybe, or, and
We can't just eliminate booleans. They must be replaced with something. In Toccata that something is the
Maybe data type. Maybe values may contain another value, or may be empty. The
Maybe type also implements some of core protocol functions. One of those functions is
extract which pulls the value from inside a
Maybe value. Of course, if the
Maybe value is empty, that's going to blow up.
But that's not quite enough. Toccata is strict, meaning that all values passed to a function are evaluated before the call. But we absolutely need a way to only evalute certain expressions depending on the results of comparisons, for example. The Toccata compiler provides two foundational special forms for this,
Will evaluate to the
nothing value if
x is not 15. But if
x is 15, that expression evaluates to a
Maybe value that contains a 15.
or expression will evaluate each of the clauses one at a time until a clause does not evaluate to
nothing. That value is what the
or expression then evaluates to. Any remaining clauses are not evaluated.
<Maybe 15> if
x is 15. Otherwise, it evaluates to
and expression evaluates each clause one at a time until one does evaluate to
nothing, in which case the
and expression evaluates to
nothing as well.
But if none of the clauses evaluate to
nothing, the value of the last clause is what the
and expression evaluates to. So
x does not equal 15 or
y does not equal 98. But if both those clauses evaluate to
<Maybe 15> and
<Maybe 98> respectively, the
and expression evaluates to
With just these, I was pretty much able write the entire Toccata compiler in Toccata itself.
But there was one fly in the ointment. I had quite a few expressions that looked like
Which is just ugly. I left those expressions in the code as an incentive to find a better way. And finally, last week, inspiration hit out of nowhere. (Literally. I was driving and thinking about something totally different.) I added a new special form,
This expression evaluates to 15 if
x is 15 and
x + 1 in all other cases. But the call to
inc will only be called if
x is not 15. This new expression let me clean up a lot of ugliness and I'm expecting to clean up more when I have a chance.
And now I see
and expressions can be nested to any depth. And the first clause of an
either expression can be as complicated as needed.
I think this is sufficient to replace booleans and cut that final tie to the low level. But I'm open to coming up with solutions to other use cases that I haven't uncovered yet.