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 <
[email protected]> 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 <
> [email protected]> wrote:
>
>>
>> ---------- Forwarded message ----------
>> From: Stefan Israelsson Tampe <[email protected]>
>> Date: Mon, Feb 8, 2016 at 4:31 PM
>> Subject: Re: regex-case
>> To: Ludovic Courtès <[email protected]>
>>
>>
>> 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 <[email protected]> wrote:
>>
>>> Matt Wette <[email protected]> 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’.
>>>
>>>
>>>
>>
>>
>

Reply via email to