GNU bug report logs - #66057
(ice-9 match) allows invalid usages of ... or ..1

Previous Next

Package: guile;

Reported by: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>

Date: Sun, 17 Sep 2023 18:18:01 UTC

Severity: normal

To reply to this bug, email your comments to 66057 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#66057; Package guile. (Sun, 17 Sep 2023 18:18:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Maxim Cournoyer <maxim.cournoyer <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Sun, 17 Sep 2023 18:18:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
To: bug-guile <bug-guile <at> gnu.org>
Subject: (ice-9 match) allows invalid usages of ... or ..1
Date: Sun, 17 Sep 2023 14:17:21 -0400
Hi,

After attempting the following:

--8<---------------cut here---------------start------------->8---
(match (string-split "./Bootloaders/Printer/Documentation/html" #\/)
                                 (("." path ..1 "Documentation" "html")
                                  (pk 'path path)))

=> ;;; (path "Bootloaders")

Expected (and works with '...'): 
;;; (path "Bootloaders" "Printer")
--8<---------------cut here---------------end--------------->8---

and asking about it in #scheme or #guile, it seems the '..1' and '...'
patterns *must* be used strictly to match at the end of lists, but this
isn't explicitly mentioned in the manual, and even works for ... but not
for ..1, which is inconsistent/econfusing.

It was suggested by Zipheir in #scheme that Guile should return a syntax
error when ..1 or ... are used somewhere else than at the end of a list.
It seems a good suggestion.

-- 
Thanks,
Maxim




Information forwarded to bug-guile <at> gnu.org:
bug#66057; Package guile. (Sun, 17 Sep 2023 18:38:02 GMT) Full text and rfc822 format available.

Message #8 received at 66057 <at> debbugs.gnu.org (full text, mbox):

From: Jean Abou Samra <jean <at> abou-samra.fr>
To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, 66057 <at> debbugs.gnu.org
Subject: Re: bug#66057: (ice-9 match) allows invalid usages of ... or ..1
Date: Sun, 17 Sep 2023 20:36:45 +0200
[Message part 1 (text/plain, inline)]
Le dimanche 17 septembre 2023 à 14:17 -0400, Maxim Cournoyer a écrit :
> Hi,
> 
> After attempting the following:
> 
> --8<---------------cut here---------------start------------->8---
> (match (string-split "./Bootloaders/Printer/Documentation/html" #\/)
>                                  (("." path ..1 "Documentation" "html")


For a start, where does that "..1" syntax come from? To my knowledge, no such
syntax is supported by Guile's pattern matcher, which AFAIK is the one described
in SRFI-204.

https://srfi.schemers.org/srfi-204/srfi-204.html


So your example is just binding the string "Printer" to the variable "..1":
since "..1" doesn't have any special meaning, it's just a pattern variable.


>                                   (pk 'path path)))
> 
> => ;;; (path "Bootloaders")
> 
> Expected (and works with '...'): 
> ;;; (path "Bootloaders" "Printer")
> --8<---------------cut here---------------end--------------->8---
> 
> and asking about it in #scheme or #guile, it seems the '..1' and '...'
> patterns *must* be used strictly to match at the end of lists,


??

This is not what SRFI 204 says, and it's not consistent with syntax-rules and
syntax-case patterns either.
[Message part 2 (text/html, inline)]
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-guile <at> gnu.org:
bug#66057; Package guile. (Mon, 18 Sep 2023 01:00:02 GMT) Full text and rfc822 format available.

Message #11 received at 66057 <at> debbugs.gnu.org (full text, mbox):

From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
To: Jean Abou Samra <jean <at> abou-samra.fr>
Cc: 66057 <at> debbugs.gnu.org
Subject: Re: bug#66057: (ice-9 match) allows invalid usages of ... or ..1
Date: Sun, 17 Sep 2023 20:59:23 -0400
Hello,

Jean Abou Samra <jean <at> abou-samra.fr> writes:

> Le dimanche 17 septembre 2023 à 14:17 -0400, Maxim Cournoyer a écrit :
>> Hi,
>> 
>> After attempting the following:
>> 
>> --8<---------------cut here---------------start------------->8---
>> (match (string-split "./Bootloaders/Printer/Documentation/html" #\/)
>>                                  (("." path ..1 "Documentation" "html")
>
>
> For a start, where does that "..1" syntax come from? To my knowledge, no such
> syntax is supported by Guile's pattern matcher, which AFAIK is the one described
> in SRFI-204.
>
> https://srfi.schemers.org/srfi-204/srfi-204.html

It's mentioned in the Guile Reference manual; see info "(guile) Pattern
Matching":

--8<---------------cut here---------------start------------->8---
 -- Scheme Syntax: match exp clause1 clause2 ...
     Match object EXP against the patterns in CLAUSE1 CLAUSE2 ... in the
     order in which they appear.  Return the value produced by the first
     matching clause.  If no clause matches, throw an exception with key
     ‘match-error’.

     Each clause has the form ‘(pattern body1 body2 ...)’.  Each PATTERN
     must follow the syntax described below.  Each body is an arbitrary
     Scheme expression, possibly referring to pattern variables of
     PATTERN.

   The syntax and interpretation of patterns is as follows:

        patterns:                       matches:

pat ::= identifier                      anything, and binds identifier
      | _                               anything
      | ()                              the empty list
      | #t                              #t
      | #f                              #f
      | string                          a string
      | number                          a number
      | character                       a character
      | 'sexp                           an s-expression
      | 'symbol                         a symbol (special case of s-expr)
      | (pat_1 ... pat_n)               list of n elements
      | (pat_1 ... pat_n . pat_{n+1})   list of n or more
      | (pat_1 ... pat_n pat_n+1 ooo)   list of n or more, each element
                                          of remainder must match pat_n+1
      | #(pat_1 ... pat_n)              vector of n elements
      | #(pat_1 ... pat_n pat_n+1 ooo)  vector of n or more, each element
                                          of remainder must match pat_n+1
      | #&pat                           box
      | ($ record-name pat_1 ... pat_n) a record
      | (= field pat)                   a ``field'' of an object
      | (and pat_1 ... pat_n)           if all of pat_1 thru pat_n match
      | (or pat_1 ... pat_n)            if any of pat_1 thru pat_n match
      | (not pat_1 ... pat_n)           if all pat_1 thru pat_n don't match
      | (? predicate pat_1 ... pat_n)   if predicate true and all of
                                          pat_1 thru pat_n match
      | (set! identifier)               anything, and binds setter
      | (get! identifier)               anything, and binds getter
      | `qp                             a quasi-pattern
      | (identifier *** pat)            matches pat in a tree and binds
                                        identifier to the path leading
                                        to the object that matches pat

ooo ::= ...                             zero or more
      | ___                             zero or more
      | ..1                             1 or more

        quasi-patterns:                 matches:

qp  ::= ()                              the empty list
      | #t                              #t
      | #f                              #f
      | string                          a string
      | number                          a number
      | character                       a character
      | identifier                      a symbol
      | (qp_1 ... qp_n)                 list of n elements
      | (qp_1 ... qp_n . qp_{n+1})      list of n or more
      | (qp_1 ... qp_n qp_n+1 ooo)      list of n or more, each element
                                          of remainder must match qp_n+1
      | #(qp_1 ... qp_n)                vector of n elements
      | #(qp_1 ... qp_n qp_n+1 ooo)     vector of n or more, each element
                                          of remainder must match qp_n+1
      | #&qp                            box
      | ,pat                            a pattern
      | ,@pat                           a pattern

   The names ‘quote’, ‘quasiquote’, ‘unquote’, ‘unquote-splicing’, ‘?’,
‘_’, ‘$’, ‘and’, ‘or’, ‘not’, ‘set!’, ‘get!’, ‘...’, and ‘___’ cannot be
used as pattern variables.
--8<---------------cut here---------------end--------------->8---

>
> So your example is just binding the string "Printer" to the variable "..1":
> since "..1" doesn't have any special meaning, it's just a pattern variable.

Unless I misread the doc, it should '..1' is a special case '...', which
means "one or more" instead of "zero or more".

>
>>                                   (pk 'path path)))
>> 
>> => ;;; (path "Bootloaders")
>> 
>> Expected (and works with '...'): 
>> ;;; (path "Bootloaders" "Printer")
>> --8<---------------cut here---------------end--------------->8---
>> 
>> and asking about it in #scheme or #guile, it seems the '..1' and '...'
>> patterns *must* be used strictly to match at the end of lists,
>
>
> ??
>
> This is not what SRFI 204 says, and it's not consistent with syntax-rules and
> syntax-case patterns either.

OK!  I hope it's just a bug in Guile that can be addressed then.

Thanks for tipping in.

-- 
Maxim




Information forwarded to bug-guile <at> gnu.org:
bug#66057; Package guile. (Mon, 18 Sep 2023 09:29:02 GMT) Full text and rfc822 format available.

Message #14 received at 66057 <at> debbugs.gnu.org (full text, mbox):

From: Jean Abou Samra <jean <at> abou-samra.fr>
To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
Cc: 66057 <at> debbugs.gnu.org
Subject: Re: bug#66057: (ice-9 match) allows invalid usages of ... or ..1
Date: Mon, 18 Sep 2023 11:28:31 +0200
[Message part 1 (text/plain, inline)]
Le dimanche 17 septembre 2023 à 20:59 -0400, Maxim Cournoyer a écrit :
> It's mentioned in the Guile Reference manual; see info "(guile) Pattern
> Matching":
> > 
> > So your example is just binding the string "Printer" to the variable "..1":
> > since "..1" doesn't have any special meaning, it's just a pattern variable.
> 
> Unless I misread the doc, it should '..1' is a special case '...', which
> means "one or more" instead of "zero or more".


OK, my bad, I didn't know that. You're right that "..1" is mistreated here, it
should be compiled as "one or more repetitions" but instead gets compiled as a
pattern variable. That's a bug, indeed — I believe the expected behavior is that
"..1" behaves like "...", namely being allowed in the middle of a list.
[Message part 2 (text/html, inline)]
[signature.asc (application/pgp-signature, inline)]

This bug report was last modified 1 year and 67 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.