unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Stefan Israelsson Tampe <stefan.itampe@gmail.com>
To: guile-devel <guile-devel@gnu.org>
Subject: Re: regex-case
Date: Mon, 8 Feb 2016 17:50:33 +0100	[thread overview]
Message-ID: <CAGua6m0FMHzhqJau97ci5MnPc5wpOzzH7cL9gMMgB3b=OC-ajg@mail.gmail.com> (raw)
In-Reply-To: <CAGua6m0Efot2A+PJutJ6auE_wp2JRcvMv=iWi=v0NOycwGQ0Dg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 7722 bytes --]

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 <stefan.itampe@gmail.com>
>> Date: Mon, Feb 8, 2016 at 4:31 PM
>> Subject: Re: regex-case
>> To: Ludovic Courtès <ludo@gnu.org>
>>
>>
>> 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 <ludo@gnu.org> wrote:
>>
>>> Matt Wette <matthew.wette@verizon.net> 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’.
>>>
>>>
>>>
>>
>>
>

[-- Attachment #2: Type: text/html, Size: 19240 bytes --]

      reply	other threads:[~2016-02-08 16:50 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <61E420AD-70B6-4DEA-A7DD-EB123E22EFD0@verizon.net>
     [not found] ` <87oabrgtrg.fsf@gnu.org>
     [not found]   ` <CAGua6m1_gbvJk_XPzg95NTRYwZAXO_wKJyKyfjOT-vFirn3Vcg@mail.gmail.com>
2016-02-08 15:40     ` Fwd: regex-case Stefan Israelsson Tampe
2016-02-08 16:04       ` regex-case Matt Wette
2016-02-08 16:15       ` regex-case Stefan Israelsson Tampe
2016-02-08 16:50         ` Stefan Israelsson Tampe [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAGua6m0FMHzhqJau97ci5MnPc5wpOzzH7cL9gMMgB3b=OC-ajg@mail.gmail.com' \
    --to=stefan.itampe@gmail.com \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).