This is a practical crash course in the style of Learn X in Y Minutes: short explanations and lots of runnable snippets.
Table of Contents
Packages and imports
// Every file starts with a package.
package main
// Imports
import tenecs.go.Main
import tenecs.go.Runtime
// Main wires your app to runtime.
app := Main((runtime: Runtime) => {
runtime.console.log("Hello world!")
})
Values and basic types
package basics
// Use := to create values.
name := "Ada"
isActive := true
count := 3
// Type annotations are optional.
welcome: String = "Hello"
Comments and type aliases
package basics
// Single-line comment
/* Multi-line
comment */
typealias UserId = String
userId: UserId = "user-123"
Functions
package basics
import tenecs.string.join
// (arg: Type): ReturnType => { ... }
greet := (name: String): String => {
join("Hello, ", name)
}
// You can also type a function explicitly.
formatter: (a: String, b: String) ~> String = (a: String, b: String): String => {
join(a, b)
}
// Named arguments are supported.
example := (): String => {
formatter(a = "Ada", b = " Lovelace")
}
Structs and data modeling
package domain
// Structs are typed product types.
struct User(
id: String,
email: String
)
admin := User("1", "admin@example.com")
Lists and generics
package collections
names := <String>["Ada", "Lin"]
// Generic function
identity := <T>(value: T): T => {
value
}
firstName := identity<String>("Ada")
Control flow with if and when
package control
describe := (value: Boolean | String): String => {
when value {
is boolValue: Boolean => {
if boolValue {
"true"
} else {
"false"
}
}
is textValue: String => {
textValue
}
}
}
classify := (value: Boolean | String | Void): String => {
when value {
is text: String => {
text
}
other _rest => {
"not a string"
}
}
}
Syntactic sugar
Tenecs has shortcuts that compile down to regular function calls and when blocks.
Arrow invocation (->)
package sugar
f := (str: String): String => {
str
}
g := (str: String, another: String): String => {
str
}
usage := (): String => {
// Sugar:
"foo"->f()->g("bar")
// Equivalent:
g(f("foo"), "bar")
}
Type-based short-circuit declaration
package sugar
import tenecs.string.join
stringOrInt := (): String | Int => {
3
}
usage := (): String | Int => {
// Sugar: if Int, return early; otherwise continue as String.
str :? Int = stringOrInt()
join(str, "!")
}
// Equivalent:
usageExpanded := (): String | Int => {
when stringOrInt() {
is int: Int => {
int
}
other str => {
join(str, "!")
}
}
}
Tests
package test
import tenecs.test.UnitTest
import tenecs.test.UnitTestSuite
_ := UnitTest("hello unit test", (testkit) => {
testkit.assert.equal("hello", "hello")
})
_ := UnitTestSuite("math suite", (registry) => {
registry.test("one equals one", (testkit) => {
testkit.assert.equal(1, 1)
})
})