Runnable programs from the examples/showcase/ folder. Compile with
lumen compile <file>.ts, or run tests with lumen test.
enum Category { Food, Tool, Book }
interface Item {
name: string;
price: int;
category: Category;
}
function describe(item: Item): string {
return `${item.name}: $${item.price}`;
}
let items: Item[] = [
{ name: "apple", price: 2, category: Category.Food },
{ name: "hammer", price: 15, category: Category.Tool },
{ name: "novel", price: 9, category: Category.Book },
];
let total = 0;
for (const item of items) {
console.log(describe(item));
total += item.price;
}
console.log(`total: $${total}`);
function applyTwice(f: (n: int) => int, v: int): int {
return f(f(v));
}
function triple(x: int): int {
return x * 3;
}
console.log(applyTwice(triple, 2)); // 18
console.log(applyTwice((x: int) => x + 10, 5)); // 25
let clamp: (n: int) => int = (x: int) => x > 100 ? 100 : x;
console.log(clamp(250)); // 100
console.log(clamp(42)); // 42
interface Settings {
host: string;
port?: int;
}
function connect(s: Settings): void {
using _ = defer(() => console.log("connection closed"));
let port = s.port ?? 8080;
console.log(`connecting to ${s.host}:${port}`);
}
function label(name: string | null): string {
if (name != null) {
return name;
}
return "anonymous";
}
connect({ host: "localhost" }); // :8080 + closed
connect({ host: "api.example.com", port: 443 }); // :443 + closed
console.log(label("ada")); // ada
console.log(label(null)); // anonymous
function gcd(a: int, b: int): int {
let x = a;
let y = b;
while (y != 0) {
let t = y;
y = x % y;
x = t;
}
return x;
}
test "gcd computes greatest common divisor" {
expect(gcd(12, 8) == 4);
expect(gcd(17, 5) == 1);
}
// @link m
declare function pow(base: number, exp: number): number;
declare function sqrt(x: number): number;
let hypotSq = pow(3.0, 2.0) + pow(4.0, 2.0);
console.log(sqrt(hypotSq)); // 5
console.log(pow(2.0, 10.0)); // 1024
// The .ts is fetched over HTTPS at compile time and inlined into the build --
// no package manager, no install step. A package is just a URL.
import greet from "https://lumen-lang.org/package/std-contrib/hello/hello.ts";
console.log(greet("world")); // Hello, world!
let nums: int[] = [1, 2, 3, 4, 5, 6];
let evens = nums.filter((n: int) => n % 2 == 0);
let doubled = evens.map((n: int) => n * 2);
let total = doubled.reduce((acc: int, n: int) => acc + n, 0);
console.log(doubled.join(", ")); // 4, 8, 12
console.log(total); // 24
let csv = "ada,grace,linus";
let names = csv.split(",");
for (const name of names) {
console.log(name.toUpperCase()); // ADA / GRACE / LINUS
}
console.log(names.length); // 3
console.log("grace,hopper".includes("grace")); // true
function firstOf<T>(xs: T[]): T {
return xs[0];
}
class Box<T> {
value: T;
constructor(v: T) {
this.value = v;
}
get(): T {
return this.value;
}
}
console.log(firstOf<int>([10, 20, 30])); // 10
console.log(firstOf<string>(["a", "b"])); // a
let boxed = new Box<string>("hello");
console.log(boxed.get()); // hello
type Circle = { kind: "circle", radius: int };
type Square = { kind: "square", side: int };
type Shape = Circle | Square;
function area(s: Shape): int {
switch (s.kind) {
case "circle":
return s.radius * s.radius * 3;
case "square":
return s.side * s.side;
}
return 0;
}
console.log(area({ kind: "circle", radius: 4 })); // 48
console.log(area({ kind: "square", side: 5 })); // 25
class Animal {
protected name: string;
constructor(name: string) {
this.name = name;
}
speak(): string {
return this.name + " makes a sound";
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
speak(): string {
return super.speak() + " (woof)";
}
}
let a = new Animal("Cat");
let d = new Dog("Rex");
console.log(a.speak()); // Cat makes a sound
console.log(d.speak()); // Rex makes a sound (woof)
try {
console.log("parsing");
throw Error("empty port");
console.log("unreached");
} catch (e) {
console.log("caught");
console.log(e.message);
} finally {
console.log("done");
}
// parsing
// caught
// empty port
// done
let scores: Map<string, int> = new Map<string, int>();
scores.set("ada", 90);
scores.set("linus", 85);
scores.set("ada", 95);
console.log(scores.size); // 2
console.log(scores.get("ada")); // 95
console.log(scores.has("linus")); // true
let tags: Set<string> = new Set<string>();
tags.add("red");
tags.add("blue");
tags.add("red");
console.log(tags.size); // 2
console.log(tags.has("blue")); // true
function sum(...nums: int[]): int {
let total: int = 0;
for (const n of nums) {
total = total + n;
}
return total;
}
function greet(name: string, greeting: string = "Hello"): string {
return greeting + ", " + name;
}
let extra: int[] = [4, 5, 6];
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, ...extra)); // 16
console.log(greet("World")); // Hello, World
console.log(greet("World", "Hi")); // Hi, World
async function fetchBase(): Promise<int> {
return 10;
}
async function total(n: int): Promise<int> {
let base: int = await fetchBase();
return base + n;
}
console.log(await fetchBase()); // 10
console.log(await total(5)); // 15
console.log(await total(32)); // 42
// The quickjs package runs JavaScript inside a native Lumen binary and passes
// values both ways. It links a C library, so it is built locally.
import { open, close, setInt, evalNumber, getString } from "./quickjs.ts";
open();
using _ = defer(() => close());
setInt("base", 21);
console.log(evalNumber("base * 2 + Math.sqrt(16)")); // 46
evalNumber("globalThis.greeting = 'hi ' + base");
console.log(getString("greeting")); // hi 21
// A command-line tool: counts words in a file and prints the most frequent.
// Build with `lumen compile wordstats.ts`, then run `./wordstats sample.txt`.
let text = fs.readFileSync(arg(1), "utf8");
let counts: Map<string, int> = new Map<string, int>();
let word = "";
for (const ch of text.toLowerCase().split("")) {
let code = ch.charCodeAt(0);
let isLetter = code >= 97 && code <= 122;
if (isLetter) {
word = word + ch;
} else if (word != "") {
counts.set(word, (counts.get(word) ?? 0) + 1);
word = "";
}
}
console.log(`unique words: ${counts.size}`);
// A typed wrapper over SQLite through the C FFI. A small C shim hides the
// library's out-pointers behind plain functions; the pragmas below link it.
// @link ./sqlite_shim.o
// @link /opt/homebrew/opt/sqlite/lib/libsqlite3.dylib
declare function db_open(path: string): int;
declare function db_exec(sql: string): int;
declare function db_query_int(sql: string): int;
declare function db_query_text(sql: string): string;
db_open(":memory:");
db_exec("CREATE TABLE books (title TEXT, year INT)");
db_exec("INSERT INTO books VALUES ('Crafting Interpreters', 2021)");
console.log(db_query_int("SELECT COUNT(*) FROM books")); // 1
console.log(db_query_text("SELECT title FROM books LIMIT 1")); // Crafting Interpreters