Ahh it is possible to get a nice regexp interface for ice-9/match. Consider (define (r1 x) (lambda (s) (regexp-exec (make-regexp x) s))) (define (r4 x) (lambda (s) (let ((res ((r1 x) s))) (if res (let lp ((out '()) (i 1)) (catch #t (lambda () (lp (cons (match:substring res i) out) (+ i 1))) (lambda x (reverse out)))) #f)))) This will produce a list of matchers or #f in case it fails. Testing this (notice i corrected a few bugs from before) we get scheme@(guile-user) [1]> (match "a(9)" ((= (r4 "^([a-z]+)\\(([0-9]+)\\)$") (v i)) (list v i))) $12 = ("a" "9") /Stefan On Mon, Feb 8, 2016 at 5:15 PM, Stefan Israelsson Tampe < stefan.itampe@gmail.com> wrote: > Because forwarded mail get hidden in modern mail clients I paste it here > as well. Sorry for the spam > An interesting question is what can be done by ice-9/match > > Consider > (define (r1 x) (regexp-exec (make-regexp x))) > > Then simple matching can be done like > > (match x > ((? (r1 "a+")) 'matche_a_lot_of_as) > ((? (r1 "b+")) 'matche_a_lot_of_bs) > ...) > > If we assume that the match = clause catches exceptiones we could use > (define (r2 x) > (let ((res (r1 x))) > (if r1 > r1 > (throw match-error)))) > > Then defining > > (define (nth i) > (lambda (x) (match:substring x i))) > > we can then do > > (match x > ((= (r2 "^([a-z]+)\\(([0-9]+)\\$")) (and (= (nth 1) v) (= (nth 2) i))) > (list v i)) > ...) > > Not as elegant as match-case but it is well composable. > > Another posibility is to define, i make this as simple as possible (the n > argument can be removed) > (define (r3 x n) > (let ((res (r1 x))) > (if res > (let lp ((out '()) (i n)) > (if (> n 0) > (lp (cons (match:substring res i) out) (- i 1)) > (reverse out))) > (throw match-error)))) > > Then this should enable a quite nice match as > > (match x > ((= (r3 "^([a-z]+)\\(([0-9]+)\\$" 2) (v i)) > (list v i)) > ...) > > which is not too bad. Now ice-9 match does not do the nessesary checks on > throw and there is quite a bit of over head in the exception mechanisms but > in principle we should be able to design an ice-9 match and an inlinable > r1, r2, r3 so that the code shoulud be effective compilied and the > exceptions transformed > into goto's. I would like to, like for records, add support in upstream > for catching a designated exception which shouled mean fail. What we could > ask for is > for foof to have customable macros like for slot-ref etc. e.g. > > (catch-error-object var thunk sucess-code failure-code) > > with default definition beeing > (let ((var (thunk) sucees-code) > > and our definition could be something like > (let ((res (catch match-error > (lambda () (thunk)) > (lambda x err-obj)))) > (if (eq? res err-obj) > failure-code > (let ((var res)) > success-code)))) > > It is not clean, but we can clobber the default macro definition > previously defined in upstream to introduce our macro without changing > upstream. > When this is ready we could think about improving the compiler to expand > regexp matches effectively. > > WDYT > > > On Mon, Feb 8, 2016 at 4:40 PM, Stefan Israelsson Tampe < > stefan.itampe@gmail.com> wrote: > >> >> ---------- Forwarded message ---------- >> From: Stefan Israelsson Tampe >> Date: Mon, Feb 8, 2016 at 4:31 PM >> Subject: Re: regex-case >> To: Ludovic Courtès >> >> >> An interesting question is what can be done by ice-9/match >> >> Consider >> (define (r1 x) (regexp-exec (make-regexp x))) >> >> Then simple matching can be done like >> >> (match x >> ((? (r1 "a+")) 'matche_a_lot_of_as) >> ((? (r1 "b+")) 'matche_a_lot_of_bs) >> ...) >> >> If we assume that the match = clause catches exceptiones we could use >> (define (r2 x) >> (let ((res (r1 x))) >> (if r1 >> r1 >> (throw match-error)))) >> >> Then defining >> >> (define (nth i) >> (lambda (x) (match:substring x i))) >> >> we can then do >> >> (match x >> ((= (r2 "^([a-z]+)\\(([0-9]+)\\$")) (and (= (nth 1) v) (= (nth 2) i))) >> (list v i)) >> ...) >> >> Not as elegant as match-case but it is well composable. >> >> Another posibility is to define, i make this as simple as possible (the n >> argument can be removed) >> (define (r3 x n) >> (let ((res (r1 x))) >> (if res >> (let lp ((out '()) (i n)) >> (if (> n 0) >> (lp (cons (match:substring res i) out) (- i 1)) >> (reverse out))) >> (throw match-error)))) >> >> Then this should enable a quite nice match as >> >> (match x >> ((= (r3 "^([a-z]+)\\(([0-9]+)\\$" 2) (v i)) >> (list v i)) >> ...) >> >> which is not too bad. Now ice-9 match does not do the nessesary checks on >> throw and there is quite a bit of over head in the exception mechanisms but >> in principle we should be able to design an ice-9 match and an inlinable >> r1, r2, r3 so that the code shoulud be effective compilied and the >> exceptions transformed >> into goto's. I would like to, like for records, add support in upstream >> for catching a designated exception which shouled mean fail. What we could >> ask for is >> for foof to have customable macros like for slot-ref etc. e.g. >> >> (catch-error-object var thunk sucess-code failure-code) >> >> with default definition beeing >> (let ((var (thunk) sucees-code) >> >> and our definition could be something like >> (let ((res (catch match-error >> (lambda () (thunk)) >> (lambda x err-obj)))) >> (if (eq? res err-obj) >> failure-code >> (let ((var res)) >> success-code)))) >> >> It is not clean, but we can clobber the default macro definition >> previously defined in upstream to introduce our macro without changing >> upstream. >> When this is ready we could think about improving the compiler to expand >> regexp matches effectively. >> >> WDYT >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> On Mon, Feb 8, 2016 at 3:29 PM, Ludovic Courtès wrote: >> >>> Matt Wette skribis: >>> >>> > (regex-case str >>> > (("^([a-z]+)\\(([0-9]+)\\)$" v i) >>> > (list v i)) >>> > (("^([a-z]+)$" v) >>> > (list v "1”))) >>> >>> Sounds useful and convenient! >>> >>> > (let ((t-292 (make-regexp "^([a-z]+)\\(([0-9]+)\\)$")) >>> > (t-293 (make-regexp "^([a-z]+)$"))) >>> > (cond ((regexp-exec t-292 str) >>> > => >>> > (lambda (m) >>> > (let ((v (match:substring m 1)) >>> > (i (match:substring m 2))) >>> > (list v i)))) >>> > ((regexp-exec t-293 str) >>> > => >>> > (lambda (m) >>> > (let ((v (match:substring m 1))) (list v "1")))))) >>> >>> When the ‘else’ clause is missing, I think it would be best to throw an >>> error like ‘match’ does—it’s rarely helpful to return #unspecified in >>> those cases. >>> >>> Ludo’. >>> >>> >>> >> >> >