Dragon

Built-in Functions

The functions on this page are always in scope - no import needed. They are the workhorses you reach for every day: printing, measuring length, looping over indices, converting between types, and inspecting values. Dragon mirrors Python's names and signatures wherever the typed, compiled model allows, so most of what you know from Python transfers directly.

Every entry in this appendix was verified by compiling and running it against the Dragon compiler. Where a Python builtin is recognized by the grammar but does not yet have a working implementation, it is listed in Not yet available with the exact error - so you always know what is real.

Output and input

FunctionSignatureDescription
printprint(*values) -> NoneWrites each value to stdout, space-separated, ending in a newline.
inputinput(prompt: str = "") -> strPrints the prompt (no newline) and reads one line from stdin.
print("hello")           # hello
print(1, 2, 3)           # 1 2 3

const name: str = input("Name: ")   # reads a line after printing "Name: "
print("Hi " + name)

Length and ranges

FunctionSignatureDescription
lenlen(x) -> intNumber of elements in a str, list, dict, set, tuple, or bytes.
rangerange(stop) / range(start, stop) / range(start, stop, step)A lazy sequence of integers for iteration.
print(len("abc"))        # 3
print(len([1, 2, 3]))    # 3

for i in range(5) {
    print(i)             # 0 1 2 3 4
}

range is an iteration construct, not an annotation type - write for i in range(n), not r: range = range(n). To materialize the values into a list, use a comprehension: const xs: list[int] = [i for i in range(5)].

Type conversion

FunctionSignatureDescription
intint(x) -> intParses a str, or truncates a float, to an integer.
floatfloat(x) -> floatParses a str, or widens an int, to a float.
strstr(x) -> strThe human-readable text form of any value (incl. lists, dicts).
boolbool(x) -> boolTruthiness of a value (see the note below).
bytesbytes() / bytes(n: int) / bytes(xs: list[int])Empty, n zero bytes, or bytes from a list of ints.
print(int("17"))         # 17
print(int(3.9))          # 3
print(float("2.5"))      # 2.5
print(str([1, 2, 3]))    # [1, 2, 3]

bytes("text", "utf-8") is not supported - the two-argument

string-encode form errors. Build bytes via the bytes(list[int]) form or the

io / encoding stdlib instead.

Numeric helpers

FunctionSignatureDescription
absabs(x: int) -> int / abs(x: float) -> floatAbsolute value; the result type matches the argument.
minmin(a, b) / min(xs: list)Smaller of two values, or the minimum of a list.
maxmax(a, b) / max(xs: list)Larger of two values, or the maximum of a list.
sumsum(xs: list)Sum of a list of numbers.
print(abs(-5))           # 5
print(min(3, 1))         # 1
print(max([4, 2, 9]))    # 9
print(sum([1, 2, 3, 4])) # 10

Sequence operations

FunctionSignatureDescription
sortedsorted(xs: list[T]) -> list[T]A new list with the elements in ascending order.
reversedreversed(xs: list[T]) -> list[T]A new list with the elements in reverse order.
enumerateenumerate(xs)Yields (index, value) pairs while iterating.
zipzip(a, b)Yields tuples pairing elements of two sequences.
anyany(xs: list[bool]) -> boolTrue if any element is truthy.
allall(xs: list[bool]) -> boolTrue if every element is truthy.

sorted and reversed return a new list[T]:

const s: list[int] = sorted([3, 1, 2])
print(s)                 # [1, 2, 3]

const r: list[int] = reversed([1, 2, 3])
print(r)                 # [3, 2, 1]

enumerate and zip are used as loop drivers:

for i, v in enumerate([10, 20, 30]) {
    print(i, v)          # 0 10  /  1 20  /  2 30
}

for a, b in zip([1, 2, 3], [10, 20, 30]) {
    print(a, b)          # 1 10  /  2 20  /  3 30
}
print(any([False, True, False]))   # True
print(all([True, False]))          # False

Introspection

FunctionSignatureDescription
isinstanceisinstance(obj, Cls) -> boolWhether obj is an instance of Cls (or a subclass).
reprrepr(x) -> strA debugging representation - strings are quoted.
idid(x) -> intA stable integer identity for the object.
hashhash(x) -> intA hash value for the object.
chrchr(code: int) -> strThe one-character string for a code point.
ordord(ch: str) -> intThe code point of a one-character string.
print(repr("hi"))        # 'hi'
print(repr(42))          # 42
print(chr(65))           # A
print(ord("A"))          # 65

