(use-package :trivial-lazy)
(use-package :optima)
;; (delay x) ~~ (lambda () x)
(defmacro lcons (a b)
"cons whose car and cdr is lazy"
`(cons (delay ,a)
(delay ,b)))
(defpattern lazy (pattern)
(with-gensyms (thunk)
`(guard ,thunk (match (force ,thunk) (,pattern t)))))
(defpattern lcons (lcar lcdr)
(with-gensyms (thunk1 thunk2)
`(cons (lazy ,lcar)
(lazy ,lcdr))))
;; This is OK
(match (lcons 1 2)
((lcons 1 2)
t))
;; but this is not
(match (lcons 1 2)
((lcons a b)
(+ a b)))
Any ideas?
RE: use the accessor functions (evaluated):
(defun lazy-consp (x)
(consp x))
(defun lazy-conscar (x)
(force (car x)))
(defun lazy-conscdr (x)
(force (cdr x)))
(defpattern lcons (lcar lcdr)
`(lazy-cons (car ,lcar) (cdr ,lcdr)))
;; then this works
(match (lcons 1 2)
((lcons a b)
(+ a b)))
;; -> 3
Accessor functions accept only one argument.
Consider x
in the above example. --- x
is the object being accessed.
In order to specify how to get the value to be stored in the variable in the matching context (in the example above, a
and b
) we need additional arguments.
x = (lcons 1 2) --(lazy-conscar x)--> 1
(accessed object) (accessor) (value)
^
|
| this is specified by the constructor-pattern
x --(funcall #'(lambda (x) ...) x)--> value
^
|
| we want to specify arbitrary accessor
| in the pattern matching clause.
The relationship between a pattern clause
and the accessor-function
is
currently hard-coded (in constructor-pattern) or require additional layer
(defpattern and gritchy lazy-consp/lazy-conscar/lazy-conscdr).
I sometimes think there are only two clauses needed in order to implement a
pattern matcher. They are type
and access
.
If everything is built on those clauses and defpattern
, things should
be simpler. Imagine if cons
pattern is not hard-coded and
implemented with type
, access
and defpattern
.
(defpattern cons (car cdr)
`(and (type cons)
(access #'car ,car)
(access #'cdr ,cdr)))
(match a
((cons b c)
(some-op b c)))
;; is equivalent to
(match a
((and (type cons)
(access #'car b)
(access #'cdr c))
(some-op b c)))
then the optima's compiler would be simple.
Any comments are welcome.
Note: I ignored not
, or
and guard
clause.