Just a note: some of the below code is already not following “good” practices as the language updates to have better ergonomics. I will update these examples as the core language stabilizes.
protocol Measurement {
func measure() -> Int
func is_zero() -> Bool { return self.measure() == 0 }
}
protocol CopyableMeasurement: Measurement, Copyable {}
struct Reading: CopyableMeasurement {
let value: Int
func measure() -> Int { return self.value }
}
func total<T: Measurement, const N: Int>(_ values: borrowing [T; N]) -> Int {
var sum = 0
for index in 0..<N { sum += values[index].measure() }
return sum
}
func main() -> Int {
let values = [Reading(value: 60), Reading(value: 7)]
let answer = total(values)
assert(!values[0].is_zero())
print(answer)
return answer
}
Views
import core
import text
// This function was made before the Char type was avaliable.
func tokens(_ src: borrowing text.View) -> core.Buffer<ReadSpan<u8>> from src {
let bytes = text.bytes(src)
var words = core.buffer<ReadSpan<u8>>(capacity: 4)
var start = 0
var index = 0
while index <= bytes.count {
if index == bytes.count || bytes[index] == u8(' ') {
if index > start {
if let word = core.slice_read<u8>(bytes, start: start, count: index - start) {
words.append(word)
}
}
start = index + 1
}
index += 1
}
return consume words
}
// A scoped struct is one that's allowed to have borrowed views. It is less flexible than a regular struct.
// I am still working out the semantics on scoped structs.
scoped struct Longest {
let word: ReadSpan<u8>
let position: Int
}
// The longest word keeps viewing the same text; the buffer can be dropped first.
func longest(_ words: borrowing core.Buffer<ReadSpan<u8>>) -> Longest from words {
let view = words.span()
var best = 0
for position in 1..<view.count {
if view[position].count > view[best].count { best = position }
}
return Longest(word: view[best], position: best)
}
Closures and Explicit Captures
import core
func apply<F: Call<(Int) -> Int>>(_ f: borrowing F, _ n: Int) -> Int { return f(n) }
func mutate<F: ?Owned & CallMut<() -> Void>>(_ f: inout F) { f() }
func main() -> Int {
let add = { [offset = 60] (n: Int) -> Int in return offset + n }
assert(apply(add, 7) == 67)
// The same callback, its signature taken from apply's bound.
let offset = 60
assert(apply({ [offset] n in offset + n }, 7) == 67)
let erased = Ref<any Call<(Int) -> Int>>(borrow add)
assert(erased.pointee(7) == 67)
var value = 60
var increment = { [target = inout value] mutating () -> Void in target.pointee += 7 }
mutate(&increment)
print(value)
let concrete = core.unique({ [value = value] consuming () -> Int in return value })
let once = Unique<any CallOnce<() -> Int>>(consume concrete)
assert((consume once)() == 67)
return 0
}
Composable Generators
import core
// Lazy sequences with generators. A call creates a suspended frame; each next() runs
// it to its next `yield`. `for x in consume` drives any core.Iterator, and dropping a
// generator early runs the cleanup of wherever it is suspended.
struct Lantern { let city: StaticString; let toll: Int; deinit { print(self.city) } }
func fibonacci(below limit: Int) -> yields Int {
var a = 0
var b = 1
while a < limit {
yield a
let next = a + b
a = b
b = next
}
}
// Generators compose: this one consumes any iterator of Int.
func evens<I: core.Iterator>(_ source: I) -> yields Int where I.Element == Int {
for value in consume source {
if value % 2 == 0 { yield value }
}
}
// Borrowed parameters stay borrowed while the generator lives.
func tour(_ stops: borrowing [StaticString; 3]) -> yields Lantern {
defer { print("home") }
for i in 0..<3 { yield Lantern(city: stops[i], toll: i + 5) }
}
func main() -> Int {
var total = 0
for value in consume evens(fibonacci(below: 100)) { total += value }
var numbers = fibonacci(below: 100)
while case .some(_) = numbers.next() { total += 1 }
let stops: [StaticString; 3] = ["mostar", "izmir", "sarajevo"]
var visited = 0
for lantern in consume tour(stops) {
total += lantern.toll
visited += 1
if visited == 2 { break }
}
return total
}
Compile-Time Reflection and Serialization
// Compile-time metadata selects ordinary typed field reads, stores and construction.
attribute BalkanWire(_ slot: Int)
public struct Sarajevo: ReflectConstructible {
@BalkanWire(1)
private let first: Int
@BalkanWire(0)
private var second: Int
}
func belgrade_encode<T: Reflectable, const N: Int>(_ value: borrowing T,
into output: inout [Int; N]) {
const if #is_struct(T) {
const for nis in 0..<#field_count(T) {
const if #field_type(T, nis) == Int {
const slot = #field_attribute_argument(T, nis, 0, 0)
output[slot] = #field(value, nis)
} else {
#error("BalkanWire requires Int fields")
}
}
} else {
#error("BalkanWire requires a struct")
}
}
func belgrade_decode<T: ReflectConstructible, const N: Int>(_ input: borrowing [Int; N]) -> T {
const if #is_struct(T) {
let builder = #builder(T)
const for nis in 0..<#field_count(T) {
const if #field_type(T, nis) == Int {
const slot = #field_attribute_argument(T, nis, 0, 0)
#field(builder, nis) = input[slot]
} else {
#error("BalkanWire requires Int fields")
}
}
return #finish(builder)
} else {
#error("BalkanWire requires a struct")
}
}
func mostar_equal<T: Reflectable>(_ first: borrowing T, _ second: borrowing T) -> Bool {
const if #is_struct(T) {
const for nis in 0..<#field_count(T) {
if #field(first, nis) != #field(second, nis) { return false }
}
return true
} else {
#error("mostar_equal requires a struct with comparable fields")
}
}
const func istanbul_table(_ nis: Int) -> [Int; 3] {
var result = [0; 3]
for izmir in 0..<3 { result[izmir] = nis + izmir }
return result
}
const ankara = istanbul_table(65)
const func BelgradeArray(_ element: type, count: Int) -> type {
return #array_type(element, count)
}
const Tuzla = BelgradeArray(Int, count: 2)
enum Skopje { case ready(Int); case waiting }
func main() -> Int {
let input = [7, 67]
let sarajevo = belgrade_decode<Sarajevo, 2>(input)
var output: Tuzla = [0; 2]
belgrade_encode<Sarajevo, 2>(sarajevo, into: &output)
let copy = belgrade_decode<Sarajevo, 2>(output)
assert(mostar_equal<Sarajevo>(sarajevo, copy))
assert(output[0] == 7 && output[1] == 67)
const for nis in 0..<#field_count(Sarajevo) {
print(#field_name(Sarajevo, nis))
print(#field_offset(Sarajevo, nis))
}
print(#size_of(Sarajevo))
let skopje = #case(Skopje, 0, ankara[2])
print(#case_name(of: skopje))
assert(#case_index(of: skopje) == 0)
return 67
}
Capability Effects and Custom Handlers
import core
import system
// There are affects for Clock, IO, and of course you can define your own.
effect Audit {
mutating func record(_ seconds: Int)
}
struct CountingAudit: Audit {
var records: Int
var lastSeconds: Int
mutating func record(_ seconds: Int) {
self.records += 1
self.lastSeconds = seconds
}
}
// A clock stopped at one second, which this example moves by providing another.
struct StoppedClock: system.Clock {
let seconds: Int
func monotonic() -> Result<system.Time, system.Error> {
return .ok(system.Time(seconds: self.seconds, nanoseconds: 0))
}
func wall() -> Result<system.Time, system.Error> { return self.monotonic() }
func sleep(seconds: Int, nanoseconds: Int) -> Result<(), system.Error> { return .ok(()) }
func share() -> Shared<any system.Clock & Send & Sync> {
return Shared<any system.Clock & Send & Sync>(core.shared(StoppedClock(seconds: self.seconds)))
}
}
struct Lease {
let token: UInt
let granted: Int
}
func now() -> Int uses system.Clock {
switch system.Clock.monotonic() {
case .ok(let time): return time.seconds
case .err(_): return 0
}
}
func grant() -> Lease uses system.Clock, system.Entropy, Audit {
var bytes: [u8; 8] = [0; 8]
_ = system.Entropy.fill(core.writeSpan(&bytes))
var token: UInt = 0
for i in 0..<8 { token = (token << 8) | UInt(bytes[i]) }
let lease = Lease(token: token, granted: now())
Audit.record(lease.granted)
return lease
}
func expired(_ lease: borrowing Lease, ttl: Int) -> Bool uses system.Clock {
return now() - lease.granted >= ttl
}
func main() -> Int {
var audit = CountingAudit(records: 0, lastSeconds: 0)
var answer = 0
provide system.Clock = StoppedClock(seconds: 60), Audit = &audit {
let lease = grant()
print(expired(lease, ttl: 7)) // false
provide system.Clock = StoppedClock(seconds: 67) {
print(expired(lease, ttl: 7)) // true
answer = now()
}
}
print(audit.records) // 1
return answer
}
Formal Verification and Binary Search
import core
// Proof declarations and ghost state are erased from generated programs.
spec func successor(_ value: MathInt) -> MathInt { return value + 1 }
proof func successorGrows(_ value: MathInt)
ensures successor(value) > value
{ assert(successor(value) == value + 1) }
@verify
func fill<const N: Int>(_ values: inout [Int; N])
modifies values
ensures forall (i: MathInt) { 0 <= i && i < MathInt(N) ==> values[i] == 67 }
{
for i in 0..<N
invariant forall (j: MathInt) { 0 <= j && j < MathInt(i) ==> values[j] == 67 }
{ values[i] = 67 }
}
// Returns the first index whose element is >= key, or values.count.
@verify
func lowerBound(_ values: ReadSpan<Int>, _ key: Int) -> Int
requires forall (i: MathInt, j: MathInt) {
0 <= i && i <= j && j < MathInt(values.count) ==> values[i] <= values[j]
}
ensures 0 <= result && result <= values.count
ensures forall (i: MathInt) { 0 <= i && i < MathInt(result) ==> values[i] < key }
ensures forall (i: MathInt) {
MathInt(result) <= i && i < MathInt(values.count) ==> key <= values[i]
}
{
var lower = 0
var upper = values.count
while lower < upper
invariant 0 <= lower && lower <= upper && upper <= values.count
invariant forall (i: MathInt) { 0 <= i && i < MathInt(lower) ==> values[i] < key }
invariant forall (i: MathInt) {
MathInt(upper) <= i && i < MathInt(values.count) ==> key <= values[i]
}
decreases MathInt(upper) - MathInt(lower)
{
let middle = lower + (upper - lower) / 2
if values[middle] < key { lower = middle + 1 }
else { upper = middle }
}
return lower
}
@verify
func main() -> Int ensures result == 67 {
var values = [0, 0, 0]
fill<3>(&values)
ghost let before = snapshot(values)
proof { successorGrows(MathInt(values[0])) }
let found = lowerBound(core.readSpan<Int, 3>(values), 67)
proof { assert(snapshot(values) == before) }
return values[found]
}
Hash Maps (and other algorithms)
import core
func precedes(_ first: borrowing Int, _ second: borrowing Int) -> Bool { return first < second }
// Count repeated city visits, queue work in arrival order, then schedule counts
// by priority. The explicit seed makes this workload reproducible.
func main() {
var visits = core.hash_map_seeded<StaticString, Int>(capacity: 0, seed: core.HashSeed(low: 67, high: 7))
var pending = core.deque<StaticString>(capacity: 0)
let cities = ["Belgrade", "Ankara", "Belgrade", "Sarajevo", "Ankara", "Belgrade"]
for city in borrow cities { pending.push_back(city.pointee) }
for city in consume pending {
var count = 0
switch visits.get(city) { case .none: count = 0; case .some(let value): count = value.pointee }
visits.insert(city, count + 1)
}
var distinct = core.hash_set<StaticString>(capacity: 0)
var work = core.priority_queue<Int, (borrowing Int, borrowing Int) -> Bool>(capacity: 0, before: precedes)
for entry in borrow visits {
distinct.insert(entry.pointee.0)
work.push(entry.pointee.1)
}
assert(distinct.count() == 3)
var total = 0
for count in consume work { print(count); total += count }
assert(total == 6)
let key = "Belgrade"
switch visits.get(key) { case .none: assert(false); case .some(let count): assert(count.pointee == 3) }
print(67)
}
Quine (Program printing itself)
let sarajevo: StaticString = #"""
func main() {
print("let sarajevo: StaticString = #\"\"\"")
print(sarajevo)
print("\"\"\"#\n")
print(sarajevo)
}
"""#
func main() {
print("let sarajevo: StaticString = #\"\"\"")
print(sarajevo)
print("\"\"\"#\n")
print(sarajevo)
}