<Papierkorb>
That has no object id, doesn't make much sense, as it's not an object zatherz
<Papierkorb>
Same goes for structs. They're `Value`s, and are not allocated on the heap
unshadow has quit [Quit: leaving]
<Papierkorb>
zatherz, you can use #hash most of the time, but if you have two instances of a struct A, and both have the same values, they're equal by definition
<FromGitter>
<zatherz> Is there any other way to reliably compare objects, even when `==` is overriden?
<Yxhuvud>
Yes, but the solution to this is not redefining hash for value types, it is redefining Hash so that it doesn't depend on ==.
<Yxhuvud>
By the way, this is not limited to hashes. For example, Array#delete Float64::NAN would also fail to delete the element as it also use ==.
<Papierkorb>
But if you use a Value as key, I expect that `hsh[Val.new] == hsh[Val.new]`
<Papierkorb>
Anything else would be really weird
<Yxhuvud>
papierkorb: Float::NAN != Float::NAN. And yeah, IEEE floating point numbers are really weird.
triangles has quit [Quit: Leaving]
<Papierkorb>
Yxhuvud: Right, I just wanted to point out that replacing a corner-case with a even bigger corner-case isn't that great
<Yxhuvud>
I wonder if anything can be done without resorting to hacks using is_a?(Float) though :/
<FromGitter>
<zatherz> I wasn't going to redefine `hash`
<FromGitter>
<zatherz> where did you get that from
<Yxhuvud>
well, what alternative do you have?
<FromGitter>
<zatherz> Ruby uses PTR_EQUAL which compares the pointers
<Papierkorb>
That would break all Values
<FromGitter>
<zatherz> of course
<Yxhuvud>
Hmm, how do PTR_EQUAL work for immediate values? That is, values that are stored in the reference itself (ints, floats are examples of this). would that end up being a raw comparison of the bits in it?
<Yxhuvud>
{Float::NAN => 1, -Float::NAN => 2}.values_at(Float::NAN, -Float::NAN) => [1, nil]. Hm, wonder if I should put a ticket on that on the ruby tracker, because it is pretty weird.
Kug3lis has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<FromGitter>
<firejox> How about define Float::NAN === Float::NAN is true? To use case equality for Values would also make sense.
<BlaXpirit>
firejox, you know, for case equality it would make sense, but for comparison certainly not
<Papierkorb>
Would actually be kinda interesting to be able to write hsh.delete(String)
<FromGitter>
<MaxLap> That would mean that delete always iterate on every keys to work, instead of using hashes to jump to the value right away
<FromGitter>
<firejox> @BlaXpirit Yeah, but for hash operation that's enough. There is no order required in hash.
unshadow has joined #crystal-lang
<FromGitter>
<firejox> Well, if all NaN with same hash id and compare with case equality, there is no need to iterate every keys.
<unshadow>
jhass: you here ?
<FromGitter>
<MaxLap> I was referring to the hsh.delete(String) idea, which would need to iterate all keys each time. Making it quite a different operation that what is expected from delete.
<Yxhuvud>
putting all strings in the same hash key may be the worst idea I've heard today.
<FromGitter>
<MaxLap> Are there other operators for "equality" in Crystal than == and === ? Ruby has equal? (for identity) and eql? (for hashes, quite the unexplicit name).
<FromGitter>
<MaxLap> And looking at the code right now... 1 and 1.0 will give you 2 different keys
unshadow has quit [Ping timeout: 255 seconds]
<FromGitter>
<MaxLap> but should there be a hash collision putting those 2 values in the same bucket, you would get the first value of the bucket
<FromGitter>
<MaxLap> At least it's how i understand it, because it uses == for the comparison of the keys, and doesn't check that the hashes are actually identical
unshadow has joined #crystal-lang
<FromGitter>
<Sija> @MaxLap `Reference#same?`?
<FromGitter>
<MaxLap> That's basically ruby's equal?, but only supporting references i guess.
soveran has joined #crystal-lang
soveran has joined #crystal-lang
soveran has quit [Changing host]
<FromGitter>
<MaxLap> holycrap floats are not.. lets say optimised for hashes lol
unshadow has quit [Ping timeout: 260 seconds]
unshadow has joined #crystal-lang
soveran has quit [Ping timeout: 245 seconds]
<FromGitter>
<MaxLap> I'll open an issue with the problems i've just found. Here is a one liner that shows a few problems all at one: ⏎ `puts({0 => 1, 0.0 => 1000, 1.0 => 10, 1 => 100})`
<FromGitter>
<bash> So serious question: If I want to have a cancellable timer... Is there no better solution than having to wait for the sleep to complete and then check if the timer has been cancelled? (Something like this: https://github.com/andrewhamon/quartz/blob/master/src/quartz/timer.cr#L11)
Kug3lis has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Philpax has quit [Ping timeout: 240 seconds]
<BlaXpirit>
bash, well that's a pretty good approach, why complicate things
<FromGitter>
<bash> Fair enough
<BlaXpirit>
bash, you could have a fiber that waits on a channel. and the channel may receive either a "do it" or "don't do it" message
<BlaXpirit>
but that's an additional fiber just for waiting
<FromGitter>
<bash> ... and I don't want to send a "do it" message
<FromGitter>
<bash> oh
<FromGitter>
<bash> this looks interesting
<BlaXpirit>
bash, well, that would be a fiber that sleeps and then sends a "do it" message
<BlaXpirit>
and heh i was gonna name a project "quartz" because it has letters 'q' and 't' but whatever, that project isn't happening any time soon
<BlaXpirit>
bash, i think that 'timeout' thing should be (and maybe is planned to be) in standard library. but it's a very small utility to use a powerful built in feature - "select". i think you could come up with something smart with that and timers
<BlaXpirit>
i'm off
soveran has quit [Remote host closed the connection]
Philpax has joined #crystal-lang
Kug3lis has joined #crystal-lang
<FromGitter>
<MaxLap> Is there and equivalent to ruby's Module#prepend?
Papierkorb has quit [Ping timeout: 258 seconds]
Papierkorb has joined #crystal-lang
Kug3lis has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]