Skip to content

Cross-module behaviors — let third-party libraries publish @when #19

@matajoh

Description

@matajoh

Problem

A bocpy program can only use @when-decorated functions that live in a single module — the one the runtime was bootstrapped against, typically __main__. A third-party library cannot publish an API whose surface includes its own behaviors, because the worker has no way to find them and no way to disambiguate them from the consumer's behaviors. This blocks any meaningful bocpy-native library ecosystem: every reusable abstraction has to be expressed as plain functions or classes that the consumer then wraps in their own @when.

The single-module assumption is baked in at several layers. The transpiler emits one module of generated thunks. Those thunks are named by per-export integer, so two modules would collide on name. The worker's behavior lookup is keyed by source line number with no module dimension. @when is recognised as a literal source token, so even from bocpy import when as w defeats it. Capture resolution walks the caller's live frames, which works for application code but is the wrong namespace for an imported library's behaviors.

Desired functionality

A third-party library can pip install cleanly into a bocpy program and expose @when-decorated functions as part of its public API. The consumer composes its own behaviors with the library's behaviors freely; cowns flow across the boundary without ceremony. From the library author's point of view, publishing a behavior should feel as much like publishing any other Python function as the runtime allows.

Design questions to resolve

  • Identity. What names a behavior at runtime, given that source line numbers no longer uniquely identify one?
  • Discovery. How does the runtime learn that a given imported module contributes behaviors — explicit registration by the application, by the library, by an import-time mechanism, or by a build-time artifact?
  • Distribution. What unit does a library actually ship — source, a pre-compiled artifact alongside the wheel, a C extension, or some combination?
  • @when API. Does the current call-site, closure-capture-style decorator survive as-is, or does cross-module use require an additional (or different) entry point with explicit captures?
  • Worker namespace. Does the worker continue to use a single flat export module, or does it need a per-module table of behavior namespaces?

Cross-cutting concerns

  • Robustness of @when recognition against import aliases and dotted access.
  • Capture resolution against the library's module namespace, not the user's, for library-supplied behaviors.
  • Behavior-name collisions across modules.
  • C ABI impact on the behavior-capsule thunk identifier.
  • When library behaviors become known to the worker — at worker boot, on first use, or on import.
  • Editable-install developer loop (pip install -e ./mypkg then pytest) staying usable.

Out of scope

Sub-interpreter cleanliness of behavior-bearing modules — that is a pre-existing runtime invariant, not new work introduced here. noticeboard, send, and receive are already cross-module clean and need no changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    designDesign conversations

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions