unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: "Linus Björnstam" <linus.internet@fastmail.se>
To: "John Cowan" <cowan@ccil.org>,
	"Zelphir Kaltstahl" <zelphirkaltstahl@posteo.de>
Cc: guile-user <guile-user@gnu.org>
Subject: Re: Surprising behavior of eq?
Date: Sun, 20 Sep 2020 22:51:35 +0200	[thread overview]
Message-ID: <40d06884-73d4-4992-81ce-962bf59ac196@www.fastmail.com> (raw)
In-Reply-To: <CAD2gp_RexKgf-P0n7r2oxebbnrHvqsqCxOMfqibJ0t--y+32GQ@mail.gmail.com>

Just a quick note on guile: if you are testing equality against literals guile will optimize to the fastest kind. (equal? b 27) becomes (eq? b 27). This was added by Andy sometime since 3.0, after Aleix discovered that match was slower than cond-with-eqv? for chars, and that the difference was huge. I wrote an awful patch, which made Andy barf so he fixed it properly (no. He was very polite. If he barfed, he didn't mention it).

A simple optimization that shaved something like 15% of time spent in json->scm in guile-json on one of the files we used for benchmarking. It was converted to cond for the benefit of 2.2, though, but it is still a nice thing to be able to rely on when writing macros.

-- 
  Linus Björnstam

On Sun, 20 Sep 2020, at 19:05, John Cowan wrote:
> On Sun, Sep 20, 2020 at 11:37 AM Zelphir Kaltstahl <
> zelphirkaltstahl@posteo.de> wrote:
> 
> > "This is where the eqv? predicate comes into picture. The eqv? is exactly
> > the same as the eq? predicate, except that it will always return #t for
> > same primitive values."
> >
> > Of course SO is not a standard. Either it is simply wrong, or I
> > misunderstood "primitive values" in that phrase. I thought: "Ah strings are
> > a primitive value, so eqv? should work in all cases when comparing
> > strings." However, this has been debunked.
> >
> Strings tend to be treated as primitive values, but technically they are
> compound values, just as much as vectors are.  And like vectors, you can
> change the characters of a string without changing its identity.
> 
> > The only thing I do not quite understand yet is: What is the difference
> > between (eqv? ...) and (eq? ...) then?
> >
> Efficiency only.
> 
> > If (eqv? ...) is only #t if things get consolidated in the same store
> > place, would that not be the same as pointer equivalence?
> >
> Eq? is allowed to return #f on identical-looking characters and numbers
> because they may or may not involve allocation.  Characters and fixnums
> (integers up to about 2^60) are generally not allocated and eq? will return
> #t on them, but larger integers and other types almost certainly will not:
> 
> (let ((i (* 48923498234892340 78902372789023)) (j (* 48923498234892340
> 78902372789023))) (eq? i j)) => #f
> 
> That's because the values of both i and j have to be allocated, and
> therefore aren't represented by the same pointers.  But unlike strings, you
> can't mutate the digits of an integer, so providing eqv? gives us an
> abstract notion of identity.  The Scheme standards simplify the situation
> by saying that eq? may return #f even when eqv? returns #t in the cases of
> numbers and characters.
> 
> Because of these strange effects, I recommend (and this is just me) not
> using eq? unless you can prove that you need the additional effi.
> 
> Note that (eq? 5 5.0) and (eqv? 5 5.0) are both #f, so if you want to
> compare for numeric equality you should use (= 5 5.0) => #t.  The reason
> they are not identical is that they behave differently:  (/ 5.0 2) => 2.5,
> whereas (/ 5 2) => 5/2.
> 
> Here's an example that shows us that Guile does not consolidate number
> literals, although it could:
> 
> (eqv? 3860180095872584138419938783820 3860180095872584138419938783820) =>#f
> 
> (In R7RS, procedures that are eqv? aren't necessarily eq? either, and in
> R6RS even procedures that seem totally identical may be neither eq? nor
> eqv?.  That's another story.)
>



  reply	other threads:[~2020-09-20 20:51 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-20 12:16 Surprising behavior of eq? Zelphir Kaltstahl
2020-09-20 12:19 ` Zelphir Kaltstahl
2020-09-20 12:58   ` Christopher Lemmer Webber
2020-09-20 13:09   ` Zelphir Kaltstahl
2020-09-20 13:52     ` John Cowan
2020-09-20 15:37       ` Zelphir Kaltstahl
2020-09-20 16:18         ` tomas
2020-09-20 17:05         ` John Cowan
2020-09-20 20:51           ` Linus Björnstam [this message]
2020-09-20 21:42             ` John Cowan
2020-09-20 13:57     ` Stefan Schmiedl
2020-09-20 15:42       ` Zelphir Kaltstahl
2020-09-20 17:26 ` Taylan Kammer

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=40d06884-73d4-4992-81ce-962bf59ac196@www.fastmail.com \
    --to=linus.internet@fastmail.se \
    --cc=cowan@ccil.org \
    --cc=guile-user@gnu.org \
    --cc=zelphirkaltstahl@posteo.de \
    /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).