Chapter 6 Definitions

Table of Contents
Overview
Functions, Procedures, and Operators
Definitions

Overview

Definitions declare new types that can be used throughout a program. Types can have properties, methods, and nested definitions.

Functions, Procedures, and Operators

A routine is introduced by one of three keywords, and that keyword — not the spelling of the name — decides how the routine behaves:

The three identifier forms from the lexical chapter — alphanumeric, operator-character, and single-quoted string identifiers — are interchangeable as names here. A function may be named with operator characters, and an operator may be named with letters or a quoted string; what makes one a function and the other an operator is the declaration keyword, never the first character of the name.


function 'add seven'(n: int) returns int      ; string-named function
    n + 7

function ++(n: int) returns int               ; operator-char-named function
    n + 1

let a 'add seven'(35)                          ; applied prefix -> 42
let b ++(41)                                   ; applied prefix -> 42
    

Operators may be declared at the top level, not only as members of a type. Like functions, they accept any of the three name forms:


operator <+>(left: int, right: int) returns int    ; operator-char name
    left + right

operator 'divided by'(left: int, right: int) returns int   ; quoted name
    left / right

let c 40 <+> 2              ; infix -> 42
let d 84 'divided by' 2     ; infix -> 42
    

Built-in arithmetic, comparison, and logical operators carry their usual precedences. A custom operator with a text or single-quoted name binds most weakly of all — at the same level as || — so the built-in arithmetic in an expression combines before it. For example, given the 'minus' operator above, 20 'minus' 3 + 5 parses as 20 'minus' (3 + 5) and yields 12.

Definitions

Definitions declare new types that can be used throughout a program.

Structure Definitions

The define keyword creates a new structure type with named properties.

InputResult
define Point(x: int, y: int)
Point(3, 4)
{"_type":"Point","x":3,"y":4}
define Point(x: int, y: int)
Point(3, 4).x
3
define Point(x: int, y: int)
let p Point(3, 4)
p.x + p.y
7
define Point(x: int, y: int)
define Rectangle(origin: Point, width: int, height: int)
Rectangle(Point(0, 0), 10, 5).width
10

Union Definitions

Unions define types with multiple variants. Each variant can optionally carry a value.

InputResult
define Option union(Some: int, None)
Some(5)
{"_type":"Option","_variant":"Some","value":5}
define Option union(Some: int, None)
None
{"_type":"Option","_variant":"None"}
define Result union(Ok: int, Err: String)
Ok(42)
{"_type":"Result","_variant":"Ok","value":42}
define Result union(Ok: int, Err: String)
Err("error")
{"_type":"Result","_variant":"Err","value":"error"}
define Option union(Some: int, None)
Option.Some(5).value
5

Function Names

A routine's role is set by its declaration keyword, not by how its name is spelled. A function may be named with ordinary letters, with a single-quoted string identifier (which may contain spaces), or with operator characters; in every case it is an ordinary function, applied by writing its name before a parenthesized argument.

InputResult
function 'add seven'(n: int) returns int
    n + 7
'add seven'(35)
42
function ++(n: int) returns int
    n + 1
++(41)
42

Operator Definitions

The operator keyword declares an operator, applied infix between its two operands. Like functions, operators may be named with operator characters or with a text or single-quoted name. Operators may be declared at the top level, not only inside a type. A text-named operator binds more weakly than the built-in arithmetic operators, so the arithmetic combines first.

InputResult
operator <+>(left: int, right: int) returns int
    left + right
40 <+> 2
42
operator 'plus'(left: int, right: int) returns int
    left + right
40 'plus' 2
42
operator 'divided by'(left: int, right: int) returns int
    left / right
84 'divided by' 2
42
operator 'minus'(left: int, right: int) returns int
    left - right
20 'minus' 3 + 5
12