GPW 2016 · Nuremberg · "KI: Wie testet man ein Hirn?"
That was 10 years ago.
A lot happened.
"Patience you must have, my young Padawan"
This prologue is not about Perl — but it is necessary context.
Some things are better left unspoken.
What I can show you today is roughly half of what happened.
3.4 kWp · 64 kWh · 66% off-grid
20+ kWp · 40 kWh · 85% off-grid
Victron ecosystem · Perl monitoring & control
~24 kWp · 45 kWh · 80+% off-grid · feed-in
40 kWp · 120 kWh · 100% off-grid
A technocrat's house — 2050s standard
...and it all needs to be controlled.
A house this complex needs an automation system that doesn't exist yet.
Witty House Infrastructure Processor
First tools: Victron Modbus + ECS BMS — all in Perl
ecs_bms_tool — ECS LiPro BMS management (SoC, cell voltage, balancing) Wmodbus — Modbus TCP/RTU: discovery, read/write, device profiles, monitoring Wcli — solar irradiance & PV power calculator Wthermal — physics-based house thermal model
Scripts work.
But a house is more than solar panels.
"We do not like CPAN" — dependencies create problems.
So we reimplement everything ourselves.
But worse.
"We do not like PBP" — contributions are done by amateurs.
Too high expectations would kill contribution.
"Efficient algorithms are overrated" — "So what?
That's 0.1s faster?"
"Tests?
TDD?
That's superfluous work!"
"I don't like you, you cannot use my GPL code"
(FHEM people: no offense.
Well, maybe a little.)
I felt there had to be something better.
Why CAN?
Hardware arbitration (CSMA/CR) · true multi-master · 1 Mbit/s · differential · industrial grade
Why not WiFi/Zigbee?
No batteries to die.
No mesh to collapse.
Building for 50 years, not 5.
Why not RS485?
No arbitration.
Master-slave only.
Two nodes transmit = garbage.
Why not KNX?
9600 baud (1990s design).
Expensive.
Closed ecosystem.
So you have 20 nodes — now what?
Higher layers are always a supplement, never a requirement.
STM32F103 (Cortex-M3, 72 MHz) STM32F303 (Cortex-M4F, FPU) Native bxCAN controller
FreeRTOS · libopencm3 No vendor HAL lock-in One YAML = one firmware
Dependency resolver inspired by Linux Kconfig
Ganglion = GANG of Lightweight I/O Nodes — insect-brain model.
IF-THEN rules, timers, local variables — compiled to bytecode on the MCU.
Nodes operate autonomously even when hub/server are down.
Specialized RasPi hubs.
Named by function, not by accident.
No hub is a single point of failure.
Each domain runs independently.
SELV-DALI — Lighting without mains
SELV = Safety Extra Low Voltage.
Under 60V DC.
Safe to touch.
The trick: Entire lighting chain runs from battery storage.
48V → 24V DC/DC → LED.
No 230V AC anywhere.
DALI controls at 16V.
Switches, sensors, dimmers — all SELV.
Inverters fail?
Lights stay on — they bypass AC entirely.
Switch next to the bathtub?
No problem.
No electrician needed.
WHIP — Protocols & Integrations
17 of 21 function codes · 869 tests · 91% coverage
Victron VRM · MasterTherm · PVGIS · Discord · Nextcloud · Proxmox · UniFi · ...
All protocol handlers in Perl · Mojolicious async I/O
Villa-A (Prague) — completely off-grid
Villa-B (Germany) — same concept, different config
Two deployments = real generalization, not "works on my machine"
Invisible when it works.
Competent when it matters.
Built for decades, not warranties.
Using AI to write Perl — the practical reality
A lot of Perl prototypes — some grew to standard tools
"User 'PETAMEM' set to nologin.
Your account may have been included in a precautionary password reset in the wake of a data breach incident at some other site.
Please talk to modules@perl.org to find out how to proceed."
→ Talked to modules@perl.org.
No answer.
"Ich leite das mal auf Steffen Winklers Empfehlung hier weiter an Dich, weil von modules@perl.org bislang keine Reaktion kam.
Würde jetzt mal wieder gerne ein paar Module auf CPAN schmeissen.
:-)"
"Hi Sören.
Weißt Du zufällig wo ich eines Andy König oder halt jemanden der mit PAUSE/CPAN weiterhelfen kann habhaft werden könnte?
Wir würden mal gerne unsere Module auf Vordermann bringen, aber [...] und bei modules@perl.org oder andyk@cpan.org rührt sich keiner."
→ An Sören Laird, LinkedIn.
No answer.
Simple Network Management Protocol — how you monitor and manage network devices.
Routers, switches, firewalls, UPS, printers — anything with an IP.
Management Information Base — the schema.
Defines what each device can report: CPU load, interface counters, temperature, error rates, ...
Thousands of vendor MIBs.
Written in ASN.1.
Riddled with vendor deviations from the standard.
Every monitoring system needs a parser — and every parser struggles.
2 days with AI · CPAN module was 93% working · targeted fixes, no rewrite
4740 MIBs · 301 fixes · 52 fewer failures than Go
Wanted gRPC in Perl.
Everything on CPAN: dormant, dead, or broken.
So we built it.
From scratch.
FFI::Platypus bindings to the gRPC C API.
Learning path: UUID::FFI → SQLite::FFI → Grpc::FFI
326 tests passing · zero memory leaks · zero crashes
Cross-language: Perl client ↔ Java/Go servers — working
Streaming: unary, client, server, bidirectional
85% production ready · ~43 implementation files
And yet — this was a prelude for something bigger.
What if FFI wasn't just a tailored library connector...
...but more integrated and automatic?
Human: strategy, architecture, learning path, priorities
AI: execution, documentation, pattern learning, iteration
gRPC example: I decided "start with UUID, then SQLite, then gRPC" AI executed each phase, documented lessons, graduated to the next
Without the navigator — the AI builds impressive things that go nowhere.
Without the AI — the navigator doesn't have enough hours in the day.
So...
AI is quite good at Coding.
But how far can this actually go?
A Perl 5 interpreter — designed by humans.
Written in Rust — by many AI agents.
Serious — no toy or academic exercise.
A Perl 5 interpreter Platform — designed by humans.
Common failure mode: underestimating Perl 5's complexity
Compatibility: strive for maximum Perl 5 compliance, currently 5.42 Performance: strive for V8 levels
XS: no, but yes Native Rust implementations, integral to the interpreter
~61–400 failures — give or take
Performance: good , bad and ugly
Native Rust implementations — not XS, not C
Maximum compatibility.
But more.
Powered by Rayon — Rust's data-parallelism library
Work-stealing scheduler Divides work into tasks, idle threads steal from busy ones — automatic load balancing
One-line change in Rust .iter() → .par_iter() — same code, parallel execution
Guaranteed data-race freedom If it compiles, it's safe.
Rust's type system enforces this at compile time.
Just-In-Time — compile to machine code while running
Cranelift — the compiler backend behind Wasmtime and Rust's alternative codegen.
Production-proven.
Targets: x86-64 · AArch64 · s390x · RISC-V
Inner loop JIT — single hot loop compiled to native code
Good.
But only the innermost loop is compiled.
What about nested loops?
Mandelbrot set Triple-nested while loop 19 variables · float arithmetic
Pure Perl.
No XS.
No Inline::C.
No tricks.
All 3 loop levels compiled as one native function
200 million escape iterations of float arithmetic.
19 variables, 3 loop levels — Cranelift register-allocates across all of them.
Perl.
With JIT.
That's a sentence nobody expected.
JIT + Rayon: compile to native, then split across cores
JIT alone: 76×.
Adding 8 threads: another ~7× on top.
user 2.6s vs real 0.34s — near-linear scaling across cores.
No XS.
No Inline::C.
No compilation.
Just call C.
Pack-style type codes: (p)L = strlen(const char*) → size_t 50+ native Rust modules already built in — Auto-FFI extends to everything else
Powered by libffi — any signature works, no pre-generated stubs
Libc: ~30 functions (process, strings, env, math, file, time) UUID: 6 functions via dlopen — dies with install hint if missing
Like Python's .pyc — but for Perl.
Opt-in.
Second run: load .plc → execute (no parsing, no codegen)
Storable-model: bincode deserializes directly to final runtime types.
Zero intermediate conversion.
Net module-loading cost: 33–37% faster with cache.
Biggest win on fallback modules.
Native Rust modules already near-zero cost.
SHA-256 keyed · mtime + version validation · aggressive format versioning
Emacs-style daemon/client model
First run: parse → codegen → execute (warm-up) → listen Client request: connect → fork() → child inherits arenas → execute → respond
fork() gives each client a fresh address space with all arenas already mapped — zero I/O, zero parsing, zero deserialization
Eliminates both startup costs: process creation (~3-4ms) + module compilation (0-15ms) Faster than bytecode cache — no deserialization, arenas are already in memory
Unix domain socket · JSON wire protocol · copy-on-write pages via fork()
All prior solutions: same interpreter across requests — state leakage by design pperl: fresh child per request via fork() — compiled arenas via COW, clean runtime state
Rule of thumb: the longer and more complex the script, the more likely you hit a corner case.
If you don't want to touch the code — use perl5.
How serious is "maximum compatibility"?
The bug: $, (OFS) vs $\ (ORS) in print
pperl checked both with the same flag mask.
Perl5 doesn't.
Checks ok-flags only.
No get-magic.
To trigger this, you'd need a tie on $\ whose FETCH returns undef, while the underlying SV has get-magic set but none of IOK/NOK/POK/ROK — and then call print .
Nobody writes this.
Nobody has ever written this.
The depth of compatibility is the product's guarantee.
I have been doing AI with Perl for a few decades.
Now it is time to let AI do Perl.
Richard Jelinek · rj@petamem.com PetaMem s.r.o.
· petamem.com
Object pipes — pass data structures, not text:
PowerShell's philosophy · Perl's text power · pperl's JIT speed
Related Stories
Source: This article was originally published by Hacker News
Read Full Original Article →
Comments (0)
No comments yet. Be the first to comment!
Leave a Comment