2025/06/23

Newest at the top

2025-06-23 18:34:20 +0200 <EvanR> hold on unsafeCoerce isn't a no-op?
2025-06-23 18:34:20 +0200ames(~amelia@offtopia/offtopian/amelia) (Quit: Bye!)
2025-06-23 18:34:18 +0200prdak(~Thunderbi@user/prdak) (Ping timeout: 252 seconds)
2025-06-23 18:34:11 +0200peterbecich(~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds)
2025-06-23 18:33:55 +0200 <tomsmeding> been there, done that
2025-06-23 18:33:53 +0200 <tomsmeding> but unsafeCoerce# is really unsafe: if you unsafeCoerce# a Double# to a Word64#, which one would think should just work on a machine with 64-bit doubles, GHC will generate Word64# instructions on a floating-point register and you'll get syntax errors from your assembler
2025-06-23 18:33:35 +0200yangby(~secret@60.176.176.179) (Quit: Go out for a walk and buy a drink.)
2025-06-23 18:33:27 +0200 <haskellbridge> <magic_rb> To use unsafeCoerce# youd have to write unbox code which is a pain in the arse
2025-06-23 18:33:09 +0200 <haskellbridge> <magic_rb> Right so unsafeCoerce breaks the unboxed arithmetic magic, interesting
2025-06-23 18:32:52 +0200 <tomsmeding> now in this case you could probably use unsafeCoerce# on the unboxed values inside, and it would work on processors that put 8-bit signed and unsigned integers in the same registers (which is all of them)
2025-06-23 18:32:22 +0200 <tomsmeding> because GHC receives from unsafeCoerce an equality of Int8 and Word8, not of Int8# and Word8#
2025-06-23 18:32:07 +0200 <tomsmeding> writing 2 * unsafeCoerce (x + 1) requires GHC to box the Word8# result of 'x +# 1#' to a Word8 again, dereference the pointer again but now as an Int8, and do the 2* on the Int8#
2025-06-23 18:31:29 +0200 <tomsmeding> https://play.haskell.org/saved/jR3HVPQ5
2025-06-23 18:31:25 +0200 <tomsmeding> magic_rb: unsafeCoerce is actually _slower_ in this case because unsafeCoerce works on lifted values
2025-06-23 18:31:21 +0200 <mreh> I wasn't expecting the answer to be fromIntegral, but there you go
2025-06-23 18:31:15 +0200Discordian93(~Discordia@user/Discordian93) (Quit: Leaving.)
2025-06-23 18:29:51 +0200prdak(~Thunderbi@user/prdak) prdak
2025-06-23 18:29:47 +0200 <tomsmeding> even better would have been static restrictions like https://hackage.haskell.org/package/int-cast does
2025-06-23 18:29:16 +0200 <tomsmeding> mreh: an alternative implementation of fromIntegral would have been: throw a runtime error if the value is not as-is representable in the target type
2025-06-23 18:29:11 +0200 <EvanR> because unsafeCoerce doesn't
2025-06-23 18:29:07 +0200 <EvanR> that the answer to this question ended up amounting to doing a conversion is great
2025-06-23 18:28:42 +0200 <tomsmeding> plenty of administration around it but that looks unrelated to the integer conversion
2025-06-23 18:28:22 +0200 <tomsmeding> when you click Asm, you see that it becomes two adjacent assembly instructions, addb and shlb
2025-06-23 18:28:05 +0200 <tomsmeding> in Core you can see that fromIntegral becomes GHC.Prim.word8ToInt8#
2025-06-23 18:27:53 +0200 <tomsmeding> the 2* and +1 added to see where the actual user code is
2025-06-23 18:27:38 +0200 <tomsmeding> magic_rb: https://play.haskell.org/saved/5AlmTIJY
2025-06-23 18:27:29 +0200 <EvanR> a baseline expectation for this operation would be, if the value is representable by both Word8 and Int8 then the conversion leaves the value unchanged
2025-06-23 18:27:07 +0200 <mreh> it's only a gameboy interpreter, no need to blazingly fast optimizations
2025-06-23 18:25:54 +0200 <mreh> tomsmeding: good point
2025-06-23 18:25:43 +0200 <tomsmeding> mreh: how did you expect it to work?
2025-06-23 18:25:30 +0200 <EvanR> it's more like the above
2025-06-23 18:25:22 +0200 <EvanR> also a C style cast from Word8 to Int8 isn't the same as unsafeCoerce
2025-06-23 18:24:42 +0200 <mreh> that was not how I expect fromIntegral to work
2025-06-23 18:24:30 +0200 <tomsmeding> there are tons of rewrite rules for fromIntegral, let me check
2025-06-23 18:24:22 +0200 <haskellbridge> <magic_rb> It should compile to a noop
2025-06-23 18:24:16 +0200 <haskellbridge> <magic_rb> tomsmeding does it optimize properly?
2025-06-23 18:24:04 +0200 <lambdabot> [0,100,-56,-1]
2025-06-23 18:24:02 +0200 <tomsmeding> > map fromIntegral [0 :: Word8, 100, 200, 255] :: [Int8]
2025-06-23 18:23:57 +0200 <lambdabot> [0,100,200,255]
2025-06-23 18:23:56 +0200 <tomsmeding> > map fromIntegral [0 :: Word8, 100, 200, 255]
2025-06-23 18:23:53 +0200mrehchecks logs
2025-06-23 18:23:49 +0200 <mreh> sorry, crashed
2025-06-23 18:23:36 +0200 <EvanR> or that
2025-06-23 18:23:32 +0200 <EvanR> if it doesn't already exist use it to write a normal function which munges the newtype wrappers and does the conversion
2025-06-23 18:23:30 +0200 <tomsmeding> mreh: why not fromIntegral?
2025-06-23 18:23:19 +0200merijn(~merijn@77.242.116.146) (Ping timeout: 260 seconds)
2025-06-23 18:22:50 +0200 <EvanR> they left but I would look for a primitive conversion
2025-06-23 18:22:49 +0200mreh(~matthew@host86-146-25-68.range86-146.btcentralplus.com)
2025-06-23 18:21:47 +0200mreh(~matthew@host86-146-25-68.range86-146.btcentralplus.com) (Read error: Connection reset by peer)
2025-06-23 18:20:26 +0200 <EvanR> maybe