unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Leo Prikler <leo.prikler@student.tugraz.at>
To: Taylan Kammer <taylan.kammer@gmail.com>, 48425@debbugs.gnu.org
Subject: bug#48425: Should #nil be equal? to '()?
Date: Thu, 24 Jun 2021 20:31:12 +0200	[thread overview]
Message-ID: <75c724023a126850b3b21a296fb658330038e670.camel@student.tugraz.at> (raw)
In-Reply-To: <aa23e415-6395-e0a8-6a51-77b249a0a8d0@gmail.com>

Hi Taylan,

after a lengthy discussion in IRC, you invited me to reply to this bug
report, so that's what I'm doing.  I will make short references to that
discussion, but I won't rehash all of it.  Anyone who is interested in
reading it in all detail, should inspect the public logs:
  http://logs.guix.gnu.org/guile/2021-06-24.log#170309

Am Freitag, den 14.05.2021, 21:36 +0200 schrieb Taylan Kammer:
> I believe it would be better if #nil were equal? to ().
> 
> It would keep *not* being equal? to #f and as such not disturb the
> property of transitiveness.
I don't think there's a good reason to prefer one of this equal?ity
over the other – it all comes down to personal preference if at all.

> Making #nil and () be equal? would be a lot more intuitive since
> they both represent the empty list, and since equal? is commonly
> used to test the equality of lists.  Meeting this expectation would
> probably prevent a common type of unexpected behavior where a list
> coming from Elisp code is not equal? to a list coming from Scheme
> code, even though they have the same contents.
I don't think, that this is a good reason to make them equal?  We've
had our lengthy discussion on the philosophy of equality, which I'm
going to cut short here, as that's not the point you're making, but for
the protocol's sake, #nil and '() are not philosophically equal?

Regarding intuitiveness, I think this actually does more harm than
good.  I could argue that #nil be equal? to #f on the grounds of
intuitiveness, but more importantly

(if (equal? a b) (equal? (if a #t #f) (if b #t #f)))

should only ever return #t or *unspecified*, never #f (insert '() and
#nil as a and b).

Finally on the point of making equal?ity work that way for the sake of
interoperability with other Lisp dialects such as Emacs Lisp or
Clojure, this assumes that this style of comparison through equal? is
"good Scheme", when I'd argue, that it is in fact not.  Pattern
matching and dedicated comparison operators are much saner alternatives
most of the time.

There are multiple ways of getting around the issue of #nil, '() and #f
not being equal? to each other.  The first would be to define an equal-
modulo-nil? procedure, which returns #t if both arguments are nil? 
Another, that would implement your style, would be the following:

--8<---------------cut here---------------start------------->8---
;; Don't forget to test this when actually using it
(define my-equal?
  (match-lambda*
    ((() ()) #t) ;; match '() against #nil
    (((a . as) (b . bs))
     (and (my-equal? a b) ;; recurse into the first sub-element 
          (list= my-equal? as bs))) ;; recurse into the others
    ((a b) (equal? a b)))) ;; fall back to base equal?
--8<---------------cut here---------------end--------------->8---

Of course, you can also take the equal? you wrote for this patch and
include it in your own library, but be sure to document it so as to not
confuse the readers of your code :)

Note, that any such implementations will come with certain limitations,
but I suppose that's what you'd want out of them.

> Attached is a patch to realize the change.  Note that it increases
> the size of compiled code that uses equal?.  I don't know if this
> represents a problem or not.
I personally don't think bytecode optimizations are something to
consider if one can achieve correctness on the other hand, but this
solution has the downside of being both wrong (philosophically, as
discussed above and in IRC) and heavier to compute.  That's not
something a standard library should aim for :P

Regards,
Leo






      reply	other threads:[~2021-06-24 18:31 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-14 19:36 bug#48425: Should #nil be equal? to '()? Taylan Kammer
2021-06-24 18:31 ` Leo Prikler [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=75c724023a126850b3b21a296fb658330038e670.camel@student.tugraz.at \
    --to=leo.prikler@student.tugraz.at \
    --cc=48425@debbugs.gnu.org \
    --cc=taylan.kammer@gmail.com \
    /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).