Skip to content

Language Basics

github-actions[bot] edited this page May 2, 2026 · 1 revision

Language Basics

Flow is a statically-typed, interpreted language. Every variable has a type, statements are separated by newlines or semicolons, and comments use either Note: or //.

Comments

Flow accepts two comment styles. Both run from their marker to the end of the line:

Note: This is a comment
// This is also a comment
Int x = 5  Note: inline comment
Int y = 7  // inline comment

Note: must start at the beginning of a line's content. // works anywhere.

Variables

Variables are declared with a type annotation:

Int x = 5
Float pi = 3.14
String name = "Flow"
Bool active = true

Default Values

A variable declared without an initializer takes a type-appropriate default (0, "", false, empty array, etc.):

Int count           Note: count = 0
String message      Note: message = ""
Bool flag           Note: flag = false
Int[] nums          Note: nums = []

Reassignment

Variables can be reassigned after declaration:

Int x = 10
x = 20
x = x + 5
(print (str x))     Note: prints 25

Semicolons

Statements are separated by newlines. Semicolons allow multiple statements on one line:

Int a = 1; Int b = 2; Int c = 3
(print (str a)); (print (str b)); (print (str c))

Primitive Types

Type Description Example
Int 32-bit integer 42
Long 64-bit integer -
Float 32-bit float 3.14
Double 64-bit float 3.14
String Text "hello"
Bool Boolean true, false
Number Arbitrary precision -

Numeric Widening

Flow supports implicit numeric widening:

Int → Long → Float → Double → Number

An Int can be used wherever a Double is expected, for example.

Special (Music) Types

Type Description Example
Note Musical pitch C4, F4+ (F sharp)
Chord Harmonic chord Cmaj7, Dm
Sequence Ordered bars | C4 D4 E4 F4 |
Bar Musical measure -
Section Named song part section intro { ... }
Song Arrangement [intro verse chorus]
Buffer Audio samples -
Semitone Pitch offset +2st
Cent Microtonal offset +50c
Millisecond Time in ms 100ms
Second Time in seconds 2.5s
Decibel Gain in dB +6dB
Beat Musical beat -
NoteValue Note duration -
TimeSignature Meter -
MusicalNote Note with duration -
Voice Positioned audio -
Track Voice collection -
Envelope Amplitude shape -
OscillatorState Running oscillator -

Note Literals

Notes use [A-G][octave][alteration]:

Syntax Meaning
C4 C natural, octave 4 (middle C)
C4+ C sharp, octave 4
C4- C flat, octave 4
C4++ C double sharp
C4-- C double flat

Chord-symbol accidentals use s and f instead (for example, Csmaj7, Bfm). See Chords and Harmony.

Arrays

Arrays are typed collections:

use "@std"

Int[] nums = (list 1 2 3 4 5)
String[] names = (list "Alice" "Bob" "Charlie")

Array indexing uses @:

Int first = nums@0
Int second = nums@1

Plural type names are shorthand for arrays: Ints = Int[], Notes = Note[], etc.

See Collections for full array operations.

Operators

Arithmetic (Binary)

Int sum  = 3 + 4      Note: 7
Int diff = 10 - 3     Note: 7
Int prod = 5 * 6      Note: 30
Int quot = 15 / 4     Note: 3 (integer division)

Flow has no negative number literal: write (sub 0 5) to get -5.

Arithmetic (Function-style)

use "@std"

Int sum  = (add 3 4)
Int diff = (sub 10 3)
Int prod = (mul 5 6)
Int quot = (div 15 4)

Comparison

Comparisons are function calls:

use "@std"

Bool eq  = (equals 5 5)     Note: true
Bool lt  = (lt 3 5)          Note: true
Bool gt  = (gt 10 5)         Note: true
Bool lte = (lte 3 3)         Note: true
Bool gte = (gte 5 3)         Note: true
Bool seq = (sequals 5 5)     Note: strict equals (types must match)

Logical

use "@std"

Bool a = (and true false)    Note: false
Bool b = (or true false)     Note: true
Bool c = (not true)          Note: false

and and or support lazy evaluation with Lazy arguments for short-circuiting.

String Concatenation

use "@std"

String greeting = (concat "Hello, " "World!")

For dynamic labels, prefer string interpolation: $"x is {x}".

Control Flow

Conditional (if)

if is a function that takes a boolean and two lazy expressions. You must wrap both branches with lazy ():

use "@std"

Int x = 10

Note: returning a value
String result = (if (gt x 5) lazy ("big") lazy ("small"))
(print result)    Note: "big"

Note: side-effect branches
(if (gt x 5) lazy ((print "big")) lazy ((print "small")))

Without lazy, arguments are eagerly evaluated and the overload won't match.

Loops

Flow supports for and while loops with break and continue:

use "@std"

Int sum = 0
for Int n in (list 1 2 3 4 5) {
    sum = sum + n
}

Int count = 0
while (lt count 5) {
    count = count + 1
}

See Loops for the full reference.

Lazy Evaluation

lazy (expr) creates a deferred value (a thunk) that is not evaluated until forced with eval:

use "@std"

Lazy<Void> deferred = lazy ((print "hello"))
Note: nothing printed yet
(eval deferred)    Note: now prints "hello"

if, and, and or accept Lazy parameters to enable short-circuit evaluation.

String Interpolation

Prefix a string with $ and wrap expressions in { }:

use "@std"

Int x = 42
(print $"x is {x}")               Note: x is 42

Int a = 3
Int b = 4
(print $"sum is {a + b}")         Note: sum is 7

See String Interpolation for details.

Type Annotations for Functions

Function type annotations use parenthesized arrow syntax:

(Int => Int) doubler = fn Int n => (mul n 2)
(Int, Int => Int) adder = fn Int a, Int b => (add a b)
(Void => Int) constant = fn => 42

Type Aliases

Any type name ending in s refers to the array form: Ints = Int[], Strings = String[], Voids = Void[], Notes = Note[], etc.

Scoping

Variables declared inside blocks (functions, musical context blocks, sections, loops) are scoped to that block. Inner scopes can access variables from outer scopes.

See Also

Clone this wiki locally