unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* match-abs
@ 2010-08-29 21:56 Stefan Israelsson Tampe
  2010-08-30 22:55 ` match-abs Ludovic Courtès
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Israelsson Tampe @ 2010-08-29 21:56 UTC (permalink / raw)
  To: guile-devel

Hi,

I've hacked on extension on ice-9/match for making modular matching possible
with a reasonable interface. Here is an example,

;; new version of match with modular matching abatractions see 
;; http://gitorious.org/guile-unify/guile-
unify/blobs/master/module/ice-9/match-abs.scm
(use-modules (ice-9 match-abs))

;;Example, notice ((<op> A B)) means first result of <op> is stored in A and 
the second is in B
(define (<op> X)
  (match abstractions ((<op> A B))
	 X
	 (['- <op> <op>  . L]  (cons  (- B A)  L))
	 (['+ <op> <op>  . L]  (cons  (+ A B)  L))
	 (['* <op> <op>  . L]  (cons  (* A B)  L))
	 (['/ <op> <op>  . L]  (cons  (/ B A)  L))
	 ([(? number? X) . L]  (cons     X     L))
	 (_                    (cons    #f    #f))))

;;alternatively one can use the more general but wordy <> notation
(define (<op> X)
  (match X
	 (['- (<> <op> A) (<> <op> B)  . L]  (cons  (- A B)  L))
	 (['+ (<> <op> A) (<> <op> B)  . L]  (cons  (+ A B)  L))
	 (['* (<> <op> A) (<> <op> B)  . L]  (cons  (* A B)  L))
	 (['/ (<> <op> A) (<> <op> B)  . L]  (cons  (/ A B)  L))
	 ([(? number? X) . L]  (cons     X     L))
	 (_                    (cons    #f    #f))))

(define (rpn x) (car (<op> (reverse x))))

;;and (rpn '(2 4 * 1 -)) evaluates to 7


So e.g. the protocol for a matcher is that the last argument for a matcher
is the list to match on. The matcher should return a cons cell, if the car
element is false the match fails and else it is the value of the match. the 
second argument represent the rest of the list after the match has been 
removed. 

More examples, this is a gready matcher that tries to match as much as 
possible
It has a curry feature thats cool.

(define (<*> <a> . r)
  (define (f x res)
    (let ((ret (<a> x)))
      (if (car ret)
	  (f (cdr ret) (cons (car ret res)))
	  (cons (reverse res) x))))
  (if (pair? r)
      (f (car r) '())
      (lambda (l) (f l '()))))


(define (<alternate> <a> <b> l)
  (match abstractions ((<a> a1 a2)(<b> b1 b2))
	 l  
	 ([<a> <b> <a> <b> . ls]  (cons (apend a1 a2 b1 b2) ls))
	 (_                       (cons #f #f))))


and now we can do something like this thanks to the currying

(match abstractions ((<alternate> alt) (<*> m3))
       X
       ((<alternate> (<*> <match1>) (<*> <match2>) (<*> <match3>))
	(append m3 alt)))

Note here <match1>, ... , <match3> are all function arguments and does not
represent a part of the match hence these abstractions are not mensioned
at the abstraction definitions also the first two <*> is at function postions 
and also in function position. also this means that (<*> <match1>) will need
to use the currying feature of <*> in order to function correctly. So here we 
se a nice application of currying.

(match abstractions ((<alternate> alt) (<*> m3))
       X
       ((<> (<alternate> (<*> <match1>) (<*> <match2>) alt)(<*> <match3>))
	(append m3 alt)))

Using <> things gets clearer.


So Is this something that can be of any interests? It's been a good exercise
in syntax-case macro writing and I do feel like I'm mastering the ice-9 match
that we are currently working on so however we choose, we do not loose.

Note 1, I've used a similar tool in parsing prolog, but I do not use this for
operatore precedence handling.

Note 2. One can device a proper backtracking methodology so that we could
have matched  (bbbbbbba) with matcher ((<*> <b>) 'b 'a), where <b> matches b, 
(<*> <b>) will consume all the b:s and not backtrack when the rest fails 
((and 'b bs) ... 'b 'a) will do the trick though!)
but I feel that using prolog or the scheme version of it (schelog?) in the 
first place is a better tool to achive this. One need to play with 
continuatons
very much like working with the prolog code I made. If you like I can make 
that
work and/or.

Note 3 using (defmacro (/. p r) 
	       `(lambda (l) (match l 
				   ((,p . l) (cons ,r  l)) 
				   (_       (cons #f #f)))))
or a correct define-syntax version of it means that we could write a matcher
like ((<*> (/. 'b 'b)) 'b 'a) in the above syntax

Cheers
Stefan

      
   





^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-09-02 22:46 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-29 21:56 match-abs Stefan Israelsson Tampe
2010-08-30 22:55 ` match-abs Ludovic Courtès
2010-08-31 14:42   ` match-abs Ludovic Courtès
2010-09-01  9:34     ` match-abs Stefan Israelsson Tampe
2010-09-01 12:05       ` match-abs Ludovic Courtès
2010-09-01  7:30   ` match-abs Stefan Israelsson Tampe
2010-09-02 15:59     ` match-abs Ludovic Courtès
2010-09-02 18:07       ` match-abs Stefan Israelsson Tampe
2010-09-02 18:53       ` match-abs Stefan Israelsson Tampe
2010-09-02 22:46         ` match-abs Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).