EK9 in Depth

Built-in Types at a Glance

Every type here is in the org.ek9.lang module and needs no references. This appendix is a map, one line per type; the authority for any one of them is the compiler's own help, ek9 -h <Type>, which lists every constructor, method and operator of the type and is generated from the runtime. ek9 -H lists every keyword, the built-in types among them. Every type is tri-state: it can be set, unset or absent, and ? asks whether it is set (Values and the Three States). Collections are the one place where that differs by type: a list or dictionary is set the moment it exists, empty or not.

Values

Type What it is Written as
Boolean logical true or false; and, or, xor, not true, false
Character one Unicode character 'A', '\n'
String Unicode text; +, length, contains, matches "hello", `Hello ${name}`
Integer 64-bit signed whole number; overflow gives unset, never a wrapped value 42, 0x1F, 1_000
Float 64-bit IEEE 754; <~> is the fuzzy comparison 3.25, -2.5e10
Money exact decimal currency, so never a Float 25.99#GBP
Bits variable-length bit sequence; and, or, xor, ~, shifts; + joins 0b1010
Byte unsigned 8-bit value with no arithmetic; out of range is unset Byte(255)
Bytes immutable binary data; the literal is hex digits in pairs 0yDEADBEEF
BytesBuilder the mutable write side of Bytes BytesBuilder()
BytesReader forward-only cursor over Bytes; a read past the end is unset aBytes.reader()
Colour RGB or ARGB colour #FF5500
Dimension a size with its unit 42.5km, 1920px
Resolution dots per inch or per centimetre 300dpi, 118dpc
Locale language and region Locale("en_GB")
Version semantic version 1.2.3-0
GUID a UUID; GUID() makes a new one GUID()
RegEx a regular expression with its own literal /[a-z]+/
Path a JSONPath, an address into structured data and not a file path $?.store.book[0].title
Void "no return value" in a signature; not a variable type

One program holds a literal of every type that has one, and prints each. It is the quickest way to see the forms:

#!ek9
defines module book.types.literals

  defines program

    Literals()
      stdout <- Stdout()

      truth <- true
      letter <- 'A'
      text <- "hello"
      count <- 1_000
      hexCount <- 0x1F
      ratio <- 3.25
      bits <- 0b1010
      octets <- 0yDEADBEEF
      shade <- #FF5500
      day <- 2024-01-15
      moment <- 2024-01-15T10:30:00Z
      clockTime <- 10:30:00
      span <- PT1H30M
      short <- 500ms
      price <- 25.99#GBP
      distance <- 42.5km
      density <- 300dpi
      locale <- Locale("en_GB")
      release <- 1.2.3-0
      address <- $?.store.book[0].title
      pattern <- /[a-z]+/
      names <- ["Ada", "Grace"]
      ages <- {"Ada": 36, "Grace": 85}

      stdout.println(`boolean ${truth}, character ${letter}, string ${text}`)
      stdout.println(`integer ${count}, hexadecimal ${hexCount}, float ${ratio}`)
      stdout.println(`bits ${bits}, bytes ${octets}, colour ${shade}`)
      stdout.println(`date ${day}, datetime ${moment}, time ${clockTime}`)
      stdout.println(`duration ${span}, millisecond ${short}, money ${price}`)
      stdout.println(`dimension ${distance}, resolution ${density}, locale ${locale}`)
      stdout.println(`version ${release}, path ${address}, regex ${pattern}`)
      stdout.println(`list ${names}, dict ${ages}`)
boolean true, character A, string hello
integer 1000, hexadecimal 31, float 3.25
bits 1010, bytes DEADBEEF, colour #FF5500
date 2024-01-15, datetime 2024-01-15T10:30:00Z, time 10:30:00
duration PT1H30M, millisecond 500ms, money 25.99#GBP
dimension 42.5km, resolution 300dpi, locale en_GB
version 1.2.3-0, path $?.store.book[0].title, regex [a-z]+
list ["Ada", "Grace"], dict {Ada=36, Grace=85}

Three of the forms surprise people from other languages. Money is written with the currency after the amount, 25.99#GBP; a bare version such as 1.2.3 does not parse, because the literal always carries its build number (1.2.3-0); and a locale has no literal - it is made with Locale("en_GB"). The values on the right of the table are the ones the example above compiles.

Time

Type What it is Written as
Time time of day 10:30:00
Date calendar date 2024-01-15
DateTime date and time with a zone 2024-01-15T10:30:00Z
Duration a span, ISO 8601 PT1H30M
Millisecond a short span in milliseconds 500ms
SystemClock the system time source; the implementation of the Clock trait; a test supplies a fixed clock SystemClock()

Collections and containers

Type What it is
List of T ordered, indexable; [1, 2, 3]; += adds
Dict of (K, V) key to value; {"a": 1}; iterating yields DictEntry
DictEntry of (K, V) one pair from a dictionary; key() and value()
PriorityQueue of T heap ordered by <=>, so T must be comparable
Iterator of T lazy sequence; hasNext() before next(); a stream source
Optional of T zero or one value; get() only in a checked block (Optional and Result, in Depth)
Result of (O, E) an ok value, an error value, both or neither (Optional and Result, in Depth)

Input, output and the system

Type What it is
Stdout, Stderr println and print; accept anything with a $ operator
Stdin standard input as lines; hasNext() and next(), and a stream source
TextFile set only when its path is absolute and names an existing file; opened for input() or output() in a try
FileSystem cwd() and tmp(), each a FileSystemPath
FileSystemPath a platform-independent path, with the file operations
JSON a JSON document; JSON().parse(text) gives a Result of (JSON, String), and $$ serialises any type
GetOpt command-line option parser
OS process id, delay, non-cryptographic random numbers
EnvVars environment variables, sanitised by default; sensitiveGet returns a Sensitive
Signals operating-system signal handlers
Exception the base of every exception, open for your own; reason() and exitCode() (Errors and Exceptions)

Network, concurrency and security

Type What it is
TCP, UDP sockets, both made in a try from a NetworkProperties (Networking: TCP and UDP)
MutexLock of T mutual exclusion around a value, entered with a MutexKey of T (Concurrency, Safely)
Digest unkeyed SHA256 and SHA512: integrity only
HMAC a keyed code over Bytes: integrity and authenticity
SecureRandom cryptographically secure random octets as Bytes, deliberately not a Random
InputSanitizer what the sanitized modifier uses; write sanitized, not a call (A Web Service, Step by Step)

When a type you expect from another language is missing from the tables, look for the operator before you look for a type: a == b, a <=> b, $ a, #? a and target :=: source stand where equals, compareTo, toString, hashCode and clone would (Operators and Pragmatic Purity, in Full), and ek9 -h <Type> prints the constructors, so there is never a need to guess whether a type can be made from a String.