ADR-0001: Nim Programming Language Selection

Status: Accepted
Date: 2024-01-15
Deciders: Engineering Team

Context

We needed to select a programming language for the C Pro embedded camera server that would provide:

  • Low-level hardware access (V4L2, GPIO, I2C)
  • High performance for real-time video processing
  • Memory safety and reliability for medical devices
  • Cross-compilation for ARM64 embedded targets
  • Small binary size for resource-constrained devices

Decision

We chose Nim as the primary programming language for the C Pro camera server.

Rationale

Performance Benefits

  • Compiled to C: Nim compiles to optimized C code, providing near-C performance
  • Zero-cost Abstractions: High-level constructs with no runtime overhead
  • Manual Memory Management: Precise control over memory allocation with ORC GC
  • Small Binaries: Typical binary size <10MB for complete application

Cross-compilation Support

# Cross-compile for ARM64 from x86
nim c --cpu:arm64 --os:linux -d:release rotordream.nim

Hardware Integration

  • C Interop: Seamless integration with existing C libraries (GStreamer, V4L2)
  • Low-level Access: Direct memory manipulation and hardware control
  • No Runtime: Minimal runtime dependencies for embedded deployment

Development Experience

  • Type Safety: Strong static typing with inference
  • Metaprogramming: Powerful macro system for code generation
  • Modern Syntax: Python-like readability with C-like performance

Code Example

# Clean integration with C libraries
proc v4l2_open(device: cstring, flags: cint): cint {.importc, header: "<fcntl.h>".}

# Type-safe, high-performance video processing
proc processFrame(buffer: ptr UncheckedArray[byte], size: int): seq[byte] =
  result = newSeq[byte](size)
  copyMem(result[0].addr, buffer, size)

Alternatives Considered

C/C++

  • Pros: Maximum performance, hardware access
  • Cons: Memory safety issues, complex build system, slower development

Rust

  • Pros: Memory safety, performance, growing embedded ecosystem
  • Cons: Steep learning curve, larger binaries, limited ARM64 ecosystem (2024)

Go

  • Pros: Simple syntax, good networking support
  • Cons: Garbage collector unsuitable for real-time, larger binaries

Python/Node.js

  • Pros: Rapid development, extensive libraries
  • Cons: Performance limitations, runtime dependencies

Consequences

Positive

  • Performance: Real-time video processing at 30fps+
  • Reliability: Type safety reduces runtime errors
  • Deployment: Single binary deployment, no runtime dependencies
  • Integration: Seamless C library integration for hardware access

Negative

  • Learning Curve: Team had to learn Nim language and ecosystem
  • Ecosystem: Smaller package ecosystem compared to mainstream languages
  • Debugging: Limited tooling compared to C/C++/Python

Neutral

  • Build System: Nim's build system works well but required configuration tuning
  • Documentation: Good core documentation, but community packages vary

Implementation Notes

Build Configuration

From rotordream.nimble:

requires "nim >= 2.2.2"
requires "corun >= 0.7.10"
requires "xxtea"
requires "checksums >= 0.2.1"

Cross-compilation Setup

From tools/buildRelease.nim:

when defined(embeddedSystem):
  switch("cpu", "arm64")
  switch("os", "linux")
  switch("define", "directCompile=true")

Monitoring

We track the following metrics to validate this decision:
- Binary Size: Target <10MB for release builds
- Memory Usage: <100MB RAM for typical operation
- Performance: 30fps video processing on ARM64 hardware
- Development Velocity: Feature delivery time vs. C++ baseline

Review Date

This decision will be reviewed in Q4 2025 based on:
- Team productivity and satisfaction
- Performance benchmarks vs. requirements
- Nim ecosystem maturity and support
- Availability of alternative technologies

Copyright © 2025 Rotoclear