[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode
From: |
Mattias Engdegård |
Subject: |
bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode |
Date: |
Sat, 28 Dec 2019 19:50:14 +0100 |
28 dec. 2019 kl. 17.36 skrev Pip Cet <pipcet@gmail.com>:
> It was part of the rather extensive eq-vs-eql debate, I'm afraid.
Thank you, I think I have heard most of the possible arguments in one form or
the other over the years...
> I'll try to be clear about this: I think anything but making eq and
> eql synonymous is likely to cause problems that drive programmers away
> from Elisp.
Actually, I can think of a bunch of more pressing issues, both in terms of the
language, its implementation, and the framework.
> But there are axioms that programmers can rely on that are
> stronger than what eq actually promises. For example, two objects
> might be thought either to be eq to each other or not, but code such
> as this:
>
> (defun my-not-eq (x y) (not (eq x y)))
>
> (defun always-t ()
> (or (eq 18446744073709551616 18446744073709551616)
> (my-not-eq 18446744073709551616 18446744073709551616)))
>
> (byte-compile 'always-t)
> (always-t)
>
> will yield unexpected results.
Elisp has a few 'boundedly undefined' parts which would be avoided in a
greenfield design but that we are more or less stuck with for the time being,
and probably should paint in large letters on the first page of the manual.
Such as: don't use eq for numbers; don't mutate literals (strings, conses,
vectors); etc.
>> I'm not sure I understand. Surely such a criterion imposes a rather low
>> limit on permissible optimisations?
>
> Yes, it does. I think any change in the behavior of eq, except for
> making it equal to eql, is likely to break code that's out there
> somewhere (and that doesn't mean we hear about it; more likely, people
> end up abandoning Elisp and using JavaScript instead). So the second
> best option is to keep the current (pre-patch) behavior in which (eq
> 1.0 1.0) is reliably nil, IMHO.
(Javascript's notion of equality, I'm told, is not quite a model of elegance
and simplicity, but perhaps that was your point.)
In my experience people seem to have little trouble understanding that eq
shouldn't be used to compare numbers. If anything, the introduction of bignums
helps driving the point home: up to and including Emacs 26, elisp programmers
could get away with eq for integers but not floating-point numbers. Now, the
rules are simpler. (Characters still get a free pass, I suppose.)
While we could document a safe range of fixnums for which eq applies, it's
probably better not to.
I definitely don't think it's worth propping up broken code that somehow relies
on the non-identity of float literals (bignums isn't a worry yet). Such code is
not only wrong, it's fragile: fragile in the face of changes to elisp, and of
innocent-looking changes to the code itself, such as introducing variables for
values.
This doesn't mean that I would necessary be opposed to making eq a synonym for
eql; just that it would be a rather more momentous decision that I won't bore
anyone by discussing here (although I'd be happy to talk about it over a drink
if we meet one day). Has any state-of-the-art Scheme or Lisp implementation
ever taken that step?
> Technically, I think code such as
>
> (cond ((eq a b) 1) ((not (eq a b)) 2) (t 3))
>
> is allowed to return 3. We should attempt not to make changes that
> make this more likely, though.
Given the state of elisp byte-code optimisation, there is plenty of room for
improvements before such semantics become unavoidable. In particular, the
committed change does not in any way enable such paradoxical behaviour.
> (Again, is this really what we want? If you can't modify an eq-based
> hash table reliably, because keys might have become eq (and thus
> overwrite each other) that weren't eq when you checked the hash table,
> what can you use such hash tables for?)
Are you arguing that this would be a consequence of the constant deduplication?
When eq-based hash tables are not for use with numeric keys anyway?
> You're right, that is eq's contract. But people do misuse it, and one
> of the things they wouldn't expect is that optimization results in
> things becoming non-eq that were eq before optimization; I think the
> other direction is much less problematic.
Good thing that the change works in that other direction then!
>> What would anyone gain from such a restriction? And the change is minor
>> because it's a small thing to do; what I thought looked like an obvious
>> oversight, or one that made more sense back when Elisp didn't have bignums.
>
> Well, Elisp has had floats for a while, and bignum constants appear to
> be nonexistent, so far.
In other words, there is no broken bignum code that can break.
Obviously it's a small change, and one that I'm prepared to revert if required.
But I would like to understand the reason and principles behind it. I want
elisp to be faster; we have promised exactly nobody that each numeric literal
has its own identity, nor is that a reasonable assumption by a programmer to
make.
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Mattias Engdegård, 2019/12/22
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Mattias Engdegård, 2019/12/27
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Pip Cet, 2019/12/27
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Mattias Engdegård, 2019/12/28
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Pip Cet, 2019/12/28
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode,
Mattias Engdegård <=
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Eli Zaretskii, 2019/12/28
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Pip Cet, 2019/12/29
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Mattias Engdegård, 2019/12/29
- bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode, Eli Zaretskii, 2019/12/30