Differences From
Artifact [fd266dcc3b]:
1 -; ʞ / interlace.scm
2 -; a scheme library by lexi hale
3 -;
4 -; (interlace) solves an age-old problem. what kind of data structure
5 -; do you use when you need both an aggregate (a list, a vector) of
6 -; items but also to be able to individually refer to those items by
7 -; name? this problem is effectively unsolvable in C and C++ without
8 -; inordinate runtime overhead, and there's no native syntax for it
9 -; in Scheme. however, by rewriting the AST, we can implement a clean,
10 -; performant, low-cost solution ourselves, thanks to the fact that
11 -; (let*) bindings are expressions.
1 +; [ʞ] interlace.scm
2 +; ~ lexi hale <lexi@hale.su>
3 +; © affero general public license
4 +; > (load "lib/lisp-macro.scm")
5 +; (load "lib/interlace.scm")
6 +
7 +; (interlace) solves an old problem. what kind of data
8 +; structure do you use when you need both an aggregate
9 +; (a list, a vector) of items but also to be able
10 +; to individually refer to those items by name? this
11 +; problem is effectively unsolvable in C and C++ without
12 +; inordinate runtime overhead, and there's no native
13 +; syntax for it in Scheme. however, by rewriting the AST,
14 +; we can implement a clean, performant, low-cost solution
15 +; ourselves, thanks to the fact that (let*) bindings are
16 +; expressions.
12 17 ;
13 -; interlace takes a constructor function, e.g. (vector) or (list),
14 -; a list of items, and returns an expression calling that constructor
15 -; on a list of all items defined in it. if an item is proceded by
16 -; an atom that ends in a period (e.g. “name.”), it is defined within
17 -; a (let*) expression, and its name is then included among the
18 +; interlace takes a constructor function, e.g. (vector)
19 +; or (list), a list of items, and returns an expression
20 +; calling that constructor on a list of all items defined
21 +; in it. if an item is proceded by an atom that ends in a
22 +; period (e.g. “name.”), it is defined within a (let*)
23 +; expression, and its name is then included among the
18 24 ; arguments passed to the constructor function.
19 25 ;
20 -; the upshot of this is that items can reference other items by name
21 -; *as they are being defined*. for instance:
26 +; the upshot of this is that items can reference other
27 +; items by name *as they are being defined*. for
28 +; instance:
22 29 ;
23 -; (define verbs (interlace vector
24 -; talk. (verb "talk" "talking" "talked")
25 -; (phrasal-verb talk "to")
26 -; (phrasal-verb talk "about")
27 -; (verb "say" "saying" "said)))
30 +; ex: (define verbs (interlace vector
31 +; talk. (verb "talk" "talking" "talked")
32 +; (phrasal-verb talk "to")
33 +; (phrasal-verb talk "about")
34 +; (verb "say" "saying" "said)))
28 35 ;
29 -; here, the function to generate a phrasal verb exhibits backreference
30 -; to an existing verb contained alongside it in the vector. note that
31 -; the name bindings are ephemeral; they do not survive the immediate
32 -; context of the constructor.
36 +; here, the function to generate a phrasal verb exhibits
37 +; backreference to an existing verb contained alongside
38 +; it in the vector. note that the name bindings are
39 +; ephemeral; they do not survive the immediate context of
40 +; the constructor.
33 41
34 42 (define-macro (interlace . body)
35 43 ; given a list with both named and nameless members, identify
36 44 ; which is which and instate the vector.
37 45 (define (name? term)
38 46 ; given a symbol, determine wheter it is a name, and if so return
39 47 ; that name as a string and without the name-marking suffix ‹.›