A research language exploring a pragmatic, highly expressive set of implicit programming techniques. We want to build better software by writing less code.
Feature Highlight
Universal Function Call Syntax
struct Dog {
name: string
dog_years: int
}
fn Dog(name: string, human_years: int) {
mut dog_years = human_years
if (dog_years > 10) dog_years -= 10
if (dog_years > 14) dog_years -= 4
dog_years /= 5
return Dog(:dog_years, :name)
}
fn main() Dog("Robbie", human_years: 34).dog_years - 4
Feature Highlight
Overloading Without Ambiguity
struct BitSet { data: u8[] }
infix fn |=(ref .data left, .data right) {
left.grow(max(left.len, right.len))
right.each: |v, i| left[i] |= v
}
fn main() {
mut a = BitSet([ 7.u8 ])
a |= BitSet([ 9.u8 ])
a.data[0] == 15 ? 0 : 1
}
Feature Highlight
Value vs Reference Semantics
fn test(ref place, const value) {
let const val a = place || value
let mut val b = place || value
let const ref c = place
let mut ref d = place
d += b += c + a
}
fn main() {
mut v = 0
test(v, v)
return v
}
Feature Highlight
Short-Circuit Operators
fn if(argv: _[], exists!i: int)
argv.len > i && argv[i]
fn main(argv: string[]) {
let name = argv.if(exists: 1).trimmed || {
println("Usage: greet [name]")
return 1
}
println("Hello, " name "!")
return 0
}
Feature Highlight
Local & Foreign Labels
:OUTER_LOOP
recipes.each: |recipe| {
fn fail(reason: string) {
println("Cannot prepare " recipe.name ": " reason)
continue :OUTER_LOOP;
}
recipe.ingredients.each: |ingredient|
if !(fridge.has(ingredient))
fail("We don't have " ~ ingredient)
return recipe
}
Feature Highlight
Iteration
fn increment_even_until(ref numbers: int[], needle: int) {
for (mut i = 0; i < numbers.len; i++) {
ref num = numbers[i]
if (num & 1) continue;
if (num == needle) break;
if (num > needle * 2) return num
num++
}
return -1
}
Feature Highlight
Structures & Reflection
struct Person {
name: string
age: int
}
fn pretty_print(value: Person) {
println("Person {")
for (fieldname i: Person)
println(" " ~ "i" ~ ": " value.i)
println("}")
}
fn main() {
let p = Person("Albert", 26)
return p.name.len + p.age - 32
}
Feature Highlight
Enums, Flags & Primitives
primitive Distance: f32 {
Meter = 1
Kilometer = 1000
}
fn main() {
assert(1000 * Distance.Meter == Distance.Kilometer)
return 0
}
Feature Highlight
Template Types
struct Pair(type Left, type Right) {
left: Left
right: Right
}
fn fst(pair: Pair(<Left>, _)): Left =
pair.left
fn snd(pair: Pair(_, <Right>)): Right =
pair.right
fn sum(pair: Pair(<T>, T))
case (T.is::arithmetic): T =
pair.fst + pair.snd
Feature Highlight
Lexical Scope & Shadowing
fn parent_fn(array_of_T: <T>[]) {
struct ChildType { raw: T }
let array_of_ChildType = array_of_T.map(|v| ChildType(v))
mut number_of_additions_performed = 0
infix fn +(a: ChildType, b: ChildType) {
number_of_additions_performed++
return ChildType(a.raw + b.raw)
}
fn sum(array: _[]) = reduce(array, |a, b| a + b)
let actual = sum(array_of_ChildType).raw
assert(actual == sum(array_of_T)
&& number_of_additions_performed == array_of_T.len)
return actual
}
Feature Highlight
“implicit” Argument Passing
struct Module { filename: string }
struct LineCol { line: int; col: int }
struct Diagnostic { filename: string; lc: LineCol; error: string }
fn emit_diagnostic(error: string,
implicit module: Module,
implicit lc: LineCol,
implicit ref diagnostics: Diagnostic[])
{
diagnostics ~= Diagnostic(:module.filename, :lc, :error)
}
fn parse_bool(span: byte[]) {
if (span == "true")
return true
if (span != "false")
emit_diagnostic("Invalid bool literal: " ~ span)
return false
}
Feature Highlight
The “using” Keyword
struct vec2 { x: f32; y: f32 }
struct Player { position: vec2 }
fn move(ref player: Player, dist: vec2) {
player.position.x += dist.x
player.position.y += dist.y
}
fn main() {
mut p: Player
p.move(vec2(10, 10))
assert(p.position.x * p.position.y == 100)
return 0
}
Feature Highlight
Getting Started
Hello! This is Fu v0.0.1
To get started:
echo 'fn main() println("Hello world!");' >> hello.fu
Build it:
~/fu/bin/fu -b hello.fu
Run it:
./hello
Hello world!