diff --git a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts index c0404f0..6e1fa09 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.spec.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.spec.ts @@ -1,11 +1,29 @@ import Ray from "./Ray"; -import rays from "../index"; describe("Ray", () => { describe(".Function", () => { describe(".Instance", () => { + test(".te", () => { + { + // "new Ray.vertex()()" vs "new Ray.vertex()" + const A = new Ray.vertex(); + const B = new Ray.vertex(); + A.compose(B); + } + { + const ray = Ray.size(2); + } + { + const ray = Ray.array([undefined, undefined]); + + } + { + const ray = Ray.boolean(); + } + + }); test(".traverse", () => { const events: any[] = []; const ray = Ray.array([]); @@ -15,7 +33,7 @@ describe("Ray", () => { // ray()()()()(); // ray.debug( - (event) => { + (event: Ray.Debug.Event) => { events.push(event); }, () => { diff --git a/environments/javascript/@orbitmines/rays/src/Ray.ts b/environments/javascript/@orbitmines/rays/src/Ray.ts index cb820af..6edc32d 100644 --- a/environments/javascript/@orbitmines/rays/src/Ray.ts +++ b/environments/javascript/@orbitmines/rays/src/Ray.ts @@ -27,17 +27,6 @@ namespace Ray { /** Storage/Movement operations which need to be implemented. */ & { [TKey in keyof Ray.Op.Impl]: Ray.Any } - export type Constructor = { - initial?: Ray.Any, - self?: Ray.Any, - terminal?: Ray.Any, - - proxy?: ProxyHandler, - debug?: Debug.Listener, - } - - export const New = (constructor?: Ray.Constructor): Ray.Any => Ray.Instance.New(constructor).proxy; - export namespace Debug { export type Event = { event: string, self: Ray.Any, context: any }; export type Listener = (event: Event) => void; @@ -48,29 +37,72 @@ namespace Ray { */ // export const None: Ray.FunctionConstructor = Ray.Function.CachedAfterUse(Ray.New); - export class Instance extends JS.Class.Instance { + // export class Object { + // + // // TODO: Could copy? + // get initial(): Ray.Any { return this._initial(); } set initial(initial: Ray.Any) { this._initial = initial; } protected _initial: Ray.Any; + // get self(): Ray.Any { return this._self(); } set self(self: Ray.Any) { this._self = self; } protected _self: Ray.Any; + // get terminal(): Ray.Any { return this._terminal(); } set terminal(terminal: Ray.Any) { this._terminal = terminal; } protected _terminal: Ray.Any; + // + // protected constructor({ initial, self, terminal }: { initial?: Ray.Any, self?: Ray.Any, terminal?: Ray.Any } = {}) { + // + // this._initial = initial ?? Ray.none.memoized; + // this._self = self ?? Ray.self_reference; + // this._terminal = terminal ?? Ray.none.memoized; + // } + // } + + /** A simplistic compiler for Ray */ + export namespace Compiler { // TODO Ray is Compiler - static New = (constructor?: Ray.Constructor): Ray.Instance => new Ray.Instance(constructor); + /** + * TODO: Compiler could have things like other composed rays which tell it cares about the other (even if that's correct or not??) + * + * + * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? + * + * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY + * + * TODO + * - Compose empty as first element? Disregard none to first elemn? Or not?? + * + * TODO; Impl + * - Generally, return something which knows where all continuations are. + * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. + * - Cache: + * - Control of (non-/)lazyness of functions + * - None as, first time called, memoize func. + * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence + * - a.orbit() -> a.orbit(a) + * // TODO: Should be automatic? is_orbit() or any method without arguments is a.is_orbit(a.self()) ?? not a.is_orbit(a) ; ??? + * + * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? + * + * TODO: Allow hooking + * + * TODO: Testing + * - Test if references hold after equivalence/composition... + * + * TODO: After initial demo: + * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) + * + * Arbitrary. + */ + } + export type Constructor = { proxy?: ProxyHandler, debug?: Debug.Listener, } - listeners: Debug.Listener[]; + export class Instance extends JS.Class.Instance { - // get initial(): Ray.Any { return this._initial.call(this.proxy); } set initial(initial: Ray.FunctionConstructor) { this._initial = Ray.Function.New(initial); } protected _initial: Ray.Function; - // get self(): Ray.Any { return this._self.call(this.proxy); } set self(self: Ray.FunctionConstructor) { this._self = Ray.Function.New(self); } protected _self: Ray.Function; - // get terminal(): Ray.Any { return this._terminal.call(this.proxy); } set terminal(terminal: Ray.FunctionConstructor) { this._terminal = Ray.Function.New(terminal); } protected _terminal: Ray.Function; + listeners: Debug.Listener[]; - protected constructor({ - // initial, self, terminal + constructor({ proxy, debug, }: Ray.Constructor = {}) { super({ proxy: proxy ?? Ray.ProxyHandlers.Default }); this.listeners = debug ? [debug] : []; - - // this._initial = Ray.Function.New(initial ?? Ray.None); - // this._self = Ray.Function.New(self ?? this.proxy); - // this._terminal = Ray.Function.New(terminal ?? Ray.None); } /** Used to jump out of the proxy. */ @@ -96,41 +128,6 @@ namespace Ray { } - export class Compiler { // Ray is Compiler - - /** - * TODO: Compiler could have things like other composed rays which tell it cares about the other (even if that's correct or not??) - * - * - * TODO: Do I want to keep the is_equiv/is_composed pattern? Or simplify to one of the two? - * - * // TODO: NEVER DIRECTLY EXECUTE, ONLY AFTER CHAIN OF FUNCS, possibly arbitrarily LAZY - * - * TODO - * - Compose empty as first element? Disregard none to first elemn? Or not?? - * - * TODO; Impl - * - Generally, return something which knows where all continuations are. - * - Generator/step function/... ; with no assumption of halting, but allow to hook into any step. - * - Cache: - * - Control of (non-/)lazyness of functions - * - None as, first time called, memoize func. - * - Perhaps locally cache (for stuff like count?) - no way to ensure globally coherence - * - a.orbit() -> a.orbit(a) - * // TODO: Should be automatic? is_orbit() or any method without arguments is a.is_orbit(a.self()) ?? not a.is_orbit(a) ; ??? - * - * - .initial/.terminal can be seen as a particular connection on .self, which .self ignores? - * - * TODO: Allow hooking - * - * TODO: Testing - * - Test if references hold after equivalence/composition... - * - * TODO: After initial demo: - * - Allow mapping/finding of other implementations regarding some equiv funcs (like different ways of implementing using NAND etc...) - */ - - } export namespace ProxyHandlers { @@ -372,17 +369,13 @@ namespace Ray { self => self.is_none().not() ); - export const self_reference = Ray.Function.Self.Impl( - self => self - ); - /** * @see "Continuations as Equivalence (can often be done in parallel - not generally)": https://orbitmines.com/papers/on-orbits-equivalence-and-inconsistencies#:~:text=Constructing%20Continuations%20%2D%20Continuations%20as%20Equivalence */ // @alias('merge, 'continues_with', 'compose') export const compose = Ray.Function.Self.Binary( - (a, b) => a.terminal().equivalent(b.initial()) - ); + (a, b) => a.terminal().equivalent(b.initial()) + ); /** * "Composing an terminal & initial boundary" @@ -399,7 +392,12 @@ namespace Ray { * - TODO: If we're only doing one end: This already assumes they are connected on the other end. * - TODO: should be a connection here, with is_composed ; or "reference.is_equivalent" so that you can drop one of the sides, or both. */ - (a, b) => ( b.last().compose(a.first()) ).and( a.first().compose(b.last()) ) + (a, b) => { + b.last().compose(a.first()); + a.first().compose(b.last()); + + return a; // ? + } ); /** @@ -442,8 +440,6 @@ namespace Ray { (a) => { throw new NotImplementedError(); } ); - - // TODO: .next but arbitrary step?? export const next = Ray.Function.Self.Impl((self) => { throw new NotImplementedError(); return self; @@ -510,8 +506,6 @@ namespace Ray { // TODO Relies heavily on the execution layer to copy initial/terminal etc... ; and an is_orbit check before calling copy again. - Then again on the execution layer it can lazily do this copy (by not evaluating (i.e.) traversing everywhere), or it first does this traversing directly. ); - export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. - /** * Placing existing structure on a new Reference, Boundary or Vertex: */ @@ -550,6 +544,9 @@ namespace Ray { return initial; }); + export const memoized = Ray.Function.Self.Impl( + self => { throw new NotImplementedError(); } + ); } } @@ -564,6 +561,11 @@ namespace Ray { export const number = (number: number) => { throw new NotImplementedError(); } + export const self_reference = Ray.Function.Self.Impl( + self => self + ); + export const none = Ray.Op.Zeroary.All.none; // TODO FOR ALL OPS, ? automatic, or just put them here. + // export const Boundary = { INITIAL: Type.INITIAL, TERMINAL: Type.TERMINAL }; TODO: LIST O // TODO CAN ALSO BE ZERO-ARY.. @@ -572,8 +574,17 @@ namespace Ray { (a, size) => { throw new NotImplementedError(); } ); // @alias('bit') - // export const boolean = size(2); + export const boolean = size(2); + export const vertex = Ray.Function.Self.Impl( + (self) => { throw new NotImplementedError(); } + ); + export const initial = Ray.Function.Self.Impl( + (self) => { throw new NotImplementedError(); } + ); + export const terminal = Ray.Function.Self.Impl( + (self) => { throw new NotImplementedError(); } + ); } export default Ray; \ No newline at end of file diff --git a/orbitmines.com/src/@orbitmines/explorer/Ray2.ts b/orbitmines.com/src/@orbitmines/explorer/Ray2.ts index 7739a75..3a1d57d 100644 --- a/orbitmines.com/src/@orbitmines/explorer/Ray2.ts +++ b/orbitmines.com/src/@orbitmines/explorer/Ray2.ts @@ -60,8 +60,6 @@ export class Ray { initial_vertex.compose(terminal_vertex); - // TODO BETTER DEBUG - return Ray.directions.next(terminal_vertex); } private ___as_vertices = (): [Ray, Ray] => { @@ -222,15 +220,6 @@ export class Ray { return copy; } - *traverse(step: Ray.FunctionImpl = Ray.directions.next): Generator { - // TODO: Also to ___func?? - - if (this.type !== RayType.VERTEX) - throw new NotImplementedError(`[${this.type}]`); - - yield *this.___next({step}); - } - *___next({ step = Ray.directions.next, } = {}): Generator { @@ -437,12 +426,6 @@ export class Ray { // throw new PreventsImplementationBug(`${pointers.length} left`) } - - /** - * - * TODO: - * - This needs something much smarter at some point... - */ all = (step: Ray.FunctionImpl = Ray.directions.next): { [key: string | symbol]: Ray.Any } & any => { return new Proxy(this, {