lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Mike Pall <mikelu-1101 <at> mike.de> writes:
> Josh Haberman wrote:
> > Speaking as someone who has previously asked for a __hasheq
> > metamethod [0], I got over it, and I would hate for this slippery
> > slope worry to lead to semantics where:
> >-
> >   1 == 1LL
> >   t[1] != 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[1], 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].

Makes sense.
 
> 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?

Josh