stz memory-address and array

stz memory-address and array
Photo by Kelly Sikkema / Unsplash

Now that we have traits, interfaces, generics, poly types ... we'll just call them traits until I realise that's the wrong word ... we can move on to the burning question in my mind. How the heck do we implement array?

array = (address: memory-address, length: uint,)

Great! That was easy. Except what is the type of the stuff inside of it? We have to force the instantiation of a subclass of array to get type information. Let's take a gamble and see if our new approach solves itself.

memory-address-t = (
  [ address get: offset | memory-address-t, int -> object ],
)

array = (address: memory-address-t, length: uint,)

Okay. That's a start. Array is now generic and must be subtyped to resolve what memory-address-t is. Whatever memory-address-t is it must respond to get: which is not what we want. We want to be able to write something like this:
array * (element-class: string).

We don't have a way to do this. We need the ability to declare fields metadata on a structure that is only available at compile time.

memory-address =
  class:     (of: object-t,)
 \variables: (address: uint,)

address-of-bytes = { memory-address of: u8 }

array =
  class:     (of: object-t, length: uint,)
 \variables: (elements: (memory-address of: of),)

names-array = { array of: string, length: 10 }

list =
  class:     (of: object-t,)
 \variables: (elements: &array of: of, length: uint,)

 names = { list of: string }

(It should be obvious from this that memory-address is unsafe as you can read anywhere relative to its address while array will assert that you are not reading outside of its length bounds)

The compiler can transform the map of fields in parameters in to methods that are implements on the type itself which will return a new type where the parameter data is filled out. The parameter data acts like any member of the class would (eg: elements or length) but is constant and immutable at runtime (and isn't stored in memory, only the compiled code).

We've now codified the -of: pattern. The definition of a class is a structure+parameters+traits. Attempting to put an array on the stack without satisfying its parameter will be a compilation error.

As an aside I was thinking about the problem of when you know it's a new statement in a code block. Things that dangle, like = or { or [ or ( make it easy. Even , is a dangle that says whatever is on the next line is part of this statement.

But if you want to break up an n-ary method like class: parameter-data variables: variables-data on to two lines you need a way to say you're doing that. For now I've co-opted \ on the next line to indicate it's part of the previous line.

This might suck. We will try it on for size and see what happens.

Back to quantity:

quantity =
  class:     (of: number-t,)
 \variables: (amount: of, unit: unt,)

my-height = { quantity of: f64 }

Problem solved. We have combined our traits with generic parameters so that a string cannot be used as an amount in quantity.