guicho271828 / trivia

Pattern Matcher Compatible with Optima
Other
334 stars 22 forks source link

Add Optima's Extra Functions #33

Closed noctuid closed 8 years ago

noctuid commented 8 years ago

I think it would be nice to have optima's extra functions. Trivia has the lambda-match functions, but I don't see if-match, when-match, let-match, etc. I think let-match is especially useful and extends optima to be able to be used in much the same way as metabang-bind.

Taking an idea from metabang bind, it might also be nice to be able to match slots with their accessors. Also, I was wondering if it would be possible to have a values pattern or is multiple-value-match a necessity?

guicho271828 commented 8 years ago

okay, it seems to work as is if I copy&paste the extra source into trivia.

noctuid commented 8 years ago

Thank you.

guicho271828 commented 8 years ago

I missed the latter part of the request.

Taking an idea from metabang bind, it might also be nice to be able to match slots with their accessors.

This is already supported.

Also, I was wondering if it would be possible to have a values pattern or is multiple-value-match a necessity?

it is a nontrivial issue. Note that in some cases values-list should be useful.

noctuid commented 8 years ago

Maybe I'm just missing it, but they all seem to match the slot name itself as opposed to the name of the accessor. Which would be the equivalent of with-accessors?

Yeah I guess in most cases, I could use values-list with let-match. Thanks.

guicho271828 commented 8 years ago

with-accessors

Sorry, this point is poorly documented. I put a decent amount of effort in class/structure patterns in order to maintain the compatibility to Optima. As you can see in level2/derived-class.lisp#L266, just put an accessor name and it will be recognized. Mapping a name to a single reader in an unbiguous way, with a support for multiple styles, is quite complex.

guicho271828 commented 8 years ago

you still have to specify the class name in order to use the feature. however, standard-object might just work.

(defclass a () ((%name :reader name :initarg :x))) ;; <--- reader is NAME
(defun fn (x)
   (match x
      ((class standard-object name) ;; <-- accessor NAME
       (print name))))
(fn (make-instance 'a :x 1))
;; -> 1

(defun wrap (x) (name x)) ;; <--- arbitrary function works
(defun fn (x)
   (match x
      ((class standard-object wrap) ;; maps an fbound symbol WRAP to the accessor function
       (print wrap))))
(fn (make-instance 'a :x 1))
;; -> 1

(defun fn (x)
   (match x
      ((class standard-object (wrap val)) ;; result of calling WRAP is bound to VAL, same as in with-accessors
       (print val))))
(fn (make-instance 'a :x 1))
guicho271828 commented 8 years ago

you also have access pattern.

https://github.com/guicho271828/trivia/wiki/Special-Patterns#access-pattern

noctuid commented 8 years ago

Thanks, that's even nicer than what I'd imagined.