[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fwd: regex-case

From: Stefan Israelsson Tampe
Subject: Fwd: regex-case
Date: Mon, 8 Feb 2016 16:40:21 +0100

---------- Forwarded message ----------
From: Stefan Israelsson Tampe <address@hidden>
Date: Mon, Feb 8, 2016 at 4:31 PM
Subject: Re: regex-case
To: Ludovic Courtès <address@hidden>

An interesting question is what can be done by ice-9/match

(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
           (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)
        (let ((var res))

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.



On Mon, Feb 8, 2016 at 3:29 PM, Ludovic Courtès <address@hidden> wrote:
Matt Wette <address@hidden> 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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]