named objects
We can name objects locally by assigning it to a variable, eg:
person = { name: string, height: distance }
We can also specify what kind of object to make with the {} syntax, eg:
origin = { vec2 of: float | x: 0, y: 0 }
But if we want to export it, suddenly we have to write two lines:
origin = { vec2 of: float | x: 0, y: 0 }
export: origin
I don't like having two ways to do a thing but this might be the exception to the rule. I'm going to introduce some new syntax and give it a fancy purpose.
{ person | name: string, height: distance }
{ origin | vec2 of: float | x: 0, y: 0 }In the first case 'person' doesn't exist yet and is therefore a variable name. In the second case we define the name and the type. This allows us to easily export them:
export: { person | name: string, height: distance }
export: { origin | vec2 of: float | x: 0, y: 0 }
While we're at it:
export: { false | bool cast: 2r0 }
export: { true | bool cast: 2r1 }
Yes this is a much shorter post. Just some thoughts put to virtual paper. These are declarations so we will also state that they are immutable (constants).
Now there's another pattern that is very annoying in languages with references. You export the type and then you end up passing a reference to it around everywhere. You have to remember if you should be passing it around as a reference or a value.
Let's add export-ref: as a method that exports the named thing but as a reference to the thing. If we have a file-handle or an io-manager do we want a ref of one and a value of the other? it's almost always the case that we want a reference to a thing. The 'io-manager' that is exported should be a reference to the internal io-manager class.
I want to avoid the C++ like approach of sticking I or P on the start or end of names to indicate one is the structure and the other is the a pointer to it.
This has more ramifications that is at first obvious. The simple code of io read: handle into: buffer is passing everthing as a value. That means 'io', the very important process manager, is being copied! Eek!
Instead of requiring developers to write &io everywhere, io-manager should have been exported as a reference:
export-ref: { io-manager | handles: ..., suspended-processes: ..., etc }
Now the code in the previous blog post will work properly. using: 'io' will expose an io-manager that isn't a value but a reference.