@@ -1,36 +1,44 @@ -; ʞ / interlace.scm -; a scheme library by lexi hale -; -; (interlace) solves an age-old problem. what kind of data structure -; do you use when you need both an aggregate (a list, a vector) of -; items but also to be able to individually refer to those items by -; name? this problem is effectively unsolvable in C and C++ without -; inordinate runtime overhead, and there's no native syntax for it -; in Scheme. however, by rewriting the AST, we can implement a clean, -; performant, low-cost solution ourselves, thanks to the fact that -; (let*) bindings are expressions. +; [ʞ] interlace.scm +; ~ lexi hale +; © affero general public license +; > (load "lib/lisp-macro.scm") +; (load "lib/interlace.scm") + +; (interlace) solves an old problem. what kind of data +; structure do you use when you need both an aggregate +; (a list, a vector) of items but also to be able +; to individually refer to those items by name? this +; problem is effectively unsolvable in C and C++ without +; inordinate runtime overhead, and there's no native +; syntax for it in Scheme. however, by rewriting the AST, +; we can implement a clean, performant, low-cost solution +; ourselves, thanks to the fact that (let*) bindings are +; expressions. ; -; interlace takes a constructor function, e.g. (vector) or (list), -; a list of items, and returns an expression calling that constructor -; on a list of all items defined in it. if an item is proceded by -; an atom that ends in a period (e.g. “name.”), it is defined within -; a (let*) expression, and its name is then included among the +; interlace takes a constructor function, e.g. (vector) +; or (list), a list of items, and returns an expression +; calling that constructor on a list of all items defined +; in it. if an item is proceded by an atom that ends in a +; period (e.g. “name.”), it is defined within a (let*) +; expression, and its name is then included among the ; arguments passed to the constructor function. ; -; the upshot of this is that items can reference other items by name -; *as they are being defined*. for instance: +; the upshot of this is that items can reference other +; items by name *as they are being defined*. for +; instance: ; -; (define verbs (interlace vector -; talk. (verb "talk" "talking" "talked") -; (phrasal-verb talk "to") -; (phrasal-verb talk "about") -; (verb "say" "saying" "said))) +; ex: (define verbs (interlace vector +; talk. (verb "talk" "talking" "talked") +; (phrasal-verb talk "to") +; (phrasal-verb talk "about") +; (verb "say" "saying" "said))) ; -; here, the function to generate a phrasal verb exhibits backreference -; to an existing verb contained alongside it in the vector. note that -; the name bindings are ephemeral; they do not survive the immediate -; context of the constructor. +; here, the function to generate a phrasal verb exhibits +; backreference to an existing verb contained alongside +; it in the vector. note that the name bindings are +; ephemeral; they do not survive the immediate context of +; the constructor. (define-macro (interlace . body) ; given a list with both named and nameless members, identify ; which is which and instate the vector.