2024/11/14

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 +0100mari-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 +0100acidjnk(~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 +0100Square2(~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 +0100L29Ah(~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