I added a new field that works as an encapsulated field like this:
(define-lambda-object stack
(,name 'stack) ;automatic-field
(,,stack '()) ;hidden-field
(,@pop (if (null? stack) ;virtual-field
(error 'stack "null stack" stack)
(let ((s (car stack))) (set! stack (cdr stack)) s)))
(,push (lambda (s) (set! stack (cons s stack))))) ;automatic-field
(define stack (make-stack))
((stack 'push) 1)
((stack 'push) 2)
(stack 'pop) => 2
(stack 'pop) => 1
(stack 'pop) => error: stack 'null stack' ()
(stack 'name) => stack
(stack 'stack) => error: define-lambda-object 'absent field' stack
The specification is changed as follows:
<automatic field> --> <automatic real field> ;automatic field
| <automatic hidden field> ;hidden field
| <automatic virtual field> ;virtual field
<automatic real field> --> (,<field> <default>) ;read-only field
| ((,<field>) <default>) ;read-write field
<automatic hidden field> --> (,,<field> <default>) ;inaccessable field
<automatic virtual field> --> (,@<field> <default>) ;immutable field
The <automatic real field> and <automatic hidden field> are initialized to
each corresponding <default> that is evaluated at the time the lambda object
is made by a constructor.
The <automatic hidden field> is an externally nonexistent field, that is, the
field is invisible outside of the define-lambda-object form but visible inside
of it. On the contrary, the <automatic virtual field> is an internally
nonexistent field whose <default> is evaluated each time when the field is
accessed.
--
Joo