Newest at the top
| 2026-05-21 15:15:21 +0000 | <jaror> | But I definitely also think unboxed arrays deserve a better API |
| 2026-05-21 15:14:47 +0000 | <jaror> | s/are/should be/ |
| 2026-05-21 15:13:36 +0000 | <jaror> | I think small arrays are very common and it is unwieldy to have to switch between Array and SmallArray |
| 2026-05-21 15:12:24 +0000 | <int-e> | If you care about the 1.6% wasted memory but are fine with the overhead of having pointers/thunks. |
| 2026-05-21 15:12:10 +0000 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) Lord_of_Life |
| 2026-05-21 15:09:39 +0000 | <jaror> | So if you use an array mostly immutably, you should go for SmallArray# is my conclusion. |
| 2026-05-21 15:09:39 +0000 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) (Excess Flood) |
| 2026-05-21 15:08:22 +0000 | <jaror> | ah that makes sense |
| 2026-05-21 15:07:37 +0000 | <int-e> | somewhere in the middle of this is https://gitlab.haskell.org/ghc/ghc/-/blob/master/rts/Updates.h#L489 |
| 2026-05-21 15:07:00 +0000 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) Lord_of_Life |
| 2026-05-21 15:06:52 +0000 | <int-e> | jaror: The card table is not touched in that case, it's the thunk that's going to be updated. The thunk is replaced by an indirection, and the indirection is recorded in the old generation's mutable list so GC treats it as a root. |
| 2026-05-21 15:05:54 +0000 | wootehfoot | (~wootehfoo@user/wootehfoot) wootehfoot |
| 2026-05-21 15:04:39 +0000 | humasect | (~humasect@dyn-192-249-132-90.nexicom.net) humasect |
| 2026-05-21 15:04:10 +0000 | Alex_delenda_est | (~al_test@5.139.233.99) |
| 2026-05-21 15:02:42 +0000 | comerijn | (~merijn@77.242.116.146) (Ping timeout: 248 seconds) |
| 2026-05-21 15:01:28 +0000 | Digit | (~user@user/digit) (Ping timeout: 256 seconds) |
| 2026-05-21 15:01:18 +0000 | Digitteknohippie | (~user@user/digit) Digit |
| 2026-05-21 14:54:40 +0000 | <tomsmeding> | (I'm guessing here though) |
| 2026-05-21 14:54:16 +0000 | <tomsmeding> | the card table being for "the Array# itself occurred in the mut list, now what changed exactly" |
| 2026-05-21 14:54:00 +0000 | <tomsmeding> | would the resolving of the thunk perhaps itself update the mut list? |
| 2026-05-21 14:53:27 +0000 | <jaror> | How is the card table updated then, it sounds quite distant |
| 2026-05-21 14:53:06 +0000 | <jaror> | ah, but then there may be a thunk nested deeply in the Array# which creates such a pointer when it is forced |
| 2026-05-21 14:52:47 +0000 | Square2 | (~Square4@user/square) (Ping timeout: 250 seconds) |
| 2026-05-21 14:52:23 +0000 | <tomsmeding> | that Channable blog post also does mention that |
| 2026-05-21 14:52:00 +0000 | <jaror> | I think I also read that laziness can cause similar kinds of pointers from the old to new generation though |
| 2026-05-21 14:51:15 +0000 | <int-e> | jaror: I believe your're right that Array# wouldn't need a card table, but then unsafeThawArray# would have to copy arrays to make room for a card table. |
| 2026-05-21 14:48:32 +0000 | <jaror> | ah so the card dirty card table entries are taken as roots when checking from pointers from the old to the new generation. |
| 2026-05-21 14:44:42 +0000 | Lord_of_Life | (~Lord@user/lord-of-life/x-2819915) (Excess Flood) |
| 2026-05-21 14:42:51 +0000 | <tomsmeding> | at least about how exactly mutability is relevant here |
| 2026-05-21 14:42:40 +0000 | <tomsmeding> | jaror: this sounds relevant https://www.channable.com/tech/lessons-in-managing-haskell-memory#mutability-is-the-root-of-all-ev… |
| 2026-05-21 14:40:43 +0000 | <jaror> | But that hardly sounds tipical |
| 2026-05-21 14:40:37 +0000 | <jaror> | Yes if you want to unsafely freeze or thaw it and use it mostly as a large mutable array then there seems to be an advantage to Array# |
| 2026-05-21 14:39:30 +0000 | <tomsmeding> | well unless it's long and you might want to thaw it at some point |
| 2026-05-21 14:38:41 +0000 | <jaror> | The documentation seems to imply that it is only mutation that is a problem and thus that SmallArray# should always be preferred over Array#... |
| 2026-05-21 14:37:29 +0000 | <jaror> | There's some documentation in the primitive package and also some documentation here: https://hackage-content.haskell.org/package/ghc-prim-0.13.0/docs/GHC-Prim.html#g:19 |
| 2026-05-21 14:37:26 +0000 | <tomsmeding> | > This allows the garbage collector to only re-traverse segments of the array that have been marked during certain phases |
| 2026-05-21 14:36:41 +0000 | <tomsmeding> | sure, I found that one first but there were no docs there whatsoever :) |
| 2026-05-21 14:36:12 +0000 | <jaror> | Yeah, or the GHC builtin one: https://hackage.haskell.org/package/base-4.21.0.0/docs/GHC-Exts.html#t:SmallArray-35- |
| 2026-05-21 14:35:49 +0000 | <tomsmeding> | oh primitive:Data.Primitive.SmallArray? |
| 2026-05-21 14:35:25 +0000 | <tomsmeding> | ok I don't actually know what SmallArray you're talking about :) |
| 2026-05-21 14:34:57 +0000 | <jaror> | But maybe it is an optimization for the other non-copying strategies that GHC also applies? |
| 2026-05-21 14:34:47 +0000 | chexum_ | (~quassel@gateway/tor-sasl/chexum) chexum |
| 2026-05-21 14:34:40 +0000 | chexum | (~quassel@gateway/tor-sasl/chexum) (Ping timeout: 252 seconds) |
| 2026-05-21 14:33:48 +0000 | <jaror> | I mean all the elements needs to be copied deeply, no? |
| 2026-05-21 14:33:45 +0000 | danza | (~danza@user/danza) danza |
| 2026-05-21 14:33:24 +0000 | <tomsmeding> | there's memcpy(), and then there's following all the pointers to all the heap nodes referenced from the array cells |
| 2026-05-21 14:27:36 +0000 | <jaror> | It talks about the GC not having to traverse all elements, but doesn't it need to do that anyway to copy everything over? |
| 2026-05-21 14:26:44 +0000 | <jaror> | I don't really understand any of the explanations in the docs on SmallArrays |
| 2026-05-21 14:23:35 +0000 | <jaror> | The immutable Array# I mean |
| 2026-05-21 14:23:13 +0000 | <jaror> | Do arrays still need a card table if their elements are unlifted? |