TorbScript in 10 Ideen
Die zehn Ideen, die TorbScript ausmachen, je ein kurzes Beispiel, für alle, die schon programmieren und die Gestalt der Sprache in fünf Minuten wollen.
TorbScript ist eine statisch typisierte Sprache für Skripte, Werkzeuge und Server, mit Wertsemantik, ohne null und
ohne Exceptions. Ein Befehl, torb, führt eine Datei sofort aus und baut dasselbe Programm zu einem schnellen
nativen. Das sind die zehn Ideen dahinter, jede mit einem kurzen Beispiel und einem Link auf die Station der
Tour, die weitergeht.
Ziel#
Nach dieser Seite kennst du die Gestalt von TorbScript und weißt, wo die Tour, die Referenz und der Spickzettel jede Idee aufgreifen.
1. Ein zweiter Name ist eine Kopie#
const original = [1, 2]
var copy = original
copy.append 3
print "{original} {copy}"
// prints [1, 2] [1, 2, 3]Jeder Typ ist ein Wert: Listen, Maps und deine eigenen Typen. Zwei Namen teilen sich nie einen Wert, also ändert sich ein Wert nur dort, wo du ihn änderst. Die Kopie ist billig, weil der Speicher geteilt bleibt, bis eine Seite schreibt. Siehe Bindungen.
2. Jede Änderung ist markiert#
const numbers = [1, 2, 3]
numbers.append 4
// error: `append` needs a `var`Die Bindung entscheidet, ob sich ein Wert ändern kann: const nie, var schon. Ein Feld, das sich ändert, ist ein
var-Feld, und eine Methode, die ihren Wert ändert, ist eine var fn. Es gibt keine MutableList: Eine var-Liste
ist eine. Siehe Typen und Methoden.
3. Ein Aufruf liest sich wie ein Befehl#
print "Hello"
const count = [1, 2, 3].length()
print(count + 1)
// prints Hello
// prints 4Ein Aufruf am Anfang einer Zeile lässt seine Klammern weg. Sie bleiben, wo sie nötig sind, und torb format schreibt
sie für dich. Siehe Aufrufe ohne Klammern.
4. Ein Wert ist einer seiner Fälle, und ein match behandelt alle#
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 ist das eine Schlüsselwort für Daten. Kommt später ein Fall dazu, kompiliert jedes match, dem er fehlt, nicht
mehr, und zwar an der Zeile, die einen neuen Zweig braucht. Siehe Fälle und match.
5. Kein null#
const ages = ["Ada": 36]
print(ages.get("Ada") ?? 0)
print(ages.get("Alan") ?? 0)
// prints 36
// prints 0Ein Wert, der fehlen kann, hat einen Option-Typ, Int?, und der Compiler lässt dich den fehlenden Fall behandeln.
?? gibt den Ersatzwert, ?. greift in den Wert, wenn es einen gibt. Siehe Kein null.
6. Keine Exceptions#
match Int.tryFrom("forty-two") {
Ok(number) => print number
Fail(_) => print "That is not a number."
}
// prints That is not a number.Eine Funktion, die scheitern kann, gibt ein Result zurück, und ein Fehlschlag ist eine Antwort wie jede andere. Ein
? nach einem Aufruf gibt ein Fail mit einem Zeichen an den Aufrufer zurück. Siehe
Keine Exceptions.
7. Traits statt Vererbung#
trait Area {
fn area(): Float
}
type Square with Area {
side: Float
fn area(): Float {
side * side
}
}
print Square(2.0).area()
// prints 4.0Es gibt keine Klassen und keine Vererbung. Was ein Typ kann, ist ein Trait, gegeben mit with oder später mit
extend, und ein Trait funktioniert als Typ. Siehe Traits statt Vererbung.
8. Verben ändern, Partizipien kopieren#
const names = ["Grace", "Ada"]
const more = names.appended "Alan"
print more.filter({ _.byteLength() > 3 }).map({ _.toUpperCase() }).toList()
// prints ["GRACE", "ALAN"]append ändert ein var an Ort und Stelle, appended gibt eine geänderte Kopie zurück und funktioniert auf einem
const. filter und map sind faul: Nichts läuft, bis ein letzter Schritt wie toList() die Werte durchzieht.
Siehe Listen, Maps und Pipelines.
9. Deine eigenen Konstrukte sind Funktionen#
fn twice(body: () => Void) {
body()
body()
}
twice {
print "hello"
}
// prints hello
// prints helloEine Closure als letztes Argument folgt dem Aufruf, also ist eine neue Kontrollstruktur eine gewöhnliche Funktion. Der Typ eines Parameters entscheidet, wie sein Argument gelesen wird, und das reicht auch für Konfigurationsblöcke: keine Makros, keine Annotationen. Siehe Kontrollfluss und eigene Konstrukte.
10. Warten ist ein Typ, kein Schlüsselwort#
fn double(value: Int): Task<Int> {
spawn { value * 2 }.await()
}
print double(21).await()Eine Funktion, die einen Task zurückgibt, darf darin await() aufrufen, so wie eine, die ein Result zurückgibt,
? benutzen darf. Ein Task läuft auf einem Pool von Workern und bekommt eine Kopie von allem, was er mitnimmt, also
teilen sich zwei Tasks nie eine Variable. Siehe Tasks.
Weiter#
- Eine Tour durch TorbScript - dieselben Ideen in fünfzehn Minuten, mit dem, was jede in der Praxis heißt.
- Installieren und ausführen - TorbScript auf deinem eigenen Computer, und dein erstes Projekt.
- Syntax cheat sheet - jede Form der Sprache auf einer Seite, beim Schreiben.