Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Values & Literals

This chapter covers the literal forms you can write directly in source code.

Integers

Integer literals are written as decimal digits. Negative integers use a leading minus sign attached to the literal. At compile time integers have arbitrary precision; at runtime they default to int64_t (signed 64-bit).

The type system supports sized integers via Int' (signed) and UInt' (unsigned) constructors that take a bit width: Int' 8, Int' 32, UInt' 64, etc. Width 0 means arbitrary precision (auto-promotes to bignum on overflow). The prelude provides aliases: Int = Int' 0, UInt = UInt' 0, Byte = UInt' 8.

small = 42
zero = 0
negative = -3
big = 2 ** 32
build =  {target = c, os = linux, arch = x86_64}
small = 42
zero = 0
negative = -3
big = 4294967296

Floats

Floating-point literals require digits on both sides of the decimal point. They default to C double (64-bit). Negative floats use a leading minus sign. Sized floats are available via Float': Float' 32 for single precision, Float' 64 for double precision. The prelude alias Float = Float' 64.

pi = 3.14
half = 0.5
neg = -2.718
__p_neg = <closure>
build =  {target = c, os = linux, arch = x86_64}
pi = 3.14
half = 0.5

Strings

Strings are double-quoted and support the escape sequences \n, \t, \\, and \".

greeting = "hello, world"
escaped = "line one\nline two"
length = len greeting
build =  {target = c, os = linux, arch = x86_64}
greeting = hello, world
escaped = line one
line two
length = 12

Triple-Quoted Strings

Triple-quoted strings span multiple lines with automatic margin stripping (Swift-style). The indentation of the closing """ defines the margin — everything to the left of that column is removed.

msg = """
  Hello, world!
    indented line
  """
build =  {target = c, os = linux, arch = x86_64}
msg = Hello, world!
  indented line

Booleans

There is no dedicated boolean type. Milang uses integers: 1 is true, 0 is false. Comparison and logical operators return 1 or 0, and if treats 0 as false and any non-zero value as true.

yes = 1
no = 0
check = 3 > 2
build =  {target = c, os = linux, arch = x86_64}
yes = 1
no = 0
check = 1

Lists

Lists are linked-list cons cells declared in the prelude as List = {Nil; Cons head tail}. The literal syntax [1, 2, 3] desugars into a chain of Cons/Nil records. The cons operator : is right-associative.

nums = [1, 2, 3]
empty = []
consed = 10 : 20 : 30 : []
build =  {target = c, os = linux, arch = x86_64}
nums = [1, 2, 3]
empty = []
consed = [10, 20, 30]

See the Lists chapter for the full prelude API.

Records

A record is a set of named fields enclosed in braces and separated by ; or newlines.

point = {x = 3; y = 4}
access = point.x + point.y
build =  {target = c, os = linux, arch = x86_64}
point =  {x = 3, y = 4}
access = 7

See the Records & ADTs chapter for updates, destructuring, and algebraic data types.

Constructors

An uppercase name applied to arguments creates a tagged record. Tags are introduced by ADT declarations or used ad-hoc.

Shape = {Circle radius; Rect width height}
c = Circle 5
r = Rect 3 4
build =  {target = c, os = linux, arch = x86_64}
Shape = _module_ {Circle = <closure>, Rect = <closure>}
Circle = <closure>
Rect = <closure>
c = Circle {radius = 5}
r = Rect {width = 3, height = 4}

Functions as Values

Functions are first-class values. They can be bound to names, passed as arguments, and returned from other functions. A function that has not received all of its arguments displays as <closure>.

add x y = x + y
inc = add 1
result = inc 10
build =  {target = c, os = linux, arch = x86_64}
add = <closure>
inc = <closure>
result = 11

See the Functions chapter for lambdas, pipes, and more.