Up to Main Index Up to Journal for September, 2023 JOURNAL FOR WEDNESDAY 13TH SEPTEMBER, 2023 ______________________________________________________________________________ SUBJECT: Types of labels for things DATE: Wed 13 Sep 20:41:51 BST 2023 Things have become interesting. First of all, I discovered I needed to add another operator to define a variable with the type of another variable — and set its value to a zero value. I’ve gone with a “define as” operator ‘::’. For example: ia := []int 3 5 7 // ia's infered type is []int IA :: ia // IA's type is []int inferred from ia // value is an empty int array, []int() This seems to fit into the “define as <type>” ‘:<type>’ pattern, but is “define as var” ‘:: var’ instead. It would have been nice to use a simpler ‘:var’ but that introduced a host of ambiguities. One interesting side effect is that you can re-define a variable as itself which results in setting the variable to its zero value: ia := []int 3 5 7 ia :: ia // ia is now an empty int array, []int() So far there are 23 new operators for defining the various types: :int :uint :float :string :bool :regexp :label :[]int :[]uint :[]float :[]string :[]bool :[]regexp :[]label :[int] :[uint] :[float] :[string] :[bool] :[regexp] :[label] := :: Astute readers may notice a ‘new’ label type in there. While variables with label values have been unofficially supported for a while, they are very useful, they now need to be officially supported. This is so that they can be strongly typed. For example, if you have a function that takes a label as a parameter you need to be able to define the parameter’s type: demo: func oper:label, s:string, x:int // do stuff call oper s x // do more stuff endfunc Having tables of functions, as in []label and [label], is also very useful. As a result of all this I’ve temporarily parked my strong typing changes to add proper label support. I’ve kept the scope of what can be done with labels quite small. Adding functionality later is easier than removing functionality when people are using it. So far, with labels, you can: • create them, as normal, myLabel: • create arrays of them []label(myLabel, …) • create maps of them [label](myLabel value, …) • work with []label or [label] as per normal arrays/maps: ▪ exists, keys, len and literal all work ▪ dim a []label with the zero values, currently using GOTO or CALL on a zero value causes the program to end, as if the end of the program was reached. This may change • compare a label, []label or [label] for equality with ‘==’ or ‘!=’, labels are considered equal if they point to the same location regardless of the label’s name Labels do not support conversions or arithmetic. I did consider adding support for other comparison operators besides ‘==’ and ‘!=’, but they provide limited usefulness — and can be added later on for completeness. I have a nagging feeling that I should split labels and function names and instead be creating a ‘func’ type, even if a ‘func’ type is only a very thin wrapper around a label. However, using labels for function names as it is now is actually working out very well. The work of adding proper label support is done. Just need to update the tests, adding in new tests for the label types… -- Diddymus Up to Main Index Up to Journal for September, 2023