stz constants:
When we send constants: to a class or a trait we're not just recording that there is one but we also want to generate a method for accessing that value easily later.
The simple example:
iterable-t = { trait | constants: ( element-class: class, ) }
We want that to produce a method like the following:
[ iterable-t-class element-class | iterable-t -> class
| iterable-t-class constants['element-class'] ]
The constants: method has to do a couple of things then:
- use the structure information to fill out the constants map
- generate the helper method
Let's see if we can pull that off...
[ t constants: constants-struct
| trait, map of: class to: any -> ø
| constants-struct members do:
[ key: class, value: class, ~&!t
| t constants[key name] = value
generate_constant_method: t name: key name type: value class ] ]
So far so good. Let's try and make a generate_constant_method:name:type:
[ generate_constant_method: t name: constant-name type: constant-type
| &trait, string, class
| compile:
"[ {t name}-class {constant-name}
| {t name} -> {constant-type name}
| {t name}-class constants['{constant-name}'] ]" ]
Well. That is shockingly easy - so long as we add string interpolation to the language. I'm not sure I'd even want to try and build a parse tree version when that is so straight forward.
We can use this same technique to generate getter/setter methods for the structure of a class too. We can do the same for enumerations as well.
Two thoughts
- wow what else can we generate from a simple description?
- boo why is object creation not better than string interpolation at this?
stz right now supports three ways of writing strings:
- 'hello world'
- "hello world"
- `hello world`
I never specified any difference between them. The ' and " variants are for convenience mostly. When you start writing code inside strings you tend to need to pick either a ' or a " for one language and " or ' for the other language.
I'll say that `` should be reserved for strings that have no interpretation what so ever. They simply are what you write in to them. The only thing you can't put inside them is a `.
That leaves ' and " strings to do interpolation. That will require coming up with a syntax for the interpolation. Much like the ' and " thing you don't want to use a bracket set you're going to be using inside the string. If we're generating stz code a lot then we'll be typing [] a lot. This'll be a topic for another blog post.
The other thing to consider, now that we can generate code easily, is public/package/private scope. Right now we send a message to the compilation scope context to change what we want, but if the definition of a trait or class is public and we want some of the constants or variables to not be public then we have a design problem.
One solution for this is to add meta-data to objects which would be a map of key to value. Let's try it:
foo = (
name: string #(scope:public,),
secret: uuid #(scope:private,), )
// or may be:
foo = (
name #(scope:public,): string,
secret #(scope:private,): uuid, )
Hm. I'm not convinced yet. Also what object is that attached to? Have we just made a variant of string and uuid which contain metadata? Is this something we can do anywhere or only in structures definitions? We'll try again in another blog post.