Show HN: Nimic – 将纯 Python 作为系统编程语言并支持 AOT 编译
Show HN: Nimic – Pure Python as a systems language with AOT compilation

原始链接: https://github.com/dima-quant/nimic

**Nimic** 是一个 Python 模块,它使开发者能够使用基于 Python 的领域特定语言编写可进行 AOT(预先)编译的代码,从而实现 C 语言级别的性能。通过将 Python 代码转译为 Nim 编程语言,Nimic 让开发者能够维护单一代码库:该代码库在执行时保持为合法的 Python 代码,同时运行性能又如同原生 Nim 代码。 主要特性包括: * **原生级性能:** 使用 `ctypes` 和自定义类型系统(标量、结构体、序列和枚举),提供可与 C/Nim 相媲美的内存和值语义。 * **Python 风格语法,Nim 语言语义:** 利用装饰器和注解(如 `@dispatch`、`@template`、`@distinct` 和 `mut @`)来模拟 Nim 的强大功能,例如多重分派、模板和编译时求值。 * **稳健的转译:** 内置基于 AST(抽象语法树)的转译器,可将 Python 语法转换为等效的 Nim 源代码。 * **双重用途兼容性:** 代码既可以在运行时作为可执行的 Python 程序运行,又能为 Nim 编译提供必要的元数据。 Nimic 填补了 Python 易于开发的语法与 Nim 高性能编译之间的鸿沟,使其成为处理性能敏感任务的理想工具,且无需脱离 Python 生态系统。

**Nimic** 是一款新型工具,支持使用纯 Python 进行高性能系统编程。通过利用类型提示(type hints)和 `ctypes` 垫片(shims),Nimic 代码保持为合法的 Python 代码,可在 CPython 中原生运行,从而实现轻松的调试与开发。 主要功能包括: * **AOT 编译:** Nimic 将 Python 代码转译为 Nim,随后编译成高性能的原生机器码(提供接近 C 的运行速度)。 * **零锁定:** 由于代码是标准的 Python,它可以在任何安装了 CPython 的机器上运行,即使没有安装 Nim 编译器也不受影响。 * **无缝工作流:** 开发者在将最终逻辑编译为可执行文件或 C 扩展之前,可以利用 Python REPL、标准调试器和断点进行开发。 该项目旨在弥合 Python 易用性与编译语言高性能之间的差距。开发者通过移植光线追踪器展示了其功效,渲染时间从数小时缩短至数分钟。尽管 Nimic 仍处于开发阶段,但它为 Pyccel、SPy 和 Codon 等类似工具提供了一个有前景的替代方案,特别是利用 Nim 的语法作为清晰高效的翻译目标。
相关文章

原文

Nimic is a pure Python module that facilitates writing AOT compilable code with a subset of Python (domain specific language), aiming to get C-level performance without leaving Python. Based on ctypes built-in module, it includes emulation of native types, pointers and operations on them, implementing dispatch, operator overloading, and templates. Nimic closely follows Nim programming language, to which nimic code transpiles.

Key principle: nimic code is valid Python that runs natively and transpiles to equivalent Nim code.

nimic/
├── ntypes.py       — Public API: re-exports type system + Nim keyword/builtin shims
├── ntypesystem.py  — Core type system (Object, NScalar, seq, dispatch, distinct, converter)
├── transpiler.py   — AST-based Python → Nim source code transpiler
├── inliner.py      — Template function inlining (@template, @template_expand)
├── ncode/          — Nim definitions (pydefs.nim, pystd/)
├── nimpy/          — API for generating Python libraries
├── std/            — Python shims for Nim stdlib (math, options, os, paths, strformat, ...)
└── system/         — Python shims for Nim system modules (ansi_c)

ntypesystem.py — Core Type System

Organized in layers from low-level memory to high-level abstractions:

Layer Classes Purpose
Memory Ntype, NTypeRegistry ctypes-backed buffers with value semantics
Scalars NScalarNInteger / NFloat Fixed-width types (int8..int64, uint8..uint64, float16..float64) with arithmetic promotion
Structs Object Nim "object" — fields via annotations, backed by ctypes.Structure
Enums NIntEnum Nim integer enums with auto-registration
Variants Object + match kind: Nim "case object" — discriminated unions
Containers seq[T], UncheckedArray[T] Growable sequence and pointer-indexed array
Dispatch @dispatch, DispDict, NMetaClass Nim-style multi-dispatch via type annotations
Modifiers @distinct, @converter Type distinctness and trivial type conversions
Strings string str subclass with Nim-compatible &, %, isEmpty

ntypes.py — Public API & Keywords

Re-exports all of ntypesystem and adds Nim keyword/builtin emulation:

  • Compiler hintsconst, let, var, block, export, alias (no-ops in Python, scoping in Nim)
  • Reference typesref, ptr, mut@ (@ operator returns identity)
  • Enum utilitiesNStrEnum with succ/pred/ord/nrange/low/high
  • Cast & memorycast[T](x), sizeof(x), addr(x), unsafe_addr(x)
  • Type aliasesSomeInteger, SomeFloat, untyped, char, u64, i64, f64
  • Iterationfields(obj), fields(a, b), countdown(a, b)
  • Compile-timecomptime(x), defined(varname), static
  • Templates@template, @template_expand (re-exported from inliner)

transpiler.py — Python → Nim Transpiler

A modified CPython ast.py where _Unparser is extended to emit Nim syntax. Implements 30+ transformation rules for indentation, type definitions, function signatures, operators, imports, and control flow.

inliner.py — Template Inlining

@template + @template_expand decorators perform AST-level function inlining for untyped templates, substituting parameter names with call arguments.

Nimic uses Python syntax with specific conventions that have dual meaning — runtime behavior in Python and transpilation semantics for Nim:

Convention Example Purpose
with let/var/const: with let: x = vec3(1,2,3) Variable declaration scope qualifier
mut @ annotation def f(x: mut @ Vec3): Mutable argument (var in Nim)
{.pragma.} docstring """{.inline.}""" Nim pragma (inline, borrow, noSideEffect)
@dispatch @dispatch
def f(x: float64):
Multi-dispatch by argument types
@distinct @distinct
class Color(Vec3):
Distinct type (no implicit conversion)
@template @template
def toUV(v):
Template (inlined at call site)
@converter @converter
def toVec3(uv):
Implicit type converter
<<= dst <<= -src Value assignment to mutable variable
match kind: match kind:
  case K.a: ...
Variant type definition (case object)
comptime(expr) if comptime(cond): Compile-time evaluation (when in Nim)
fields(obj) for f in fields(obj): Iterate over object fields
with export: with export: mod1, mod2 Re-export modules

Projects built with nimic

from __future__ import annotations
from nimic.ntypes import *

# Struct definition (Nim object)
class Vec3(Object):
    x: float64
    y: float64
    z: float64

    def __add__(self: Vec3, v: Vec3) -> Vec3:
        """{.inline.}"""
        result = Vec3()
        result.x = self.x + v.x
        result.y = self.y + v.y
        result.z = self.z + v.z
        return result

# Distinct type
@distinct
class Point3(Vec3):
    """{.borrow: `.`.}"""

# Multi-dispatch
@dispatch
def point3(x: float64, y: float64, z: float64) -> Point3:
    result = Point3(Vec3())
    result.x = x; result.y = y; result.z = z
    return result

# Usage
with let:
    a = point3(1.0, 2.0, 3.0)
    b = point3(4.0, 5.0, 6.0)
    c = Vec3(a) + Vec3(b)
联系我们 contact @ memedata.com