Newest at the top
2024-11-14 16:19:25 +0100 | <EvanR> | (this is not the case for writing a big list out to I/O, this is a case where you can get streaming, which is good) |
2024-11-14 16:18:26 +0100 | <EvanR> | unless you use lazy I/O which is weird |
2024-11-14 16:18:20 +0100 | <EvanR> | usually when you load a big list of stuff from I/O, the whole list will exists just because |
2024-11-14 16:18:18 +0100 | <bailsman> | geekosaur: I'm fine that it streams loading and writing. But streaming the list generator into the update and never actually constructing the intermediate list is cheating for the purposes of the benchmark, since that won't be possible in the real use case. |
2024-11-14 16:17:39 +0100 | <geekosaur> | in fact that's where streaming frameworks came from |
2024-11-14 16:17:14 +0100 | <geekosaur> | as can writing |
2024-11-14 16:17:10 +0100 | <EvanR> | should do it |
2024-11-14 16:17:09 +0100 | <geekosaur> | consider that loading can be streamed |
2024-11-14 16:17:04 +0100 | <EvanR> | in IO somewhere realList <- evaluate (force list) |
2024-11-14 16:16:58 +0100 | <haskellbridge> | <Bowuigi> bailsman foldr/build uses a rule so just creating the list on a function on a function that is not inlined (with "{-# NOINLINE createList #-}") may work, I don't have a GHC at hand to test though |
2024-11-14 16:16:48 +0100 | <bailsman> | In my real-world-use-case I'm pretty sure the lists are going to have to be loaded from memory and cannot be streamed. |
2024-11-14 16:16:33 +0100 | <bailsman> | Did I write this correctly? https://paste.tomsmeding.com/B6koT8Nx |
2024-11-14 16:16:20 +0100 | mari-estel | (~mari-este@user/mari-estel) (Quit: on the move) |
2024-11-14 16:16:01 +0100 | <lortabac> | AutomaticExclamationMark |
2024-11-14 16:15:43 +0100 | acidjnk | (~acidjnk@p200300d6e7283f73687bc11ede7922f8.dip0.t-ipconnect.de) (Ping timeout: 264 seconds) |
2024-11-14 16:15:25 +0100 | <haskellbridge> | <Bowuigi> Fair enough |
2024-11-14 16:15:06 +0100 | <bailsman> | When I hear someone say AutomaticBang something different comes to mind than was probably intended |
2024-11-14 16:14:38 +0100 | <haskellbridge> | <Bowuigi> AutomaticBang might have been a clearer name lol |
2024-11-14 16:14:33 +0100 | <geekosaur> | and you really don't want to because a fair amount of the Prelude assumes laziness and will bottom if you somehow forced them to be strict |
2024-11-14 16:14:33 +0100 | <bailsman> | and the output list is created as well |
2024-11-14 16:14:27 +0100 | <bailsman> | How do I write this benchmark to ensure the list is already created when map runs and not streamed |
2024-11-14 16:13:56 +0100 | <haskellbridge> | <Bowuigi> Oh well, you can't make Haskell strict on a single pragma then |
2024-11-14 16:13:40 +0100 | <lortabac> | geekosaur: if you only use functions and data types that you define it shouldn't make a difference I guess |
2024-11-14 16:13:33 +0100 | <haskellbridge> | <Bowuigi> So it is StrictData but also for functions? Huh |
2024-11-14 16:13:02 +0100 | <lortabac> | it won't magically make Haskell a strict language |
2024-11-14 16:13:00 +0100 | <geekosaur> | not `rnf` |
2024-11-14 16:12:51 +0100 | <geekosaur> | not even that, actually. "strict" in Haskell means WHNF |
2024-11-14 16:12:28 +0100 | <lortabac> | Bowuigi: probably worth mentioning that the Strict pragma only makes user definitions strict. So the rest of the ecosystem (including lists) will still be lazy |
2024-11-14 16:12:16 +0100 | <haskellbridge> | <Bowuigi> I think that usage of deepseq means "fully evaluate smallRecs when smallRecs is evaluated" but I am probably wrong |
2024-11-14 16:12:13 +0100 | <EvanR> | it might also be that the non deepseq version was "just as slow" for some reason |
2024-11-14 16:11:54 +0100 | <geekosaur> | given the stuff in that paper you should be able to construct a derivative-based zipper for any list-like or tree-like structure |
2024-11-14 16:11:37 +0100 | <EvanR> | that's just a definition, it would have to be evaluated to cause the normal form to be realized |
2024-11-14 16:11:06 +0100 | <bailsman> | the benchmark is using `nf` so that should be forcing both the source list and the destination list to be actually created now, right? But it's exactly as fast as before |
2024-11-14 16:11:06 +0100 | <geekosaur> | right, I'm not sure it's the place to start buit the fundamentals of the zipper technique are http://strictlypositive.org/diff.pdf |
2024-11-14 16:11:03 +0100 | Square2 | (~Square4@user/square) (Ping timeout: 246 seconds) |
2024-11-14 16:10:43 +0100 | <bailsman> | doing smallRecsDeep = smallRecs `deepseq` smallRecs did not change anything either |
2024-11-14 16:10:04 +0100 | <haskellbridge> | <Bowuigi> You might need the slightly more general idea of the "derivative of a data structure" but it is essentially the same idea |
2024-11-14 16:09:51 +0100 | <geekosaur> | I don't know of any examples, but that doesn't seem much different from (say) a zipper for red-black trees |
2024-11-14 16:08:52 +0100 | <ph88> | geekosaur, i was mistaken, i have actually not one data structure to fit all of the tree but multiple like `data Program = Program a [Statement]` and `data Statement = Statement a Expression` (dummy examples). Can tree zippers work with this? or do i need another technique? |
2024-11-14 16:08:48 +0100 | <geekosaur> | optimizing lists by treating them as loops is another |
2024-11-14 16:08:20 +0100 | <haskellbridge> | <Bowuigi> You can force the first constructor (IIRC) with "seq", every constructor with "length" and the entire thing with "deepseq". Yeah Haskell has evaluation control |
2024-11-14 16:08:18 +0100 | <geekosaur> | build/foldr is one |
2024-11-14 16:08:14 +0100 | <geekosaur> | there's multiple levels of cheating |
2024-11-14 16:08:02 +0100 | L29Ah | (~L29Ah@wikipedia/L29Ah) L29Ah |
2024-11-14 16:07:27 +0100 | <EvanR> | why are we trying to cripple haskell again by "actually creating lists" and enabling Strict xD |
2024-11-14 16:07:23 +0100 | <bailsman> | Or did the compiler optimize that out |
2024-11-14 16:06:57 +0100 | <haskellbridge> | <Bowuigi> Laziness is something you will want to learn at some point but for now you can use "{-# LANGUAGE Strict #-}" if you don't want laziness |
2024-11-14 16:06:43 +0100 | <bailsman> | How do I force it to actually create the list? `smallRecs = force [... | ... <- ...]` did not change anything, map is still as fast as it was before. Maybe it wasn't cheating? |
2024-11-14 16:05:47 +0100 | <geekosaur> | IIRC it's in OCaml instead of Haskell so it won't cover things like laziness, but it'll still teach you the zen of functional programming |
2024-11-14 16:04:53 +0100 | <haskellbridge> | <Bowuigi> Because it is different to what you are used to. Functional languages can do optimizations that imperative langs can't, like list/fold/map/hylo fusion (AKA removing intermediate computations while traversing or creating stuff), safe(-ish) inlining, laziness stuff, etc |