Learn Fifth in Y Minutes
20 minFifth is a systems programming language with first-class support for knowledge graphs and semantic web technologies. It combines imperative programming with RDF triple management.
// This is a single-line comment
/*
Multi-line comments
work like this
*/
//////////////////////////////////////
// 1. Basic Syntax and Literals
//////////////////////////////////////
// Every Fifth program needs a main function with an int return type
main(): int {
return 0;
}
// Integer literals support multiple bases
main(): int {
x: int;
x = 42; // Decimal
x = 0b101010; // Binary (prefix 0b)
x = 0o52; // Octal (prefix 0o)
x = 0x2A; // Hexadecimal (prefix 0x)
x = 42i; // Imaginary numbers
return 0;
}
// Floating-point literals
main(): int {
pi: float;
pi = 3.14159;
pi = 3.14e0; // Scientific notation
pi = 0x1.921fb54442d18p+1; // Hex float
return 0;
}
// Boolean literals
main(): int {
t: bool;
f: bool;
t = true;
f = false;
return 0;
}
// String literals
main(): int {
plain: string;
raw: string;
interpolated: string;
plain = "Hello, World!"; // Interpreted strings
raw = `Raw\nstring\twith\escapes`; // Raw strings (backticks)
interpolated = $"Value is {x}"; // Interpolated strings ($ prefix)
return 0;
}
// Rune literals (single characters)
main(): int {
c: rune;
c = 'A';
c = '\n'; // Escape sequences
c = '\u0041'; // Unicode escape
return 0;
}
// Null literal
main(): int {
ptr: int;
ptr = null;
return 0;
}
//////////////////////////////////////
// 2. Variables and Type Declarations
//////////////////////////////////////
// Variable declarations use colon syntax: name : type
main(): int {
x: int;
y: float;
s: string;
// Declaration with initialization
z: int;
z = 100;
return 0;
}
// Type specifications for arrays and lists
main(): int {
arr: int[10]; // Fixed-size array
dynamicArr: int[]; // Dynamic array
matrix: int[5][5]; // Multi-dimensional array
// List type with brackets
numbers: [int];
// Generic types
optional: Maybe<int>;
return 0;
}
//////////////////////////////////////
// 3. Operators
//////////////////////////////////////
// Arithmetic operators
main(): int {
x: int;
x = 10 + 5; // Addition
x = 10 - 5; // Subtraction
x = 10 * 5; // Multiplication
x = 10 / 5; // Division
x = 10 % 3; // Modulo
x = 2 ** 8; // Power (exponentiation with **)
x = 2 ^ 8; // Bitwise XOR (use ** for power)
return 0;
}
// Comparison operators
main(): int {
result: bool;
result = 5 == 5; // Equality
result = 5 != 3; // Inequality
result = 5 < 10; // Less than
result = 5 <= 5; // Less than or equal
result = 10 > 5; // Greater than
result = 10 >= 5; // Greater than or equal
return 0;
}
// Logical operators
main(): int {
result: bool;
result = true && false; // Logical AND
result = true || false; // Logical OR
result = !true; // Logical NOT
result = true !& false; // Logical NAND
result = true !| false; // Logical NOR
result = true ~ false; // Logical XOR
return 0;
}
// Bitwise operators
main(): int {
x: int;
x = 5 | 3; // Bitwise OR
x = 5 & 3; // Bitwise AND
x = 5 << 2; // Left shift
x = 20 >> 2; // Right shift
return 0;
}
// Increment and decrement
main(): int {
x: int;
x = 5;
x++; // Post-increment
x--; // Post-decrement
++x; // Pre-increment
--x; // Pre-decrement
return 0;
}
// Compound assignment
main(): int {
x: int;
x = 10;
x += 5; // x = x + 5
x -= 3; // x = x - 3
return 0;
}
//////////////////////////////////////
// 4. Functions
//////////////////////////////////////
// Function declaration syntax: name(params): returnType { body }
add(x: int, y: int): int {
return x + y;
}
// Multiple parameters
greet(firstName: string, lastName: string): string {
return firstName;
}
// Functions are called before main is defined
main(): int {
sum: int;
sum = add(5, 3);
return 0;
}
// Function with parameter constraints
// Use pipe | to specify constraints on parameters
// IMPORTANT: When using constraints, you must provide a base case
// The base case is an unconstrained version that handles all other inputs
positive(x: int | x > 0): int {
return x * 2; // Handles positive numbers
}
positive(x: int): int {
return 0; // Base case: handles zero and negative numbers
}
// Multiple constrained overloads with a base case
classify(x: int | x < 0): string {
return "negative";
}
classify(x: int | x == 0): string {
return "zero";
}
classify(x: int | x > 0): string {
return "positive";
}
classify(x: int): string {
return "unknown"; // Base case (fallback)
}
callClassify(): int {
return 0;
}
// Parameter destructuring
class Person {
FirstName: string;
LastName: string;
}
greetPerson(p: Person { first: FirstName, last: LastName }): string {
return first;
}
testGreet(): int {
return 0;
}
//////////////////////////////////////
// 5. Control Flow
//////////////////////////////////////
// If statements
main(): int {
x: int;
x = 10;
if (x > 5) {
x = 1;
}
// If-else
if (x < 5) {
x = 0;
} else {
x = 1;
}
return 0;
}
// While loops
main(): int {
i: int;
i = 0;
while (i < 10) {
i++;
}
return 0;
}
// With statement (scoped resource management)
main(): int {
with resource {
;
}
return 0;
}
// Try/catch/finally for exception handling
main(): int {
result: int;
result = 0;
// Try with finally - finally always executes
try {
result = 10;
} finally {
std.print("cleanup");
}
// Try/catch - handles exceptions
try {
result = 42;
} catch {
result = 1; // Catch-all handler
}
// Try/catch/finally combined
try {
result = 10;
} catch {
result = 1;
} finally {
result = result + 5; // Always executes
}
return result;
}
//////////////////////////////////////
// 6. Lists and Comprehensions
//////////////////////////////////////
// List literals
main(): int {
empty: [int];
numbers: [int];
empty = [];
numbers = [1, 2, 3, 4, 5];
return 0;
}
// List comprehensions with filtering
main(): int {
xs: [int];
ys: [int];
xs = [1, 2, 3, 4, 5];
// List comprehension: [projection from var in source where constraint]
ys = [x from x in xs where x > 2]; // [3, 4, 5]
return 0;
}
// Accessing list elements
main(): int {
numbers: [int];
first: int;
numbers = [10, 20, 30];
first = numbers[0]; // Index access
return 0;
}
//////////////////////////////////////
// 7. Classes and Objects
//////////////////////////////////////
// Class definition
class Rectangle {
Width: float;
Height: float;
}
// Class with methods
class Calculator {
Value: int;
Add(x: int): int {
return Value + x;
}
Multiply(x: int): int {
return Value * x;
}
}
// Class instantiation
main(): int {
rect: Rectangle;
calc: Calculator;
// Create new object (can be empty)
rect = new Rectangle();
// Create with property initialization
rect = new Rectangle() {
Width = 10.0,
Height = 5.0
};
calc = new Calculator() { Value = 100 };
return 0;
}
// Class inheritance
class Shape {
Color: string;
}
class Circle extends Shape {
Radius: float;
}
main(): int {
c: Circle;
c = new Circle();
return 0;
}
// Member access
main(): int {
rect: Rectangle;
w: float;
rect = new Rectangle() { Width = 10.0, Height = 5.0 };
w = rect.Width; // Access member
rect.Width = 15.0; // Modify member
return 0;
}
//////////////////////////////////////
// 8. Generic Types
//////////////////////////////////////
// Generic classes allow type parameters for reusable data structures
class Stack<T> {
items: [T];
push(item: T): int {
return 0;
}
pop(): T {
return items;
}
}
main(): int {
intStack: Stack<int>;
stringStack: Stack<string>;
// Each instantiation creates a distinct type
intStack = new Stack<int>();
stringStack = new Stack<string>();
return 0;
}
// Multiple type parameters
class Pair<T1, T2> {
first: T1;
second: T2;
}
class Dictionary<TKey, TValue> {
keys: [TKey];
values: [TValue];
}
main(): int {
pair: Pair<int, string>;
dict: Dictionary<string, int>;
pair = new Pair<int, string>() {
first = 42,
second = "answer"
};
return 0;
}
// Generic functions with type inference
identity<T>(x: T): T {
return x;
}
main(): int {
result: int;
text: string;
// Explicit type arguments
result = identity<int>(42);
text = identity<string>("hello");
// Type inference (types inferred from arguments)
result = identity(42); // Infers T = int
text = identity("world"); // Infers T = string
return 0;
}
// Type constraints ensure type parameters meet requirements
sort<T>(items: int): int where T: IComparable {
return 0;
}
extend<T>(base: T): int where T: BaseClass {
return 0;
}
process<T>(item: T): int where T: IComparable, IDisposable {
return 0;
}
//////////////////////////////////////
// 9. Module System
//////////////////////////////////////
// Import modules
use Math, IO, Net;
// Multiple imports
use System, Collections;
main(): int {
return 0;
}
//////////////////////////////////////
// 10. Knowledge Graphs & Semantic Web
//////////////////////////////////////
// Alias declarations for IRI namespaces
alias ex as <http://example.org/>;
alias foaf as <http://xmlns.com/foaf/0.1/>;
// Store declaration
myStore : store = remote_store(<http://localhost:8080/graphdb>);
// Triple literals: <subject, predicate, object>
main(): int {
// Triples use prefixed IRIs
<ex:john, foaf:name, "John Doe">;
<ex:john, foaf:age, 30>;
<ex:john, ex:knows, ex:jane>;
return 0;
}
// Graph creation using TriG literals
main(): int {
// TriG literals embed RDF data directly in Fifth code
g: graph = @<
@prefix ex: <http://example.org/> .
ex:data {
ex:subject1 ex:predicate1 ex:object1 .
ex:subject2 ex:predicate2 42 .
}
>;
return 0;
}
// Working with graphs and objects
class Person {
Name: string;
Age: int;
}
main(): int {
// Create an object
alice: Person;
alice = new Person();
// Create graph using a TriG literal
peopleGraph: graph = @<
@prefix ex: <http://example.org/> .
ex:people {
ex:alice ex:name "Alice" ;
ex:age 30 ;
ex:knows ex:bob .
}
>;
return 0;
}
// TriG literals support interpolation with {{ }}
main(): int {
name: string = "Alice";
age: int = 30;
g: graph = @<
@prefix ex: <http://example.org/> .
ex:people {
ex:alice ex:name {{ name }} ;
ex:age {{ age }} .
}
>;
return 0;
}
// Assigning graphs to stores
alias ex as <http://example.org/>;
myStore : store = remote_store(<http://localhost:8080/graphdb>);
main(): int {
myGraph: graph = @<
@prefix ex: <http://example.org/> .
ex:data {
ex:entity ex:property "value" .
}
>;
// Add graph to store
myStore += myGraph;
// Remove graph from store
myStore -= myGraph;
return 0;
}
// Classes in semantic context
class Entity in <http://example.org/ontology#> {
Name: string;
Value: int;
}
main(): int {
e: Entity;
e = new Entity() { Name = "Test", Value = 42 };
return 0;
}
//////////////////////////////////////
// 11. Full Example: Semantic Application
//////////////////////////////////////
// Define namespace aliases
alias foaf as <http://xmlns.com/foaf/0.1/>;
alias ex as <http://example.org/people/>;
// Connect to a store
peopleDB : store = remote_store(<http://localhost:8080/graphdb>);
// Define a class for people
class Person {
FirstName: string;
LastName: string;
Age: int;
}
// Function to calculate if someone is an adult
isAdult(age: int): bool {
return age >= 18;
}
// Main program
main(): int {
// Create a person
john: Person;
john = new Person() {
FirstName = "John",
LastName = "Doe",
Age = 30
};
// Check if adult
adult: bool;
adult = isAdult(john.Age);
// Create knowledge graph using a TriG literal with interpolation
johnGraph: graph = @<
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix ex: <http://example.org/people/> .
ex:people {
ex:john foaf:firstName {{ john.FirstName }} ;
foaf:lastName {{ john.LastName }} ;
foaf:age {{ john.Age }} .
}
>;
// Save to the store
peopleDB += johnGraph;
return 0;
}