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 --]
prev parent 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).