From c388afa00b4351516951ee9d99c753ca24c3db22 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Tue, 2 Jun 2026 17:05:44 +0800 Subject: [PATCH 1/2] feat: switch closures to be generators --- src/conductor/stdlib/list/accumulate.ts | 5 ++--- src/conductor/types/moduleInterface/ExternCallable.ts | 2 +- src/conductor/types/moduleInterface/IDataHandler.ts | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/conductor/stdlib/list/accumulate.ts b/src/conductor/stdlib/list/accumulate.ts index 35b3a6f..6cce633 100644 --- a/src/conductor/stdlib/list/accumulate.ts +++ b/src/conductor/stdlib/list/accumulate.ts @@ -11,12 +11,11 @@ import { DataType, type IDataHandler, type TypedValue } from "../../types" * @param resultType The (expected) type of the result. * @returns A Promise resolving to the result of accumulating the Closure over the List. */ -export async function accumulate>(this: IDataHandler, op: TypedValue, initial: TypedValue, sequence: TypedValue, resultType: T): Promise> { +export async function* accumulate>(this: IDataHandler, op: TypedValue, initial: TypedValue, sequence: TypedValue, resultType: T): AsyncGenerator, undefined> { const vec = await this.list_to_vec(sequence); let result = initial; for (let i = vec.length - 1; i >= 0; --i) { - result = await this.closure_call(op, [vec[i], result], resultType); + result = yield* this.closure_call(op, [vec[i], result], resultType); } - return result; } diff --git a/src/conductor/types/moduleInterface/ExternCallable.ts b/src/conductor/types/moduleInterface/ExternCallable.ts index 45f95cf..8416e68 100644 --- a/src/conductor/types/moduleInterface/ExternCallable.ts +++ b/src/conductor/types/moduleInterface/ExternCallable.ts @@ -5,4 +5,4 @@ type DataTypeMap = { [Idx in keyof T]: TypedValue }; -export type ExternCallable = (...args: DataTypeMap) => TypedValue | Promise>; +export type ExternCallable = (...args: DataTypeMap) => AsyncGenerator, undefined>; diff --git a/src/conductor/types/moduleInterface/IDataHandler.ts b/src/conductor/types/moduleInterface/IDataHandler.ts index 372554b..ddc3aa0 100644 --- a/src/conductor/types/moduleInterface/IDataHandler.ts +++ b/src/conductor/types/moduleInterface/IDataHandler.ts @@ -145,7 +145,7 @@ export interface IDataHandler { * @param returnType The expected type of the returned value. * @returns A promise to the returned typed value. */ - closure_call(c: TypedValue, args: TypedValue[], returnType: T): Promise>>; + closure_call(c: TypedValue, args: TypedValue[], returnType: T): AsyncGenerator>, undefined>; /** * Calls a Closure of known return type. @@ -153,7 +153,7 @@ export interface IDataHandler { * @param args An array of typed arguments to be passed to the Closure. * @returns A promise to the returned typed value. */ - closure_call_unchecked(c: TypedValue, args: TypedValue[]): Promise>>; + closure_call_unchecked(c: TypedValue, args: TypedValue[]): AsyncGenerator>, undefined>; /** * Asserts the arity of a Closure. @@ -208,6 +208,6 @@ export interface IDataHandler { list(...elements: TypedValue[]): Promise>; is_list(xs: TypedValue): Promise; list_to_vec(xs: TypedValue): Promise[]>; - accumulate>(op: TypedValue, initial: TypedValue, sequence: TypedValue, resultType: T): Promise>; + accumulate>(op: TypedValue, initial: TypedValue, sequence: TypedValue, resultType: T): AsyncGenerator, undefined>; length(xs: TypedValue): Promise; } From 768d04efe2b3f7defb98c6afe0cf2cf57023b6c6 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Tue, 2 Jun 2026 17:13:52 +0800 Subject: [PATCH 2/2] feat: update documentation --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1d4e95f..51a4121 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,8 @@ Thus, evaluators are responsible for providing functions to allow modules to rea Each of the data types passed as identifier have functions to create an instance of that data type, as well as read and write data to it (or call it, in the case of closures). See `conductor/types/IDataHandler`. +In the case of closures, the `closure_call` and `closure_call_unchecked` return `AsyncGenerator`s. In the case of CSE machines, yielding a closure call to a CSE closure would allow the module function to defer the execution until the closure's return value is executed. + ### Standard library A standard library of functions must be made available to modules. See `conductor/stdlib` for sample implementations.