Overview
K is an experimental low-level programming language compiled by klang.
It features static type checking, compile time code execution, polymorphic functions, and basic modules with a
Rust-inspired syntax. The compiler can either generate simple C code or leverage LLVM
for more optimized code generation. Basic test cases and examples of K programs can be found in
the test directory of the klang
repository.
Polymorphic Functions
Function parameters can be specified as generic types, represented here by the letter T
:
fn add(a $T, b T) -> T {
a + b
}
At each of the function’s call sites, the compiler generates or reuses a specialized definition of the generic function. For example, adding two 64-bit integers (i64) together looks like this:
let x = add(3, 4);
let y = add(x, 5);
The specialized function that is generated for this case:
fn add(a i64, b i64) -> i64 {
a + b
}
Attempting to use two different types for this example function results in an error:
let z = add(y, 3.14); // Error: types y (i64), 3.14 (f64) do not match
Modules
Types and functions can be defined inside modules, which are similar to namespaces in C++. For
example, consider a type Thing
defined inside module foo
:
module foo {
struct Thing {
x i64;
y i64;
};
fn make_thing(x i64, y i64) -> Thing {
let t Thing;
t.x = x;
t.y = y;
t
}
fn do_something(t *Thing) -> i64 {
t.x + t.y
}
}
The foo
module can be imported and used by external code:
import "foo.k";
fn main() {
let t0 foo::Thing;
t0.x = 3;
t0.y = 5;
let t1 = foo::make_thing(4, 8);
let x = foo::do_something(&t0); // x is 8
let y = foo::do_something(&t1); // y is 12
}
OpenGL Bindings
K provides OpenGL bindings, which are defined and loaded into the gl
module in
gl.k. An example usage looks something
like this:
import "gl.k";
fn main() {
// Create the OpenGL context and OS window
let window = gl::create_window("Title", 1280, 720);
// Load OpenGL function pointers
gl::load_funcs();
// Initialize and clear input state
let input Input;
for i in 0..256 {
input.keys[i] = 0;
};
gl::ClearColor(1.0, 0.0, 1.0, 1.0);
// Main loop
loop {
gl::poll_events(window, &input);
// Handle events, simulate...
gl::Clear(gl::COLOR_BUFFER_BIT);
// Draw things...
gl::swap_buffers(window);
};
gl::destroy_window(window);
}