* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
@ 2017-07-12 6:13 Tino Calancha
2017-07-20 0:54 ` Drew Adams
2017-07-20 19:51 ` Philipp Stephani
0 siblings, 2 replies; 14+ messages in thread
From: Tino Calancha @ 2017-07-12 6:13 UTC (permalink / raw)
To: 27659
Severity: wishlist
Just wondering if the following is of any interest:
(defun string-matched-text (regexp string num &optional start)
""
(when (string-match regexp string start)
(match-string num string)))
Then,
(let ((str "foo-123"))
(when (string-match "[[:alpha:]]+-\\([0-9]+\\)" str)
(match-string 1 str)))
=> "123"
is equivalent to:
(string-matched-text "[[:alpha:]]+-\\([0-9]+\\)" "foo-123" 1)
=> "123"
--8<-----------------------------cut here---------------start------------->8---
commit 65741b74d8999beaacd5093e128030a8635aff05
Author: Tino Calancha <tino.calancha@gmail.com>
Date: Wed Jul 12 14:29:08 2017 +0900
string-matched-text: New function
* lisp/subr.el (string-matched-text): New defun.
* doc/lispref/searching.texi (Simple Match Data): Update manual.
* etc/NEWS: Announce it.
diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi
index 67d4c22464..81bcad1740 100644
--- a/doc/lispref/searching.texi
+++ b/doc/lispref/searching.texi
@@ -1457,6 +1457,16 @@ Simple Match Data
repetition that repeated zero times.
@end defun
+@defun string-matched-text regexp string count &optional start
+This function returns, as a string, the text matched by @var{regexp}
+in @var{string}, or @code{nil} if there is no match. The meaning
+of @var{count} is same as in @code{match-string}. If @var{start}
+is non-@code{nil}, the search starts at that index in @var{string}.
+The behavior of this function is equivalent to
+@w{@code{(and (string-match @var{regexp} @var{string} @var{start})
+(match-string @var{count} @var{string}))}}.
+@end defun
+
@defun match-string-no-properties count &optional in-string
This function is like @code{match-string} except that the result
has no text properties.
diff --git a/etc/NEWS b/etc/NEWS
index 68ebdb3c15..794edef9cd 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1105,6 +1105,8 @@ break.
\f
* Lisp Changes in Emacs 26.1
+** New function 'string-matched-text'.
+
** New function 'seq-set-equal-p' to check if SEQUENCE1 and SEQUENCE2
contain the same elements, regardless of the order.
diff --git a/lisp/subr.el b/lisp/subr.el
index a9edff6166..1482787842 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3635,6 +3635,15 @@ match-string
(substring string (match-beginning num) (match-end num))
(buffer-substring (match-beginning num) (match-end num)))))
+(defun string-matched-text (regexp string num &optional start)
+ "Return string of text matched by REGEXP in STRING.
+NUM specifies which parenthesized expression in REGEXP.
+ Value is nil if NUMth pair didn’t match, or there were less than NUM pairs.
+Zero means the entire text matched by the whole regexp or whole string.
+If optional arg START is non-nil, then start search at that index in STRING."
+ (when (string-match regexp string start)
+ (match-string num string)))
+
(defun match-string-no-properties (num &optional string)
"Return string of text matched by last search, without text properties.
NUM specifies which parenthesized expression in the last regexp.
--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 26.0.50 (build 4, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
of 2017-07-11
Repository revision: d014a5e15c1110af77e7a96f06ccd0f0cafb099f
^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-12 6:13 bug#27659: 26.0.50; Add string-matched-text: string-match + match-string Tino Calancha
@ 2017-07-20 0:54 ` Drew Adams
2017-07-20 1:19 ` Tino Calancha
2017-07-20 19:51 ` Philipp Stephani
1 sibling, 1 reply; 14+ messages in thread
From: Drew Adams @ 2017-07-20 0:54 UTC (permalink / raw)
To: Tino Calancha, 27659
> (when (string-match "[[:alpha:]]+-\\([0-9]+\\)" str)
> (match-string 1 str))
> is equivalent to:
> (string-matched-text "[[:alpha:]]+-\\([0-9]+\\)" str 1)
My own opinion, FWIW, is that the former is much clearer
and is sufficiently succinct. YAGNI.
[FWIW2:
I would write the former as
(and (string-match ...) (match-string...)), not as
(when (string-match ...) (match-string...)).
I follow the Common Lisp convention of using `when' to
indicate (to a human) that the return value is not
important (the function is used for side effects only).
I don't expect a human reader to look for a `nil' return
value from `when', for instance.]
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-20 0:54 ` Drew Adams
@ 2017-07-20 1:19 ` Tino Calancha
0 siblings, 0 replies; 14+ messages in thread
From: Tino Calancha @ 2017-07-20 1:19 UTC (permalink / raw)
To: 27659-done
Drew Adams <drew.adams@oracle.com> writes:
>> (when (string-match "[[:alpha:]]+-\\([0-9]+\\)" str)
>> (match-string 1 str))
>> is equivalent to:
>> (string-matched-text "[[:alpha:]]+-\\([0-9]+\\)" str 1)
>
> My own opinion, FWIW, is that the former is much clearer
> and is sufficiently succinct. YAGNI.
Thank you for your feedback and tips.
I am closing the report since it seems this proposal
doesn't bring us actual value.
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-12 6:13 bug#27659: 26.0.50; Add string-matched-text: string-match + match-string Tino Calancha
2017-07-20 0:54 ` Drew Adams
@ 2017-07-20 19:51 ` Philipp Stephani
2017-07-21 12:29 ` Tino Calancha
2017-07-22 1:46 ` Michael Heerdegen
1 sibling, 2 replies; 14+ messages in thread
From: Philipp Stephani @ 2017-07-20 19:51 UTC (permalink / raw)
To: Tino Calancha, 27659
[-- Attachment #1.1: Type: text/plain, Size: 670 bytes --]
Tino Calancha <tino.calancha@gmail.com> schrieb am Mi., 12. Juli 2017 um
08:16 Uhr:
> Severity: wishlist
>
> Just wondering if the following is of any interest:
>
> (defun string-matched-text (regexp string num &optional start)
> ""
> (when (string-match regexp string start)
> (match-string num string)))
>
> Then,
>
> (let ((str "foo-123"))
> (when (string-match "[[:alpha:]]+-\\([0-9]+\\)" str)
> (match-string 1 str)))
> => "123"
>
> is equivalent to:
> (string-matched-text "[[:alpha:]]+-\\([0-9]+\\)" "foo-123" 1)
> => "123"
>
This looks useful, but I think it would be even better to add it as a pcase
macro to be composable (see attached patch).
[-- Attachment #1.2: Type: text/html, Size: 1095 bytes --]
[-- Attachment #2: 0001-Add-rx-pattern-for-pcase.txt --]
[-- Type: text/plain, Size: 4322 bytes --]
From b95f7477887a283134a19021b8d21ee466d457c3 Mon Sep 17 00:00:00 2001
From: Philipp Stephani <phst@google.com>
Date: Thu, 20 Jul 2017 21:36:18 +0200
Subject: [PATCH] Add 'rx' pattern for pcase.
* lisp/emacs-lisp/pcase.el (rx): New pcase macro.
* test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-rx): Add unit test.
---
etc/NEWS | 3 +++
lisp/emacs-lisp/pcase.el | 47 +++++++++++++++++++++++++++++++++++++
test/lisp/emacs-lisp/pcase-tests.el | 9 +++++++
3 files changed, 59 insertions(+)
diff --git a/etc/NEWS b/etc/NEWS
index 954fe0d547..a16db7f4e0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1521,6 +1521,9 @@ manual.
** 'tcl-auto-fill-mode' is now declared obsolete. Its functionality
can be replicated simply by setting 'comment-auto-fill-only-comments'.
+** New pcase pattern 'rx' to match against a rx-style regular
+expression.
+
\f
* Changes in Emacs 26.1 on Non-Free Operating Systems
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 4a06ab25d3..2273840916 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -54,6 +54,7 @@
;;; Code:
(require 'macroexp)
+(require 'rx)
;; Macro-expansion of pcase is reasonably fast, so it's not a problem
;; when byte-compiling a file, but when interpreting the code, if the pcase
@@ -930,6 +931,52 @@ pcase--u1
((or (stringp qpat) (integerp qpat) (symbolp qpat)) `',qpat)
(t (error "Unknown QPAT: %S" qpat))))
+(pcase-defmacro rx (&rest regexps)
+ "Build a `pcase' pattern matching `rx' regexps.
+The REGEXPS are interpreted as by `rx'. The pattern matches if
+the regular expression so constructed matches the object, as if
+by `string-match'.
+
+Within the case code, the match data is bound as usual, but you
+still have to pass the correct string as argument to
+`match-string'.
+
+In addition to the usual `rx' constructs, REGEXPS can contain the
+following constructs:
+
+ (let VAR FORM...) creates a new explicitly numbered submatch
+ that matches FORM and binds the match to
+ VAR.
+ (backref-var VAR) creates a backreference to the submatch
+ introduced by a previous (let VAR ...)
+ construct.
+
+The VARs are associated with explicitly numbered submatches
+starting from 1. Multiple occurrences of the same VAR refer to
+the same submatch."
+ (let* ((vars ())
+ (rx-constituents
+ `((let ,(lambda (form)
+ (rx-check form)
+ (let ((var (cadr form)))
+ (cl-check-type var symbol)
+ (let ((i (or (cl-position var vars :test #'eq)
+ (prog1 (length vars)
+ (setq vars `(,@vars ,var))))))
+ (rx-form `(submatch-n ,(1+ i) ,@(cddr form))))))
+ 1 nil)
+ (backref-var ,(lambda (form)
+ (rx-check form)
+ (rx-form
+ `(backref ,(1+ (cl-position (cadr form) vars
+ :test #'eq)))))
+ 1 1 ,(lambda (var) (memq var vars)))
+ ,@rx-constituents))
+ (regexp (rx-to-string `(seq ,@regexps) :no-group)))
+ `(and (pred (string-match ,regexp))
+ ,@(cl-loop for i from 1
+ for var in vars
+ collect `(app (match-string ,i) ,var)))))
(provide 'pcase)
;;; pcase.el ends here
diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el
index ef0b2f6b24..a887b460b1 100644
--- a/test/lisp/emacs-lisp/pcase-tests.el
+++ b/test/lisp/emacs-lisp/pcase-tests.el
@@ -67,6 +67,15 @@ pcase-tests-grep
(ert-deftest pcase-tests-vectors ()
(should (equal (pcase [1 2] (`[,x] 1) (`[,x ,y] (+ x y))) 3)))
+(ert-deftest pcase-tests-rx ()
+ (should (equal (pcase "a 1 2 3 1 b"
+ ((rx (let u (+ digit)) space
+ (let v (+ digit)) space
+ (let v (+ digit)) space
+ (backref-var u))
+ (list u v)))
+ '("1" "3"))))
+
;; Local Variables:
;; no-byte-compile: t
;; End:
--
2.14.0.rc0.284.gd933b75aa4-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-20 19:51 ` Philipp Stephani
@ 2017-07-21 12:29 ` Tino Calancha
2017-07-21 13:34 ` Stefan Monnier
2017-07-22 1:46 ` Michael Heerdegen
1 sibling, 1 reply; 14+ messages in thread
From: Tino Calancha @ 2017-07-21 12:29 UTC (permalink / raw)
To: Philipp Stephani; +Cc: 27659, Michael Heerdegen, Stefan Monnier, Tino Calancha
[-- Attachment #1: Type: text/plain, Size: 925 bytes --]
On Thu, 20 Jul 2017, Philipp Stephani wrote:
>
>
> Tino Calancha <tino.calancha@gmail.com> schrieb am Mi., 12. Juli 2017 um 08:16 Uhr:
> Severity: wishlist
>
> Just wondering if the following is of any interest:
>
> (defun string-matched-text (regexp string num &optional start)
> ""
> (when (string-match regexp string start)
> (match-string num string)))
>
> Then,
>
> (let ((str "foo-123"))
> (when (string-match "[[:alpha:]]+-\\([0-9]+\\)" str)
> (match-string 1 str)))
> => "123"
>
> is equivalent to:
> (string-matched-text "[[:alpha:]]+-\\([0-9]+\\)" "foo-123" 1)
> => "123"
>
>
> This looks useful, but I think it would be even better to add it as a pcase macro to be composable (see attached patch).
Thank you!
Although, i must admit i am not fluent in `rx' syntaxis, i find your idea
very nice.
Tino
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-21 12:29 ` Tino Calancha
@ 2017-07-21 13:34 ` Stefan Monnier
2017-07-21 14:08 ` Tino Calancha
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Stefan Monnier @ 2017-07-21 13:34 UTC (permalink / raw)
To: Tino Calancha; +Cc: 27659, Michael Heerdegen, Philipp Stephani
>> This looks useful, but I think it would be even better to add it
>> as a pcase macro to be composable (see attached patch).
Hey, very nice. Please add it to rx.el.
[ But please change `backref-var` to just `backref` (you can distinguish
the two based on the type of the argument, I think). I guess one
could also argue that you could similarly rename the `let` to
`group-n`. ]
> Although, i must admit i am not fluent in `rx' syntaxis, i find your idea
> very nice.
If you prefer the standard/cryptic regexp syntax, I posted a similar
thingy in the past (see below).
This lets you do
(pcase "foo-123"
((re-match "[[:alpha:]]+-\\(?num:[0-9]+\\)")
num))
=> "123"
Maybe I should install it in pcase.el?
Stefan
(pcase-defmacro re-match (re)
"Matches a string if that string matches RE.
RE should be a regular expression (a string).
It can use the special syntax \\(?VAR: to bind a sub-match
to variable VAR. All other subgroups are treated as shy.
Multiple uses of this macro in a single `pcase' are not optimized
together, so don't expect lex-like performance. But in order for
such optimization to be possible in some distant future, back-references
are not supported."
(let ((start 0)
(last 0)
(new-re '())
(vars '())
(gn 0))
(while (string-match "\\\\(\\(?:\\?\\([-[:alnum:]]*\\):\\)?" re start)
(setq start (match-end 0))
(let ((beg (match-beginning 0))
(name (match-string 1 re)))
;; Skip false positives, either backslash-escaped or within [...].
(when (subregexp-context-p re start last)
(cond
((null name)
(push (concat (substring re last beg) "\\(?:") new-re))
((string-match "\\`[0-9]" name)
(error "Variable can't start with a digit: %S" name))
(t
(let* ((var (intern name))
(id (cdr (assq var vars))))
(unless id
(setq gn (1+ gn))
(setq id gn)
(push (cons var gn) vars))
(push (concat (substring re last beg) (format "\\(?%d:" id))
new-re))))
(setq last start))))
(push (substring re last) new-re)
(setq new-re (mapconcat #'identity (nreverse new-re) ""))
`(and (pred stringp)
(app (lambda (s)
(save-match-data
(when (string-match ,new-re s)
(vector ,@(mapcar (lambda (x) `(match-string ,(cdr x) s))
vars)))))
(,'\` [,@(mapcar (lambda (x) (list '\, (car x))) vars)])))))
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-21 13:34 ` Stefan Monnier
@ 2017-07-21 14:08 ` Tino Calancha
2017-07-21 23:28 ` John Mastro
2017-07-23 20:41 ` Philipp Stephani
2 siblings, 0 replies; 14+ messages in thread
From: Tino Calancha @ 2017-07-21 14:08 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 27659, Michael Heerdegen, Philipp Stephani, Tino Calancha
On Fri, 21 Jul 2017, Stefan Monnier wrote:
>> Although, i must admit i am not fluent in `rx' syntaxis, i find your idea
>> very nice.
>
> If you prefer the standard/cryptic regexp syntax, I posted a similar
> thingy in the past (see below).
>
> This lets you do
>
> (pcase "foo-123"
> ((re-match "[[:alpha:]]+-\\(?num:[0-9]+\\)")
> num))
> => "123"
>
> Maybe I should install it in pcase.el?
This is nice too, and it looks familiar to me. A pity that it doesn't
accept back references, but to be honest weirdly use them.
For me it's useful to have it to study the code and learn how these
things are implemented; but i understand that is not
an encouraged argument.
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-21 13:34 ` Stefan Monnier
2017-07-21 14:08 ` Tino Calancha
@ 2017-07-21 23:28 ` John Mastro
2017-07-22 2:02 ` Michael Heerdegen
2017-07-23 20:41 ` Philipp Stephani
2 siblings, 1 reply; 14+ messages in thread
From: John Mastro @ 2017-07-21 23:28 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 27659, Michael Heerdegen, Philipp Stephani, Tino Calancha
Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> If you prefer the standard/cryptic regexp syntax, I posted a similar
> thingy in the past (see below).
>
> This lets you do
>
> (pcase "foo-123"
> ((re-match "[[:alpha:]]+-\\(?num:[0-9]+\\)")
> num))
> => "123"
>
> Maybe I should install it in pcase.el?
I hope you do - both this and the rx pattern would be nice to have.
John
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-20 19:51 ` Philipp Stephani
2017-07-21 12:29 ` Tino Calancha
@ 2017-07-22 1:46 ` Michael Heerdegen
2017-07-23 20:45 ` Philipp Stephani
1 sibling, 1 reply; 14+ messages in thread
From: Michael Heerdegen @ 2017-07-22 1:46 UTC (permalink / raw)
To: Philipp Stephani; +Cc: 27659, Tino Calancha
Hi Philipp,
nice idea! I have some questions:
+(pcase-defmacro rx (&rest regexps)
+ "Build a `pcase' pattern matching `rx' regexps.
+The REGEXPS are interpreted as by `rx'.
Should we tell what the semantics of multiple REGEXPS is? I guess they
are implicitly wrapped inside rx-`and' (but FWIW, the doc of `rx' also
fails to tell that).
+Within the case code, the match data is bound as usual, but you
This makes it sound like match data is bound pcase-branch-locally.
This isn't the case, right?
+In addition to the usual `rx' constructs, REGEXPS can contain the
+following constructs:
+
+ (let VAR FORM...) creates a new explicitly numbered submatch
+ that matches FORM and binds the match to
+ VAR.
This made me wonder what FORM should be. I think it means any rx
symbolic expression, so the name FORM seems misleading.
+(ert-deftest pcase-tests-rx ()
+ (should (equal (pcase "a 1 2 3 1 b"
+ ((rx (let u (+ digit)) space
+ (let v (+ digit)) space
+ (let v (+ digit)) space
+ (backref-var u))
+ (list u v)))
+ '("1" "3"))))
+
I don't understand the example (or test). Is v first bound to 2, and
after that rebound to 3? This seems at least surprising, since let
behaves differently in pcase, e.g.
(pcase 'foo
((and (let x 1) (let x 2)) x))
==> nil
Hmm, in general I see the risk of confusing this `let' with `pcase' let.
It seems to be something very different. Maybe you could just pick a
different name, `bind' maybe?
Michael.
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-21 23:28 ` John Mastro
@ 2017-07-22 2:02 ` Michael Heerdegen
0 siblings, 0 replies; 14+ messages in thread
From: Michael Heerdegen @ 2017-07-22 2:02 UTC (permalink / raw)
To: John Mastro; +Cc: 27659, Philipp Stephani, Stefan Monnier, Tino Calancha
John Mastro <john.b.mastro@gmail.com> writes:
> I hope you do - both this and the rx pattern would be nice to have.
I think we should make it so that they have corresponding semantics.
Ideally, without variable binding, Phillip's macro should be eqivalent
to calling rx on the pattern args and then calling Stefan's version. On
top of that, both should add variables and back-references in the same
way. It would be very confusing to add the same thing twice with only
very subtle differences (modulo regexp syntax used).
Michael.
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-21 13:34 ` Stefan Monnier
2017-07-21 14:08 ` Tino Calancha
2017-07-21 23:28 ` John Mastro
@ 2017-07-23 20:41 ` Philipp Stephani
2017-07-24 14:30 ` Stefan Monnier
2 siblings, 1 reply; 14+ messages in thread
From: Philipp Stephani @ 2017-07-23 20:41 UTC (permalink / raw)
To: Stefan Monnier, Tino Calancha; +Cc: 27659, Michael Heerdegen
[-- Attachment #1: Type: text/plain, Size: 1329 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Fr., 21. Juli 2017 um
15:34 Uhr:
> >> This looks useful, but I think it would be even better to add it
> >> as a pcase macro to be composable (see attached patch).
>
> Hey, very nice. Please add it to rx.el.
> [ But please change `backref-var` to just `backref` (you can distinguish
> the two based on the type of the argument, I think). I guess one
> could also argue that you could similarly rename the `let` to
> `group-n`. ]
>
Pushed as ad4eff3b905dbc32e2d38bfec1e4f93eceec288d. I've renamed
backref-var to backref as you suggested, but left `let' because I think
that feature is important enough to deserve a short, common name.
>
> > Although, i must admit i am not fluent in `rx' syntaxis, i find your idea
> > very nice.
>
> If you prefer the standard/cryptic regexp syntax, I posted a similar
> thingy in the past (see below).
>
> This lets you do
>
> (pcase "foo-123"
> ((re-match "[[:alpha:]]+-\\(?num:[0-9]+\\)")
> num))
> => "123"
>
> Maybe I should install it in pcase.el?
>
>
>
Sure! I'd suggest to change the syntax to be compatible with other
languages:
\(?<abc>[0-9]+\) or \(?'abc'[0-9+\) (Perl and .NET)
\(?P<abc>[0-9]+\) (Python)
These languages also have syntax for named backreferences, though that's
less important.
[-- Attachment #2: Type: text/html, Size: 2030 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-22 1:46 ` Michael Heerdegen
@ 2017-07-23 20:45 ` Philipp Stephani
2017-07-23 21:39 ` Michael Heerdegen
0 siblings, 1 reply; 14+ messages in thread
From: Philipp Stephani @ 2017-07-23 20:45 UTC (permalink / raw)
To: Michael Heerdegen; +Cc: 27659, Tino Calancha
[-- Attachment #1: Type: text/plain, Size: 2257 bytes --]
Michael Heerdegen <michael_heerdegen@web.de> schrieb am Sa., 22. Juli 2017
um 03:46 Uhr:
> Hi Philipp,
>
> nice idea! I have some questions:
>
>
> +(pcase-defmacro rx (&rest regexps)
> + "Build a `pcase' pattern matching `rx' regexps.
> +The REGEXPS are interpreted as by `rx'.
>
> Should we tell what the semantics of multiple REGEXPS is? I guess they
> are implicitly wrapped inside rx-`and' (but FWIW, the doc of `rx' also
> fails to tell that).
>
yes, probably something should be added to the docstring of `rx'.
>
>
> +Within the case code, the match data is bound as usual, but you
>
> This makes it sound like match data is bound pcase-branch-locally.
> This isn't the case, right?
>
Yes, I've reworded it to sound less like a variable binding.
>
>
> +In addition to the usual `rx' constructs, REGEXPS can contain the
> +following constructs:
> +
> + (let VAR FORM...) creates a new explicitly numbered submatch
> + that matches FORM and binds the match to
> + VAR.
>
> This made me wonder what FORM should be. I think it means any rx
> symbolic expression, so the name FORM seems misleading.
>
I think the words `form' and `sexp' are used mostly interchangeably
nowadays, and the docstring of `rx' speaks of "forms" several times.
>
>
> +(ert-deftest pcase-tests-rx ()
> + (should (equal (pcase "a 1 2 3 1 b"
> + ((rx (let u (+ digit)) space
> + (let v (+ digit)) space
> + (let v (+ digit)) space
> + (backref-var u))
> + (list u v)))
> + '("1" "3"))))
> +
>
> I don't understand the example (or test). Is v first bound to 2, and
> after that rebound to 3? This seems at least surprising, since let
> behaves differently in pcase, e.g.
>
> (pcase 'foo
> ((and (let x 1) (let x 2)) x))
> ==> nil
>
> Hmm, in general I see the risk of confusing this `let' with `pcase' let.
> It seems to be something very different. Maybe you could just pick a
> different name, `bind' maybe?
>
>
>
I'd rather stick with the short and common `let'. That there's a name clash
is unfortunate, but there are lots of similar cases (e.g. pcase `let' vs.
Lisp `let', rx `and' and `or').
[-- Attachment #2: Type: text/html, Size: 3418 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-23 20:45 ` Philipp Stephani
@ 2017-07-23 21:39 ` Michael Heerdegen
0 siblings, 0 replies; 14+ messages in thread
From: Michael Heerdegen @ 2017-07-23 21:39 UTC (permalink / raw)
To: Philipp Stephani; +Cc: 27659, Tino Calancha
Philipp Stephani <p.stephani2@gmail.com> writes:
> I think the words `form' and `sexp' are used mostly interchangeably
> nowadays, and the docstring of `rx' speaks of "forms" several times.
If you read carefully, then you'll see that the word "form" is only used
in descriptive language. The only place where something is named "form"
is the argument of `eval', which actually must be a form.
AFAIC, we use the convention that anything called "a form" is normal
Lisp code to be evaluated, especially if an argument of a macro or
special form is named "FORM". We describe this convention in the
manual.
If you don't follow it, it will confuse others. It confused me; I
didn't understand what your `let' does until I had a look at the tests.
This is just not necessary. Enough people already have problems
understanding and accepting pcase stuff, so I think it's extra important
to use unambiguous language.
And BTW, if we choose to give up that naming convention, shouldn't we
first discuss it?
Michael.
^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#27659: 26.0.50; Add string-matched-text: string-match + match-string
2017-07-23 20:41 ` Philipp Stephani
@ 2017-07-24 14:30 ` Stefan Monnier
0 siblings, 0 replies; 14+ messages in thread
From: Stefan Monnier @ 2017-07-24 14:30 UTC (permalink / raw)
To: Philipp Stephani; +Cc: 27659, Michael Heerdegen, Tino Calancha
> Pushed as ad4eff3b905dbc32e2d38bfec1e4f93eceec288d. I've renamed
> backref-var to backref as you suggested, but left `let' because I think
> that feature is important enough to deserve a short, common name.
Thanks.
> Sure! I'd suggest to change the syntax to be compatible with other
> languages:
>
> \(?<abc>[0-9]+\) or \(?'abc'[0-9+\) (Perl and .NET)
> \(?P<abc>[0-9]+\) (Python)
Fine by me. I'm surprised they didn't use the (?<var>:...) syntax,
since it seemed such an obvious choice, but maybe they wanted to allow :
in <var>.
Feel free to adapt my patch for that. BTW, the main reason why I didn't
push my patch originally is because of its inability to extract the
match-beginning/end of the named subgroup: it felt like
a serious shortcoming.
Stefan
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2017-07-24 14:30 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-12 6:13 bug#27659: 26.0.50; Add string-matched-text: string-match + match-string Tino Calancha
2017-07-20 0:54 ` Drew Adams
2017-07-20 1:19 ` Tino Calancha
2017-07-20 19:51 ` Philipp Stephani
2017-07-21 12:29 ` Tino Calancha
2017-07-21 13:34 ` Stefan Monnier
2017-07-21 14:08 ` Tino Calancha
2017-07-21 23:28 ` John Mastro
2017-07-22 2:02 ` Michael Heerdegen
2017-07-23 20:41 ` Philipp Stephani
2017-07-24 14:30 ` Stefan Monnier
2017-07-22 1:46 ` Michael Heerdegen
2017-07-23 20:45 ` Philipp Stephani
2017-07-23 21:39 ` Michael Heerdegen
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
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).