stz foundational types

stz foundational types
Photo by Scott Blake / Unsplash

The name OrderedCollection is too dang long. I'm tired of writing it. So let's not. Really, what's wrong with a short name like list? And if we want something a little fancier than we could even have an ordered list.

Why is ordered list fancier than unordered list? cost of lookup, search, adding is the same between the two - but removal is more expensive if the list has to preserve order.

That brings us to naming conventions. CamelCase is cool if you're giving all your types a capital first letter. But I don't want to. I like not having to hit the shift key constantly. There's always the choice of ordered_list but i still have to hit that shift key. This is a small bugbear for sure. but for now humour me and let me write ordered-list like i'm in a shell terminal.

Okay, back to fundamental types. It's not integers. Machines don't really care if an integer is signed or unsigned. They have bits. They have bits of fixed sizes. I'm going to call this binary and we'll use our fanceh parametrics on it: (binary size: 8)

For the moment let's go with that being number of bits. May be that's wrong but it'll do. That means unsigned-integers and signed-integers are distinct variants of binary types.
uint8 := unsigned-integer8 := binary size: 8

It's a systems language - we're going to be using these sized integer types a lot. A full name makes sense but a short name is more realistic if anyone ever wants to use this language. Heck, we could go real short and use u8 instead. Why don't we do that...
u8 := unsigned-integer8 := binary size: 8

This is nice. The only problem with it is that this is an alias. We're not making a new type here just giving binary size: 8 a different name. What we need is a distinct variant of binary size: 8.

Here's an idea i've been toying with. Why bother specifying the receiver if it's the current execution scope? all those self references in Smalltalk looks a little odd when we're sending messages to ourself. The self object during compilation is your compilation scope which could understand the message distinct:, eg:
u8 := unsigned-integer8 := distinct: (binary size: 8)

(As an aside we're already giving up on the magic . in front of the type name aren't we.. well we'll have to deal with that when we come to it then)

One neat thing I saw in another language recently was naming the boolean class ?. Just a question mark, nothing else. Is this a good idea? well it does make for some interesting looking code:
of-legal-age? := [ p: person → ? | ^p age ≥ 18 ]

The other options are bool and boolean. For now let's humour the idea of using ? as the name for the boolean class.

Speaking of boolean, let's lean in to the maths and define it as a distinct variant of an integer.
? := distinct: u8
false := ? cast: 0b0
true := ? cast: 0b1

Why do it this way instead of the classic True/False subclasses of Boolean in Smalltalk? Well for one those classes are a bit of a lie. It is incredibly rare to have a class with a singleton and nothing more. For two it allows us to make booleans themselves a non-core concept in the language implementation.

When we want to know if a && b is true, we can do the bit-and operation on the two booleans as integers and get the result as a boolean again. The same is true of ||. Not is 1 - the integer of the boolean.

What about if/then/else? the Smalltalk way of doing that is with messages on the True/False classes. Since we don't need specialised identity for the numbers 0 and 1 we can compare the two integers (actually binary size: 8) and evaluate the provided closure if they are equal.

Now we're starting to hit machine code. The various cmp instructions can be defined directly for things like binary to binary comparison.

I suppose we need to define a syntax for declaring methods next...

In summary here are our core classes so far:
binary size: ...
u8 / u16 / u32 / u64 / s8 / s16 / s32 / s64
string
array
list
ordered-list
? (or maybe be bool)

There are some other useful ones that i'll thrown in here too to be discussed later:
map
range
set
memory-address
reference
float
unit
quantity
character
symbol
type