LoginSignup
0
0

More than 5 years have passed since last update.

Matching Thunk Object in Optima

Last updated at Posted at 2014-01-07
(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.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0