stackclosures

Allocate closures on stack

Pure Nim score 15/100 · tests present · no docs generated

Summary

Latest Version 0.1.2
License MIT
CI Status Failing
Downloads 0
Last Indexed 2026-07-21 05:26

Authors

  • G. Bareigts

Installation

nimble install stackclosures
choosenim install stackclosures
git clone https://github.com/guibar64/stackclosures

OS Compatibility

Platform Linux macOS Windows FreeBSD OpenBSD NetBSD Android iOS WASM Embedded
stackclosures - - - - - - -

Dependencies

Package Version Optional
nim >= 2.0.0 No

Source

Repository https://github.com/guibar64/stackclosures
Homepage https://github.com/guibar64/stackclosures
Registry Source nimble_official

README

Github Actions

A macro (stackClosures) is provided to annotate a function, closures defined inside this function will be allocated on the stack.

import std/sequtils

proc doMap(a: openArray[int]): seq[int] {.stackClosures.} =
    map(a, proc(x: int): int = x + 1)

⚠⚠⚠ UNSAFE . The closures must not escape the function stack frame. ⚠⚠⚠

It is ABI compatible with Nim closures for ARC/ORC (which means sequtils and friends work)

It can work in a multithreading context, provided the threads exit before the owning function termination. For example, see tests/threads/tthreading.nim.

If one wish to use regular Nim closures, wrap the closure definition with nimClosure:

import std/sequtils

proc doMap(a: openArray[int]): seq[int] {.stackClosures.} =
    map(a, nimClosure proc(x: int): int = x + 1)

Caveats (besides safety concerns): - the current implementation is quite eager to transform any inner proc to a closure even non-capturing ones, use explicit annotations like nimcall to avoid that. - Should not be compatible with --mm:refc (tests do pass but it may be an happy accident) - capturing parameters is allowed, caution is advised. Currently, openArray is not supported. - generics are not supported (the implementation use typed AST but generics are mostly untyped) - compatibility with regular Nim closures implies allocating some space for ref-like bookkeeping, that is an overhead of 2*sizeof(int) for ARC and 3*sizeof(int) for ORC - the current implementation use one environment per containing function, it works OK for this limited purpose but it could be improved