TorbScript in 10 ideas
The ten ideas that make TorbScript what it is, one short example each, for somebody who programs already and wants the shape of the language in five minutes.
TorbScript is a statically typed language for scripts, tools and servers, with value semantics, no null and no
exceptions. One command, torb, runs a file at once and builds the same program into a fast native one. These are the
ten ideas behind it, each with a short example and a link to the stop of the tour that goes on.
Goal#
After this page you know the shape of TorbScript, and where the tour, the reference and the cheat sheet pick up each idea.
1. A second name is a copy#
const original = [1, 2]
var copy = original
copy.append 3
print "{original} {copy}"
// prints [1, 2] [1, 2, 3]Every type is a value: lists, maps and your own types. Two names never share one value, so a value changes only where you change it. The copy is cheap, because the storage is shared until one side writes. See Bindings.
2. Every change is marked#
const numbers = [1, 2, 3]
numbers.append 4
// error: `append` needs a `var`The binding decides whether a value can change: const never does, var can. A field that changes is a var field,
and a method that changes its value is a var fn. There is no MutableList: a var list is one. See
Types and methods.
3. A call reads like a command#
print "Hello"
const count = [1, 2, 3].length()
print(count + 1)
// prints Hello
// prints 4A call at the start of a line drops its parentheses. They stay where they are needed, and torb format writes them
for you. See Calls without parentheses.
4. A value is one of its cases, and a match handles all of them#
type Shape {
case Circle(radius: Float)
case Square(side: Float)
}
const shape = Shape.Square 2.0
match shape {
.Circle(radius) => print(3.0 * radius * radius)
.Square(side) => print(side * side)
}
// prints 4.0type is the one keyword for data. Add a case later, and every match that misses it stops compiling at the line
that needs a new arm. See Cases and match.
5. No null#
const ages = ["Ada": 36]
print(ages.get("Ada") ?? 0)
print(ages.get("Alan") ?? 0)
// prints 36
// prints 0A value that may be missing has an Option type, Int?, and the compiler makes you handle the missing case. ??
gives the fallback, ?. reaches into the value if there is one. See No null.
6. No exceptions#
match Int.tryFrom("forty-two") {
Ok(number) => print number
Fail(_) => print "That is not a number."
}
// prints That is not a number.A function that can fail returns a Result, and a failure is an answer like any other. A ? after a call hands a
Fail back to the caller in one character. See No exceptions.
7. Traits instead of inheritance#
trait Area {
fn area(): Float
}
type Square with Area {
side: Float
fn area(): Float {
side * side
}
}
print Square(2.0).area()
// prints 4.0There are no classes and no inheritance. What a type can do is a trait, given with with or later with extend, and
a trait works as a type. See Traits instead of inheritance.
8. Verbs change, participles copy#
const names = ["Grace", "Ada"]
const more = names.appended "Alan"
print more.filter({ _.byteLength() > 3 }).map({ _.toUpperCase() }).toList()
// prints ["GRACE", "ALAN"]append changes a var in place, appended returns a changed copy and works on a const. filter and map are
lazy: nothing runs until a last step such as toList() pulls the values through. See
Lists, maps and pipelines.
9. Your own constructs are functions#
fn twice(body: () => Void) {
body()
body()
}
twice {
print "hello"
}
// prints hello
// prints helloA closure as the last argument follows the call, so a new control structure is an ordinary function. The type of a parameter decides how its argument is read, and that is enough for configuration blocks too: no macros, no annotations. See Control flow and your own constructs.
10. Waiting is a type, not a keyword#
fn double(value: Int): Task<Int> {
spawn { value * 2 }.await()
}
print double(21).await()A function that returns a Task may await() inside, the way one that returns a Result may use ?. A task runs on
a pool of workers and gets a copy of what it captures, so two tasks never share a variable. See
Tasks.
Next#
- A tour of TorbScript - the same ideas in fifteen minutes, with what each one means in practice.
- Install and run - TorbScript on your own computer, and your first project.
- Syntax cheat sheet - every form of the language on one page, while you write.