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

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…


  Up to Main Index                         Up to Journal for September, 2023