bug#48318: (ice-9 match) does not allow distinguishing between () and #nil

Maxime Devos <[email protected]>
Newsgroups gmane.lisp.guile.bugs
Message-ID <[email protected]>
Taylan Kammer schreef op do 13-05-2021 om 21:14 [+0200]:
> Hi Maxime,
> 
> I believe that match conflating () and #nil is the right thing,
> even if the current implementation does it unintentionally.
> 
> Those two values should be considered "the same" in most situations
> even though (eqv? #nil '()) is false.

Conflating #nil and () is reasonable for my use case,
though this conflation should be documented.

> In fact I think they should be equal? to each other.  It feels
> wrong that (equal? '(foo . #nil) '(foo . ())) evaluates to false,
> even though both arguments represent the list '(foo).

The guile manual has some information on this.
(6.24.2.1 Nil, under 6.24.2 Emacs Lisp).

> Please note that #nil is not ever supposed to be used intentionally.
I know, but ...
> It's there purely as an Elisp compatibility trick, and the only time
> Scheme could should receive it is when receiving data generated by
> Elisp code.  For instance when Elisp code generates a list, it would
> be terminated by #nil.  (Which is why I think it should equal? '().)

I have been porting some common lisp code to Guile Scheme. I replaced
'() with #nil, which allows me to largely ignore whether Lisp nil is used
as end-of-list or as boolean for now (I'm in the process of replacing it
with '() or #f where appropriate).

Being able to directly refer to #nil, to perform equality checks like
(eq? #f #nil) --> #f, (eq? '() #nil) --> #f, ... can be useful for writing
Scheme code that could be called from both elisp and Scheme when the
compatibility isn't transparent.  For example, suppose (ice-9 match) actually
did not conflate #nil and () (which is what I initially thought; I expected
(ice-9 match) to compare atoms with eqv?), then the
following code ...

;; Somewhat contrived (untested), but based on some real code
(define 
  (match-lambda
    ((_ . stuff) stuff)
    (() 0)))

... would need to be rewritten to something like ...

;; Somewhat contrived (untested), but based on some real code
(define 
  (match-lambda
    ((_ . stuff) stuff)
    (() 0)
    (#nil 0)))

Also, consider the 'case' syntax.

Greetings,
Maxime.
signature.asc (application/pgp-signature, 260 B)
-----BEGIN PGP SIGNATURE-----

iI0EABYKADUWIQTB8z7iDFKP233XAR9J4+4iGRcl7gUCYJ2OkxccbWF4aW1lZGV2
b3NAdGVsZW5ldC5iZQAKCRBJ4+4iGRcl7n9CAP9lTwPh87IbXbJo1IUdfB01PtTF
X1ZM4OaJRr4Fol27KwEA3FsAk/qEirTQtCvOvJRG4YbQpu0Y5gDNO0IpybEt1g8=
=c75C
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.