isinstance works for class hierarchies, checking against a base type:

class Animal {
    name: str
    def(n: str) { self.name = n }
}
class Dog(Animal) {
    def(n: str) { super(n) }
}

const d: Animal = Dog("Rex")
print(isinstance(d, Animal))   # True

isinstance against builtin primitive types returns False.

isinstance(5, int), isinstance("x", str), and isinstance(3.0, float)

all return False today - it is reliable only for user-defined class

hierarchies, and only when the runtime value matches (or subclasses) the

type being tested against the declared base.

Number-base formatting

FunctionSignatureDescription
hexhex(n: int) -> strHexadecimal string with a 0x prefix.
octoct(n: int) -> strOctal string with a 0o prefix.
binbin(n: int) -> strBinary string with a 0b prefix.
print(hex(255))          # 0xff
print(oct(8))            # 0o10
print(bin(5))            # 0b101

Collection constructors

FunctionSignatureDescription
setset() / set(xs: list[T]) -> set[T]An empty set, or a set built from a list (dedupes).
dictdict() -> dict[K, V]An empty dictionary.
listlist() -> list[Any]An empty list (typed list[Any]).
const s: set[int] = set([1, 2, 2, 3])
print(s)                 # {1, 2, 3}

const d: dict[str, int] = dict()
print(len(d))            # 0

list() always yields list[Any]. It cannot be assigned to a

concretely-typed binding such as list[int] (you get

cannot assign 'list[Any]' to variable of type 'list[int]'). For a typed

empty list use the literal: const xs: list[int] = []. The list(iterable)

copy form is likewise not yet wired - copy with a comprehension,

[x for x in src].

Numeric and functional builtins

These mirror Python's names in the forms the typed model supports. A few carry a caveat worth knowing, noted in the table.

FunctionSignatureNotes
powpow(base: int, exp: int) -> intInteger power; same as base ** exp.
roundround(x: float) -> intRounds to the nearest integer. The 2-arg round(x, ndigits) form is not available.
divmoddivmod(a: int, b: int) -> tuple[int, int](quotient, remainder).
mapmap(fn, xs) -> listEager: returns a list, not a lazy iterator. A comprehension is the idiomatic form.
filterfilter(fn, xs) -> listEager: returns a list.
tupletuple(iterable) -> tupleBuilds a tuple from an iterable; a list literal argument gives an exact-arity tuple[...].
typetype(x) -> strReturns the type name, e.g. "int", "str", "list".

Not yet available

These names are recognized by the grammar (they highlight as builtins) but do not compile-and-run today. Each was tested; the error is shown so you know exactly where the boundary is.

FunctionStatusError when used
iter, next, getattr, setattr, hasattr, delattr, dir, vars, globals, locals, eval, exec, compile, callable, format, issubclass, slice, frozensetReserved, unverifiedundefined name '...' / Unknown function: ...

The dynamic-reflection names (eval, exec, compile, getattr, setattr, vars, globals, locals) are excluded on purpose: they are the dynamic crutches Dragon rejects, not gaps waiting to be filled. A comprehension ([f(x) for x in xs], [x for x in xs if cond]) is still the idiomatic and faster form even though map/filter now work.

At a glance

You want to...Write
Print valuesprint(a, b, c)
Read a lineconst s: str = input("> ")
Measure sizelen(x)
Loop over indicesfor i in range(n) { ... }
Loop with indexfor i, v in enumerate(xs) { ... }
Pair two sequencesfor a, b in zip(xs, ys) { ... }
Convert to textstr(x)
Parse a numberint(s) / float(s)
Sortconst s: list[T] = sorted(xs)
Reverseconst r: list[T] = reversed(xs)
Dedupe a listset(xs)
Any / all trueany(flags) / all(flags)
Char and codechr(n) / ord(c)
Number basehex(n) / oct(n) / bin(n)
Transform a list[f(x) for x in xs] or map(f, xs)
Filter a list[x for x in xs if c] or filter(f, xs)

For the operators (**, //, in, not in, comparison, bitwise) see the operators appendix; for keywords see the keywords appendix; and for everything behind an import see the stdlib appendix.