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 +0200 | ames | (~amelia@offtopia/offtopian/amelia) (Quit: Bye!) |
2025-06-23 18:34:18 +0200 | prdak | (~Thunderbi@user/prdak) (Ping timeout: 252 seconds) |
2025-06-23 18:34:11 +0200 | peterbecich | (~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 +0200 | yangby | (~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 +0200 | Discordian93 | (~Discordia@user/Discordian93) (Quit: Leaving.) |
2025-06-23 18:29:51 +0200 | prdak | (~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 +0200 | mreh | checks 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 +0200 | merijn | (~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 +0200 | mreh | (~matthew@host86-146-25-68.range86-146.btcentralplus.com) |
2025-06-23 18:21:47 +0200 | mreh | (~matthew@host86-146-25-68.range86-146.btcentralplus.com) (Read error: Connection reset by peer) |
2025-06-23 18:20:26 +0200 | <EvanR> | maybe |