From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Taylan Kammer Newsgroups: gmane.lisp.guile.bugs Subject: bug#48318: (ice-9 match) does not allow distinguishing between () and #nil Date: Thu, 13 May 2021 23:21:48 +0200 Message-ID: <6c3a61c2-0449-9f7c-a978-b034803bcebd@gmail.com> References: <26e0536a8f0c16f53002b045cb7e9a30a1e8a09e.camel@telenet.be> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="1107"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.10.1 To: Maxime Devos , 48318@debbugs.gnu.org Original-X-From: bug-guile-bounces+guile-bugs=m.gmane-mx.org@gnu.org Thu May 13 23:22:12 2021 Return-path: Envelope-to: guile-bugs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lhImZ-000050-K6 for guile-bugs@m.gmane-mx.org; Thu, 13 May 2021 23:22:11 +0200 Original-Received: from localhost ([::1]:47862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lhImY-0008Gi-LR for guile-bugs@m.gmane-mx.org; Thu, 13 May 2021 17:22:10 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:40504) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lhImQ-0008GP-SO for bug-guile@gnu.org; Thu, 13 May 2021 17:22:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:32916) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lhImQ-0006Ud-L9 for bug-guile@gnu.org; Thu, 13 May 2021 17:22:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lhImQ-0000V8-HG for bug-guile@gnu.org; Thu, 13 May 2021 17:22:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Taylan Kammer Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Thu, 13 May 2021 21:22:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48318 X-GNU-PR-Package: guile Original-Received: via spool by 48318-submit@debbugs.gnu.org id=B48318.16209409181915 (code B ref 48318); Thu, 13 May 2021 21:22:02 +0000 Original-Received: (at 48318) by debbugs.gnu.org; 13 May 2021 21:21:58 +0000 Original-Received: from localhost ([127.0.0.1]:44462 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lhImL-0000Uo-Kl for submit@debbugs.gnu.org; Thu, 13 May 2021 17:21:57 -0400 Original-Received: from mail-ej1-f50.google.com ([209.85.218.50]:47030) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lhImK-0000UY-5s for 48318@debbugs.gnu.org; Thu, 13 May 2021 17:21:56 -0400 Original-Received: by mail-ej1-f50.google.com with SMTP id u21so41759180ejo.13 for <48318@debbugs.gnu.org>; Thu, 13 May 2021 14:21:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=KBuOUfMqxQuvKOexsu4bzuWkmqr65+RRWiBgNCMpc9s=; b=Ro7S8zhXawdxvVFj/gGMLMR0y1iqso1qq/7fu08JYgcqB6ccAK5hPvQKR/AEwqpxnB 8YdQTbPPldrzumEtAxPEZYZ0dFpLwSY8Xf90ewee4tslHq9K/abMlYv1hOLv4F0gtNWh BpEkdf7RW+0WNsMFfHt6/qFRWA2sue1MS1Gy5b4c054OH3Nl5VFyekbVvKD1HG+fUiQa p/ihev38ODabpl1jJNS/NK8zEf0SXSFatFx62ouCBAnz3I0lb5Q+LPqxukrM8V10AVkI SqLd1EjywU4CnlVWx/JzAjThTvh99JLLhPOcJrKr6mBdep6TM/hqaL+NtHMKHHBnW3Ne SGVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=KBuOUfMqxQuvKOexsu4bzuWkmqr65+RRWiBgNCMpc9s=; b=HqJURys1B4gNR/KTsKrj7EP18+8we0XUblo6Xchat0972EUWGiM0W1yIxPvSJsvHba Fokw5/l+ziYStzE7lXDFcxPQ26eok+WJBrOf1YXRC44M3dKJgwX4b1N9C/csHfrEQsh5 gIY1tLRfHMVrA6vQxWnTaPvk30rc+vx1Z/VqoJbjUG6B5ZCt5JAqG2GX+ZKqSgROnCGX y+Z4OvA73/6fLVMvyh5N4RkfjrCx7UJZHkdj58TMCpGgOVPdkMBvY6dnVWVw15fWdbYD BpSocxWgZqn/pJhNaX9NfHA4UbFTPmJm/oYi44DPRlmEvbF4jZat/gSPc7Dr/GqJbwoT bpFA== X-Gm-Message-State: AOAM531D8YbeJXD/qYm57qGoB3l2X1Nz32lZ1gWhVE/SwY71jLslDjLn v6Q8vlaxjuk3dlLOoQwSM9h9R9um58NbKg== X-Google-Smtp-Source: ABdhPJxcU8zw51C579rM9M/q9mduM+6ECo0jwIe3J4rr/5gOP+UVAqrP88YP9t8VtnyyImfHhkwKFw== X-Received: by 2002:a17:907:f91:: with SMTP id kb17mr44809970ejc.521.1620940910071; Thu, 13 May 2021 14:21:50 -0700 (PDT) Original-Received: from [192.168.178.20] (b2b-109-90-125-150.unitymedia.biz. [109.90.125.150]) by smtp.gmail.com with ESMTPSA id ga28sm2428446ejc.20.2021.05.13.14.21.49 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 13 May 2021 14:21:49 -0700 (PDT) In-Reply-To: <26e0536a8f0c16f53002b045cb7e9a30a1e8a09e.camel@telenet.be> Content-Language: en-US X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane-mx.org@gnu.org Original-Sender: "bug-guile" Xref: news.gmane.io gmane.lisp.guile.bugs:10054 Archived-At: On 13.05.2021 22:39, Maxime Devos wrote: > 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. Agree, it should definitely 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). Good catch. I see it mentions that equal? is expected to be transitive, so if (equal? #nil '()) and (equal? #nil #f) were both true, (equal? '() #f) would have to be too, which would be wrong for a Scheme implementation. We could however make it equal? to just one of the two without making equal? non-transitive. And if we're going to do that, I think the empty list would be the better choice, because of the role it plays in the structure of lists. Without any data to verify this, I'd say that situations where #nil surprises programmers by not being equal? to '() are likely to come up much more often than cases where it surprises programmers by not being equal? to #f. The parallel between equal?-ness and external representation also comes to mind. I think it's not a concrete rule, but there's the general expectation that two objects are equal? if their external representation is the same, which is the case for (foo . #nil) and (foo . ()), which would both be canonically represented as (foo). We could also go in the other direction and make Scheme's write procedure output (foo . #nil) as (foo . #nil), but I think that would be less desirable. >> 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). Exciting! I guess that's one feasible extra use-case for #nil, but as you noted it yourself, it's probably best to rewrite the code to eliminate all the assumptions that the end-of-list object is false as a Boolean. > 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))) Indeed. > Also, consider the 'case' syntax. Case is defined in terms of eqv? in the standards so I guess it should differentiate between #nil and (). Unlike match, which does pattern matching on lists. > Greetings, > Maxime. > - Taylan