Data Types
Basic Data Types
L4's basic data types are
Booleans
strings
numbers
records
Booleans
L4's Boolean values are TRUE
and FALSE
. The type of Booleans is called BOOLEAN
.
Strings
Strings are quoted using double-quotes: "Alice Avocado"
is a string. (Note that `Alice Avocado`
is not a string, it is an identifer with a compound name, and if used, its meaning must be defined somewhere in the program.) The type of strings is called STRING
.
Numbers
L4 does not currently distinguish between integers and floats and just has a common type called NUMBER
.
Literal numbers can be written as usual: 333
, 0.25
and -77.2
are examples of valid numbers.
User-Defined Types
Enumerations, or Enums
An enumeration type can be declared as follows:
DECLARE Colour IS ONE OF red
green
blue
This introduces a new type Colour
(distinct from all other types) with exactly three values, which are called red
, green
and blue
.
If you try to use purple
as a Colour
, it will be rejected.
Destructuring with CONSIDER
We pattern-match the possible values of a variable using CONSIDER / WHEN / THEN
:
GIVEN c IS A Colour
DECIDE `is qing` IF
CONSIDER c
WHEN red THEN FALSE
WHEN green THEN TRUE
WHEN blue THEN TRUE
In classical Chinese, blue is 青, but green is also 青.
https://www.lomography.com/magazine/337259-color-chronicles-deconstructing-qing
Type Aliases
We can declare our own types in terms of the above basic types:
DECLARE `count of fruit in my bag` IS A NUMBER
DECLARE `common name of fruit` IS A STRING
DECLARE `scientific name of fruit` IS A STRING
DECLARE `my bag has a hole` IS A BOOLEAN
This creates aliases from a user-defined type to a native type. Aliases are exchangeable with the type they expand to, their primary intent is to provide more descriptive names in specific situations.
Records
Records in L4 are used to group related data together.
Record Definition
Record types are declared using DECLARE ... HAS ... IS A ...
syntax.
DECLARE Person
HAS name IS A STRING
age IS A NUMBER
This introduces a new type Person
(distinct from all other types) comprising two fields, one called name
being a string, and one called age
being a number.
Once the type has been declared, you can instantiate it by defining variables using MEANS
syntax.
There are two ways to give the attributes.
Using WITH ... IS ...
syntax:
alice MEANS
Person WITH name IS "Alice Avocado"
age IS 21
If using WITH ... IS ...
syntax, argument order is flexible, so you could also define:
bob MEANS
Person WITH age IS 20
name IS "Bob Blueberry"
One can also use the shorter Type OF ...
syntax:
alice MEANS Person OF "Alice Avocado", 21
In this case, the arguments have to appear exactly in the order they have been listed in the declaration of the type Person
above, so the name has to come before the age.
You can omit the OF
when the attributes go down the page:
alice MEANS Person "Alice Avocado"
21
Accessing Record Fields
Fields of a record can be accessed using the possessive apostrophe-s ('s
) notation:
GIVEN john IS A Person
GIVETH A STRING
johnsName MEANS john's name
GIVETH A NUMBER
johnsAge MEANS john's age
This is analogous to the use of a dot (.
) used in most other languages for record accessors: john.age
becomes john's age
Algebraic data types
Some types are neither enumeration nor record types, but a combination of the two. (TODO.)
Advanced Concepts
More on these later.
Type-Directed Name Resolution (TDNR)
TDNR allows the same identifier to be in scope multiple times with different types.
ASSUME foo IS A NUMBER
ASSUME foo IS A BOOLEAN
ASSUME foo IS A STRING
Last updated