Over the last thirty years, I’ve worked across a sprawling landscape of technologies—from writing Go, C#, Pascal, Swift, and C, to orchestrating massive cloud pipelines, down to micro-managing registers on bare-metal microcontrollers.
But lately, my time has been dominated by a very specific,
highly opinionated, and occasionally cooperative localized AI agent: DANI.
If you've been following my previous posts, you know DANI
has transitioned from an LSTM-based cognitive core into a physical, moving
entity. And that is where the real-world engineering headaches began. Every
time you start a new robotics or physical AI project, you are forced to make a
compromise that feels like choosing between a kick in the shins or a poke in
the eye:
- The
C/C++ Extremity: You get deterministic, blazing-fast performance on
microcontrollers, but you sacrifice developer ergonomics, modern package
safety, and swift prototyping. Writing raw $C++$ register manipulation
code sometimes feels like trying to perform laparoscopic surgery on
yourself with a rusty spoon.
- The
Python Extremity: You get instant access to rich AI primitives, neural
networks, and expressiveness. But you inherit bloated virtual environments
that take up more disk space than the library of Alexandria, and
unpredictable garbage collection (GC) latency. When DANI’s control loop is
running at $100\text{ Hz}$ and the Python garbage collector decides to
take a mandatory three-millisecond tea break, DANI doesn't stop. She
gracefully, but deterministically, plows straight into the skirting board.
I got tired of choosing between developer speed and hardware
execution safety. I wanted a compiled language built specifically for low-level
systems hardware, high-throughput concurrent event streams, and native AI
execution.
So, I built Skink-lang.
What is Skink?
Skink is an LLVM-backed, statically-typed systems
programming language designed from the ground up for the modern era of
intelligent automation. It blends the tight, expressive syntax of modern
languages like Swift with the lightweight concurrency model of Go, leaving
behind the runtime bloat.
To save you from the nightmare of modern package
managers—where doing a pip install on a single helper utility somehow downloads
half the internet and a bootleg copy of Doom—Skink comes with a rich,
"batteries-included" standard library right out of the box.
As a Skinker (yes, that is our official title now),
you get native access to:
- Automatic
Reference Counting (ARC): Predictable, deterministic memory management
without "stop-the-world" garbage collection pauses. This is a
non-negotiable requirement when you are driving physical motors or
processing high-frequency sensor telemetry.
- Lightweight
Concurrency: A native spawn keyword that allows you to spin up
millions of concurrent tasks with near-zero overhead, communicating
cleanly via typed channels.
- The
Rules Engine: A compiler-optimized reactive rules engine that lets you
define declarative behavioral overrides that monitor variables in the
background. It is perfect for saying, "I don't care what the
neural net is thinking; if we are $15\text{ cm}$ away from a wall,
hit the brakes."
- Native
Tensors & ML Cores: Multi-dimensional arrays built directly into
the type system via std/tensor, complete with matrix operations,
activation functions, neural layers, and hooks for CUDA acceleration and
llama.cpp (std/llm). DANI can run local inferences natively, at maximum
speed, without needing a dedicated power plant or $16\text{ GB}$ of RAM.
- Model
Context Protocol (MCP) & MQTT: Built-in support for turning any
hardware endpoint into an instantly discoverable AI tool with SQLite
(std/db) and edge-to-cloud messaging (std/mqtt) ready to go.
Under the Hood: Preventing a DANI Catastrophe
To see what "skinking" actually looks like, let's
write a syntactically valid program based on the current Skink manual.
The following script concurrently polls a physical distance
sensor via GPIO, pipes the measurements to our main execution block using
channels, evaluates safety overrides in a background ruleset, and processes the
inputs through a linear neural network layer to calculate motor outputs:
module main
import "std/gpio"
import "std/time"
import "std/tensor"
// 1. Declare global state variables (accessible by the ruleset)
var current_distance: float = 100.0
var motor_speed: float = 0.5
// 2. Define a reactive ruleset for safety overrides
ruleset SafetyOverride {
rule collision_warning when current_distance < 15.0 {
action: trigger_emergency_stop()
priority: 1
}
}
// Helper function called when the rule fires
fn trigger_emergency_stop() {
motor_speed = 0.0
print("SAFETY OVERRIDE: Obstacle detected! Distance: {current_distance}cm. Braking.")
}
// 3. Concurrently poll the hardware sensor in a background task
fn sensor_loop(ch: chan<float>) {
err := gpio.Setup()
if err.message != "" {
print("Failed to initialize GPIO: " + err.message)
return
}
// Bind to BCM Pin 17 (e.g., our sensor input pin)
sensor_pin := gpio.PinFactory(17)
sensor_pin.SetInput()
while true {
// Mocking a physical sensor read for this demo loop
// In physical deployment, you'd calculate raw voltage pulses here
measured := 12.5
ch <- measured
time.SleepMs(10) // Poll at 100Hz
}
}
// 4. Main Entry Point
fn main() -> int {
sensor_chan := make(chan<float>)
// Spawn our lightweight background polling loop
spawn sensor_loop(sensor_chan)
// Activate our safety ruleset background thread
safety := SafetyOverride{}
safety.start()
defer safety.stop()
// Initialize a linear neural network layer [input_features: 3, output_features: 1]
layer := tensor.NewLinear(3, 1)
// Run our control loop for 100 iterations
for i := 0; i < 100; i = i + 1 {
// Block until next sensor reading arrives
current_distance = <-sensor_chan
// If we are in a safe zone, let the tensor neural layer drive
if current_distance >= 15.0 {
input := tensor.Zeros([1, 3])
input.Set([0, 0], current_distance)
output := layer.Forward(input)
motor_speed = output.Get([0, 0])
print("Processing... Current motor velocity: {motor_speed}")
}
}
return 0
}
Notice how neatly this handles the classic embedded AI
problem. The concurrency model lets you poll hardware safely on separate
execution threads without blocking the main loop, while the native ruleset
watches the critical state variables and takes action within milliseconds if a
threshold is breached—guaranteeing deterministic safety constraints before DANI
can do any structural damage to the house.
Where Skink-lang Goes From Here
Currently, the compiler is bootstrapped in Go, using an LLVM
backend to output highly optimized native machine binaries targeting both Linux
and Windows corporate environments. Because there is no heavy runtime or
garbage collector, a compiled Skink binary running an active inference loop can
comfortably squeeze inside less than $128\text{ KB}$ of RAM.
But this is just the beginning. The roadmap ahead includes:
- Direct
Single Board Computer HAL: Expanding the standard library to map
hardware registers and pins natively (such as on the Raspberry Pi 5) with
zero external C-bindings.
- Self-Hosting:
Rewriting the Skink compiler entirely in Skink itself, proving the
language's capabilities to handle massive, complex systems-level software
natively.
![]() |
| Cullen Skink |
I’m incredibly excited about what this language makes possible. DANI is already running much cooler, much faster, and with a significantly lower skirting-board collision rate.
It is time to stop fighting the plumbing.
Let's get skinking!
Let me know your thoughts on the syntax, and what
features you'd like to see added to the compiler next!











