Tag
Hash :
7a4adde3
Author :
Thomas de Grivel
Date :
2024-05-05T22:03:31
Variables in C3 can be defined using the litteral value for a variable
which is always ?
. You can cast this litteral value and it will not
really be casted but it will give you a typed variable litteral value.
E.g. (List) ?
.
The typed variable litteral value will only accept to be set once to
one value of the variable’s type (in this example the type of a linked
list).
It’s actually a syntax so you cannot rename ?
by mistake and
so is an easy task to do static analysis of variable creation.
The default type for a variable which you can also specify explicitly
is Tag
which is an enum-tagged union type of any other C3 types
currently defined in the environment. So ?
is exactly equivalent to
(Tag) ?
and they will both accept to be set once to one value of any
type.
Actually all variables are allocated as tags and in the end the typing is dynamic but it could be made static through JIT compilation of functions.
A variable is settable once and cannot be changed afterwards (there is an exception if you write C code and link to it but it is not easy nor silent).
This way you do not need to lock or trust any behaviour, once your variable is set to a value the value of the variable will never change, it really is read-only.
To set the value of a variable in the end you need to call a C function
that should accept this C function definition :
quote cfn unquote(type) unquote("init_#{variable_type}#{init_suffix}") (Result, ...)
.
There are many functions for this, here is a quick list :
tag_init_1
takes a C string as an argument and returns a value of
any type currently defined in the C3 environment. #{type}_init_1
C functions take a C string as an argument and return
a value of type type
. tag_init_copy
takes a tag as an argument and returns a deep copy
of it.
You can also use the assignment operator which is <-
which in turn calls
tag_init_copy
. It works like the C assignment operator (=
).
Examples :
# Declare a unsigned byte 8 bits variable "x".
x = (U8) ?
# Set the variable "x" to zero.
x <- 0
# Allocate again for the same binding name "x"
x = (U8) ?
# Also set the new variable "x" to zero with just one Unicode symbol
# that is AltGr+Y on my keyboard.
x ← 0
You can always reset an existing binding at will to another variable litteral and another variable will be created for the same name and it will be in a different memory location, settable once and then read-only again so you can use it without locking.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
# Variables
Variables in C3 can be defined using the litteral value for a variable
which is always `?`. You can cast this litteral value and it will not
really be casted but it will give you a typed variable litteral value.
E.g. `(List) ?`.
The typed variable litteral value will only accept to be set once to
one value of the variable's type (in this example the type of a linked
list).
It's actually a syntax so you cannot rename `?` by mistake and
so is an easy task to do static analysis of variable creation.
The default type for a variable which you can also specify explicitly
is `Tag` which is an enum-tagged union type of any other C3 types
currently defined in the environment. So `?` is exactly equivalent to
`(Tag) ?` and they will both accept to be set once to one value of any
type.
Actually all variables are allocated as tags and in the end the typing
is dynamic but it could be made static through JIT compilation of
functions.
A variable is settable once and cannot be changed afterwards (there is
an exception if you write C code and link to it but it is not easy nor
silent).
This way you do not need to lock or trust any behaviour, once your
variable is set to a value the value of the variable will never change,
it really is read-only.
## Init and C interoperatbility
To set the value of a variable in the end you need to call a C function
that should accept this C function definition :
`quote cfn unquote(type) unquote("init_#{variable_type}#{init_suffix}") (Result, ...)`.
There are many functions for this, here is a quick list :
- `tag_init_1` takes a C string as an argument and returns a value of
any type currently defined in the C3 environment.
- `#{type}_init_1` C functions take a C string as an argument and return
a value of type `type`.
- `tag_init_copy` takes a tag as an argument and returns a deep copy
of it.
You can also use the assignment operator which is `<-` which in turn calls
`tag_init_copy`. It works like the C assignment operator (`=`).
Examples :
```
# Declare a unsigned byte 8 bits variable "x".
x = (U8) ?
# Set the variable "x" to zero.
x <- 0
# Allocate again for the same binding name "x"
x = (U8) ?
# Also set the new variable "x" to zero with just one Unicode symbol
# that is AltGr+Y on my keyboard.
x ← 0
```
## So how do I change anything if it is read-only ?
You can always reset an existing binding at will to another variable
litteral and another variable will be created for the same name and it
will be in a different memory location, settable once and then
read-only again so you can use it without locking.