Merge pull request #1 from cpressey/develop-0.1
develop 0.1
Chris Pressey authored 7 months ago
GitHub committed 7 months ago
10 | 10 | means other than via the defined operations. |
11 | 11 | |
12 | 12 | 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)**. | |
14 | 14 | |
15 | 15 | The idea is that you'd just copy it into your project and |
16 | 16 | `(load "define-opaque.scm")` where you need it. For usage, |
17 | 17 | see the demo files also in [the `src` directory](src/). |
18 | 18 | |
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. | |
23 | 48 | |
24 | 49 | ### TODO |
25 | 50 | |
26 | 51 | - [ ] is more than one private field supported? |
27 | 52 | - [ ] support supplying initial values for private fields |
28 | 53 | |
29 | ||
30 | 54 | [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 | (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 '())))))) |