Threadon / Examples

Examples

the programs in the repo, explained

Running them

Each example lives in its own folder under examples/. Run one from the project root:

python3 -m threadon --run examples/02_structs/main.th

Numbers below are the exact output of each program.

The examples

01_hello — a first program

The minimal shape of a Threadon program: a helper function, a main, a call, arithmetic, print, and a return 0. Demonstrates functions.

def greet(x: Int32) -> Int32
    return x * 10

def main() -> Int32
    x: Int32 = 21
    print(greet(x) + 1)
    return 0
211

02_structs — a struct in action

A Point struct, a function that takes it, and a call. Demonstrates structs.

struct Point:
    x: Int32
    y: Int32

def length_sq(p: Point) -> Int32
    return p.x * p.x + p.y * p.y

def main() -> Int32
    p: Point = Point(x=3, y=4)
    print(length_sq(p))
    return 0
25

03_imports — a module with two import styles

A math.th module with abs, clamp, and mean. The main file imports it both ways, then calls the same functions through both. Demonstrates imports. Note how clamp and abs use the variable-merging trick from the Variables page.

from math import abs, clamp
import math

def main() -> Int32
    a: Int32 = abs(-5)
    b: Int32 = math.clamp(99, 0, 50)
    c: Int32 = math.abs(-9)
    print(a + b + c)
    return 0
64

04_import_structs — importing structs and functions

A geom.th module that exports Point and a few functions. The main file imports the struct directly and via the module name, then uses the functions. Demonstrates importing structs.

from geom import Point, dot, scale, origin
import geom

def main() -> Int32
    p: Point = geom.Point(x=3, y=4)
    q: Point = scale(2, p)
    o: Point = origin()
    print(dot(p, q) + o.x)
    return 0
50

(dot(Point(3,4), Point(6,8)) is 3×6 + 4×8 = 18 + 32 = 50.)

05_lazyimports — lazy from-import

Imports abs lazily from math.th and uses it once. Demonstrates lazyimport / lazyfrom.

lazyfrom math import abs

def main() -> Int32
    print(abs(-7))
    return 0
7

06_input — reading from the user

Asks for a name and prints a greeting. Demonstrates input. It waits for a line of input.

def main() -> Int32
    name: String = input("What is your name? ")
    print("Hello,")
    print(name)
    return 0
What is your name? Joep Hello, Joep

07_conversion — every kind of cast

Exercises all the casts: int to float, float to int, bool to int, string to int and float, string to bool, and number to bool.

print(Float32(7))       # 7.000000
print(Int32(3.7))      # 3
print(Int32(True))       # 1
print(Int32("123"))   # 123
print(Float32("3.5")) # 3.500000
print(Bool("true"))  # 1
print(Bool("0"))     # 0
print(Bool(7))       # 1
7.000000 3 1 123 3.500000 1 0 1

08_pointer — references and struct fields

A tour of the ^ operator and struct field assignment. It prints what each value is before and after a change.

r = 10 r = 15 x = 15 origin.x = 0 origin.y = 0 origin.x = 3 origin.y = 4

09_zero_division — a runtime check

Reads a number and divides by it. With --debug, entering 0 triggers the runtime check. Demonstrates debug mode.

def main() -> Int32
    x: Int8 = Int8(2)/Int8(input("Enter a number"))
    print(x)
    return 0
python3 -m threadon --run --debug examples/09_zero_division/main.th
Enter a number: 0
[RUNTIME ERROR] │ Error: Division by zero ├─> Location: (null) └─> Process terminated with exit code 1

10_stack_overflow — how the runtime handles deep recursion

Recurses without a base case. The runtime stops it with a stack-depth check. Demonstrates why while and for loops exist.

def stack_overflow(x: Int32) -> NoneType
    stack_overflow(68)
    return
[RUNTIME ERROR] │ Error: stack overflow detected ├─> Location: Runtime stack depth exceeded (max 10000) └─> Process terminated with exit code 1

11_native_c — calling a C function

A C module described by a manifest, imported and called from Threadon. Demonstrates the foreign backends. Needs a C compiler and the module's shared library built.

import cadd

def main() -> Int32
    print(cadd.add(20, 22))
    return 0
42

12_native_cpp — calling a C++ function

Like the C example, but through the C++ backend, which can map C++ classes onto Threadon structs.

import cpppow

def main() -> Int32
    print(cpppow.square(6))
    return 0
36

13_native_rust — calling a Rust function

Rust modules are built with cargo and expose extern "C" functions.

import rsum

def main() -> Int32
    print(rsum.sum(2, 40))
    return 0
42

14_python_example — calling Python

Python functions wrapped into Threadon via the python backend. Passes a list (for mean) and a dict (for describe) to a Python module and prints the results, which come back as Threadon values.

import PyAdd

def main() -> Int32
    print(PyAdd.add(2.0, 23.0))
    print(PyAdd.mean([1.0, 2.0, 3.0]))
    print(PyAdd.describe({"1": 1.0, "2": 2.0, "3": 3.0}))
    return 0
25.000000 2.000000 {1: 2.000000, 2: 4.000000, 3: 6.000000}

15_string_ops — the string features

Joining strings with +, converting numbers and bools to text with String(...), and converting text back with casts. Demonstrates the string and cast pages.

def main() -> Int32
    a: String = "Hello"
    b: String = " World"
    c: String = a + b
    print(c)
    print(String(42))
    print(String(3.14))
    print(String(True))
    print(Int32("123"))
    return 0
Hello World 42 3.140000 true 123

16_python_classes — Python classes as Threadon classes

A Python class wrapped by the python backend and used like a Threadon value, methods included. Needs Python and the bridge installed.

import PyVec3

def main() -> Int32
    v: PyVec3.Vec3 = PyVec3.Vec3(3.0, 4.0, 0.0)
    print(v.length())
    return 0
5.000000

17_for_range — loops, from range to dicts

A tour of the for loop: counting with range in three forms (including a negative step and an empty run), then iterating a List and the keys of a Dict.

def main() -> Int32
    total: Int64 = 0
    for i in range(5):
        print("i =", i)
        total = total + i
    print("sum =", total)
    for j in range(10, 0, -3):
        print("j =", j)
    for k in range(15, 10):
        print("k =", k)  # empty: a step of +1 never reaches 15 from 10
    names: List[String] = ["ann", "bob", "clyde"]
    for name in names:
        print("name =", name)
    ages: Dict[String, Int32] = {"ann": 30, "bob": 40}
    for key in ages:
        print("key =", key, "value =", ages[key])
    return 0
i = 0 i = 1 i = 2 i = 3 i = 4 sum = 10 j = 10 j = 7 j = 4 j = 1 name = ann name = bob name = clyde key = ann value = 30 key = bob value = 40

18_colorama — colors via the colorama module

The bundled colorama module (written in pure Threadon) returns ANSI escape codes. fore, back, and style take a name ("red", "blue", "bright", ...) and return the escape that switches to it; reset and reset_all turn it back off. Concatenate them with the text. The example prints each line in its color, so no output box is given — run it on a terminal to see the effect.

import colorama

def main() -> Int32
    print(colorama.fore("red") + "red text" + colorama.reset())
    print(colorama.fore("green") + colorama.style("bright") + "bright green" + colorama.reset_all())
    print(colorama.back("blue") + "blue background" + colorama.reset())
    print(colorama.fore("lightmagenta") + colorama.style("dim") + "dimmer magenta" + colorama.reset_all())
    print(colorama.fore("yellow") + "yellow text" + colorama.reset_all())
    return 0