git @ Cat's Eye Technologies define-opaque / master
Merge pull request #1 from cpressey/develop-0.1 develop 0.1 Chris Pressey authored 7 months ago GitHub committed 7 months ago
5 changed file(s) with 80 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
1010 means other than via the defined operations.
1111
1212 The macro is defined in
13 **[`src/define-opaque.scm`](src/define-opaque.scm)**.
13 **[`src/define-opaque-0.1.scm`](src/define-opaque-0.1.scm)**.
1414
1515 The idea is that you'd just copy it into your project and
1616 `(load "define-opaque.scm")` where you need it. For usage,
1717 see the demo files also in [the `src` directory](src/).
1818
19 This is an early version of the macro, and its name in
20 the source code is intended to indicate this fact.
21 If at some point it becomes more usable, I will update
22 its name.
19 ### Basic Instructions
20
21 The arguments to the `define-opaque` macro are
22
23 * the name of the opaque data structure that will result
24 (this name will be visible globally)
25 * the name of a function which creates a new instance
26 of the data structure
27 (this name will be visible only to the operations)
28 * a list of names for the data items used internally
29 (these names will be visible only to the operations)
30 * a list of operations. Each operation is a 2-element
31 list, consisting of its name, and a lambda expression
32 giving its implementation.
33
34 The opaque data structure that results is a Scheme
35 function. When it is called, the first argument
36 must be the name of an operation; the remainder of the
37 arguments are passed to
38
39 Typically, the opaque data structure that results
40 is treated as a "protoype", and one defines an operation
41 called `new` that provides a way to initialize a new
42 instance of the data structure based on some initialization
43 parameters.
44
45 If the above description is unclear, the example programs
46 in [the `src` directory](src/) may help illuminate the
47 usage patterns.
2348
2449 ### TODO
2550
2651 - [ ] is more than one private field supported?
2752 - [ ] support supplying initial values for private fields
2853
29
3054 [Information Hiding in Scheme]: https://github.com/cpressey/Information-Hiding-in-Scheme
0 This is free and unencumbered software released into the public domain.
1
2 Anyone is free to copy, modify, publish, use, compile, sell, or
3 distribute this software, either in source code form or as a compiled
4 binary, for any purpose, commercial or non-commercial, and by any
5 means.
6
7 In jurisdictions that recognize copyright laws, the author or authors
8 of this software dedicate any and all copyright interest in the
9 software to the public domain. We make this dedication for the benefit
10 of the public at large and to the detriment of our heirs and
11 successors. We intend this dedication to be an overt act of
12 relinquishment in perpetuity of all present and future rights to this
13 software under copyright law.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 OTHER DEALINGS IN THE SOFTWARE.
22
23 For more information, please refer to <http://unlicense.org/>
0 (define-syntax opaque-op
1 (syntax-rules ()
2 ((opaque-op (name body) args)
3 (apply body args))))
4
5 (define-syntax opaque-ops
6 (syntax-rules ()
7 ((opaque-ops target args ())
8 (begin
9 (display "Undefined operation ") (display target) (newline) #f))
10 ((opaque-ops target args (op rest ...))
11 (if (equal? (car 'op) target) (opaque-op op args) (opaque-ops target args (rest ...))))))
12
13 (define-syntax define-opaque
14 (syntax-rules ()
15 ((define-opaque name make-name privs ops)
16 (define name
17 (letrec
18 (
19 (make-name (lambda privs
20 (lambda (target . args)
21 (opaque-ops target args ops))))
22 )
23 (make-name '()))))))
+0
-24
src/define-opaque.scm less more
0 (define-syntax opaque-op
1 (syntax-rules ()
2 ((opaque-op (name body) args)
3 (apply body args))))
4
5 (define-syntax opaque-ops
6 (syntax-rules ()
7 ((opaque-ops target args ())
8 (begin
9 (display "Undefined operation ") (display target) (newline) #f))
10 ((opaque-ops target args (op rest ...))
11 (if (equal? (car 'op) target) (opaque-op op args) (opaque-ops target args (rest ...))))))
12
13 (define-syntax define-opaque-lousy
14 (syntax-rules ()
15 ((define-opaque-lousy name make-name privs ops)
16 (define name
17 (letrec
18 (
19 (make-name (lambda privs
20 (lambda (target . args)
21 (opaque-ops target args ops))))
22 )
23 (make-name '()))))))
00 ; usage: csi -q -b demo.scm
11
2 (load "define-opaque.scm")
2 (load "define-opaque-0.1.scm")
33
4 (define-opaque-lousy stack make-stack (items)
4 (define-opaque stack make-stack (items)
55 (
66 (new (lambda (new-items)
77 (make-stack new-items)))