[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: LuaJIT 64 bit integers (was: the purpose of lightuserdata)
- From: Josh Haberman <jhaberman@...>
- Date: Thu, 13 Jan 2011 17:05:47 +0000 (UTC)
Mike Pall <mikelu-1101 <at> mike.de> writes:
> Josh Haberman wrote:
> > Speaking as someone who has previously asked for a __hasheq
> > metamethod , I got over it, and I would hate for this slippery
> > slope worry to lead to semantics where:
> > 1 == 1LL
> > t != t[1LL]
> > That sounds extremely counter-intuitive.
> Then you'll be even more surprised that t[1LL] != t[1LL], because
> neither cdata not cdata literals are interned.
Yes, I shudder to think of explaining that to users. I was initially
very excited to hear your announcement of 64-bit integer support since
it's been a stumbling block for adoption of Lua inside Google where we
have lots of 64-bit integers floating around, but these semantics seem
so counter-intuitive that I'd hesitate to advocate people use them.
By the time I'm explaining that regular numbers and 64-bit numbers
have different table semantics because one is built-in and one is
cdata I think I will have lost my audience. People who are new and/or
infrequent users of a language have only so much brain space to fill
up with unexpected quirks.
> Then t[1LL] should map to t, so both would need to end up in
> the array part of a table. Ok, so a table traversal would return
> the key as 1 and not 1LL, which may lead to even more confusion.
It shouldn't be confusing if 1LL and 1 behave identically for key
operations like comparison and table indexing.
> And then t[10000000000000000LL] needs to map to t[1e16].
> But t[9999999999999999LL] shouldn't map to t[1e16], even though
> tonumber(9999999999999999LL) == 1e16.
I don't see the problem with this.
9999999999999999LL == 1e16 => false
t[9999999999999999LL] == t[1e16] => false
tonumber(9999999999999999LL) == 1e16 => true
t[tonumber(9999999999999999LL)] == t[1e16] => true
It seems perfectly consistent to me. 9999999999999999LL and
tonumber(9999999999999999LL) are different and do not compare equal,
because tonumber() is a lossy conversion.
> And the final catch is that
> t[-1LL] and t[-1ULL] better both map to t[-1], even though
> tonumber(-1LL) == -1 and tonumber(-1ULL) == ~1.844674407371e+19.
Why would t[-1ULL] map to t[-1]? I certainly wouldn't expect
-1ULL == -1 or -1ULL == -1LL. I think it's still consistent:
-1ULL == -1 => false
t[-1ULL] == t[-1] => false
-1ULL == -1LL => false
t[-1ULL] == t[-1LL] => false
-1ULL == 1.844674407371e19 => true (or whatever the exact constant is)
t[-1ULL] == t[1.844674407371e19] => true
> Ouch! That's a can of worms I *really* don't want to open. This is
> not ever going to work in a sensible way.
I think it's really consistent and logical if you just follow the same
semantics as == (with the exception of the __eq metamethod, as you
noted). If you can make == work sensibly between numbers and int64_t,
why not table indexing?