All docsLanguage tour

Language tour

The full grammar, in the order a working program actually uses it: values, control flow, functions, shapes, and error handling.

Venutian reads like English on purpose. This tour walks the grammar in the order a working program actually uses it: values first, then control flow, then functions, then records, then errors.

Values

Venutian has eight core types: Integer, Number, Text, Truth, Nothing, List, Function, and one type per declared shape. There is no Dictionary, Tuple, or Set literal built into the core syntax, and Truth is never numeric.

venutian
age = 30
price = 19.99
name = "Ada"
found = yes
nothing_here = nothing
numbers = [1, 2, 3, 4, 5]

A Number with no fractional part always prints with one decimal place, so 4.0, never 4.

Lists are a reference type, shared when you assign them, not copied:

venutian
a = [1, 2, 3]
b = a
b[0] = 99
print a
print b
output
[99, 2, 3]
[99, 2, 3]

Reassigning a = [7] afterward rebinds the name a only; it never touches whatever b points at.

Operators

venutian
print 2 + 3 * 4
print power(2, 10)
print 7 / 2
print quotient_and_remainder(7, 2)
output
14
1024
3.5
[3, 1]

/ always produces a Number, even Integer divided by Integer. There is no ** operator (exponentiation is the power builtin), no //, and no bitwise operators. Equality with == is structural for List and shape values, not by identity, and there is no is operator at all.

Text

venutian
name = "Ada"
print name[0]
print length(name)
print uppercase(name)
print trimmed("  hi  ")
print name + " Lovelace"
output
A
3
ADA
hi
Ada Lovelace

Text takes double quotes only. There is no slicing; build a substring from length, indexing, or split_text instead.

Control flow

when / otherwise when / otherwise replace if / elif / else, with no parentheses and no colon:

venutian
score = 82

when score >= 90
    print "A"
otherwise when score >= 80
    print "B"
otherwise
    print "C"
output
B

Loops are repeat for x in y and repeat while condition, with stop for break and skip for continue:

venutian
repeat for n in [1, 2, 3]
    when n == 2
        skip
    print n
output
1
3

Pattern matching with choose

choose evaluates one subject expression once and compares it against each is pattern in turn, which reads cleaner than a chain of when/otherwise when for the same value:

venutian
make describe(day)
    choose day
        is 1
            give "Monday"
        is 6
            give "Saturday"
        is 7
            give "Sunday"
        otherwise
            give "a weekday"

repeat for day in [1, 3, 6, 7]
    print describe(day)
output
Monday
a weekday
Saturday
Sunday

choose also works directly on Text and List subjects, as well as Integer.

Functions

make declares a function, give hands back a result. Every top level make is registered before any statement runs, so a function can call another one declared later in the same file.

venutian
make greet(name)
    give "Hello, " + name

print greet("world")
output
Hello, world

Type annotations in a parameter list document intent for the reader and feed the tooling: venutian tools and the language server read them (see the CLI).

Shapes

shape declares a plain, positionally constructed, mutable data record. A shape supports single inheritance with inherits, but has no methods and no self; a shape holds data, and ordinary make functions take the record as an explicit first argument.

venutian
shape Person
    name: Text
    job: Text
    pay: Integer

bob = Person("Bob Smith", "developer", 50000)
print bob.name
print bob.job
output
Bob Smith
developer

Composition, one shape's field holding another shape, covers most of what Python reaches for inheritance to do. See types and shapes for inherits.

Errors

attempt / rescue replaces try / except, with exactly one rescue clause and no finally:

venutian
attempt
    result = 10 / 0
    print result
rescue e
    print "caught:", e
output
caught: Division by zero.

Every built in runtime fault surfaces to rescue as plain Text. Raising your own structured value, a shape instance carrying fields like .message and .field, is Venutian's answer to Python's class exceptions; see concurrency for how a fault inside a spawned task surfaces at await the same way.

Comments

A line starting with :: is a comment, discarded entirely, never captured anywhere. The one exception is a tool make's leading string statement, which is captured as a docstring; see the CLI's venutian tools.

Modules

use "path.ven" splices another file's make/tool make/shape declarations into the current file at compile time, resolved relative to the file containing the use. It is not a runtime import: the top level code of a file brought in with use, including any print, never executes.

venutian
:: utils/mathy.ven
make double(n)
    give n * 2

:: main.ven
use "utils/mathy.ven"
print double(21)
shell
venutian run main.ven
output
42

Every name declared in a file brought in with use arrives unqualified, directly in your file's namespace; there is no module.function() syntax, because there is no module object at runtime. See modules for the full story.

Where to go next