2025/12/21

Newest at the top

2025-12-21 20:12:23 +0100jmcantrell_jmcantrell
2025-12-21 20:12:07 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 265 seconds)
2025-12-21 20:12:01 +0100shaeto(~Shaeto@94.25.234.244) (Quit: WeeChat 4.1.1)
2025-12-21 20:10:25 +0100jmcantrell_(~weechat@user/jmcantrell) jmcantrell
2025-12-21 20:06:59 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) merijn
2025-12-21 20:06:35 +0100FloorCalc(~user@user/FloorCalc) FloorCalc
2025-12-21 20:06:10 +0100FloorCalc(~user@user/FloorCalc) (Remote host closed the connection)
2025-12-21 20:04:06 +0100CiaoSen(~Jura@2a02:8071:64e1:da0:5a47:caff:fe78:33db) (Ping timeout: 256 seconds)
2025-12-21 20:01:16 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 256 seconds)
2025-12-21 19:56:21 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) merijn
2025-12-21 19:56:05 +0100 <monochrom> In the case of lists, those rules will suggest that the best way to build list is to use `build`, ironically literally. >:)
2025-12-21 19:55:54 +0100CiaoSen(~Jura@2a02:8071:64e1:da0:5a47:caff:fe78:33db) CiaoSen
2025-12-21 19:53:28 +0100 <monochrom> If you consult base source code for performance prediction, don't forget to look for RULES which can totally override normal source code.
2025-12-21 19:46:02 +0100 <c_wraith> I was actually amused my testing for Day 8, part 2 showed that the classic hyper-optimized mutable reference algorithms weren't any faster than just using Data.Map. At least at that size of problem.
2025-12-21 19:45:15 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 240 seconds)
2025-12-21 19:44:31 +0100 <c_wraith> Yeah. In the context of aoc, just avoid the big performance pitfalls and you'll be fine. I mean, people use *far* slower runtimes than what you get out of GHC without trouble. Algorithm choice is the big deal.
2025-12-21 19:41:07 +0100 <milan2> I guess, I am still noob and optimizations are not needed for Advent of Code :D
2025-12-21 19:40:34 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) merijn
2025-12-21 19:40:01 +0100 <c_wraith> But the moral of the story - there are a lot of ways to consume and produce lists. Which one is best can be pretty context-dependent. For broad rules: use the least powerful tool that gets the job done.
2025-12-21 19:37:09 +0100 <c_wraith> .... also, it was the runtime of that specific operation. Not the whole program. I should be clear, it was a micro-optimization.
2025-12-21 19:36:52 +0100 <milan2> That is considerable.
2025-12-21 19:36:04 +0100 <c_wraith> I've definitely written code where using build cut the run time by about 65%.... given the specific way the list was later being consumed.
2025-12-21 19:34:23 +0100 <c_wraith> For tight loops, that can make a big difference.
2025-12-21 19:33:00 +0100 <c_wraith> every one of those (:) that's actually allocated still goes on the heap and still needs to be collected later.
2025-12-21 19:32:20 +0100 <c_wraith> it minimizes garbage collector churn
2025-12-21 19:30:33 +0100 <milan2> c_wraith: I think I understand what build does, so for chaining foldr multiple lists are created. But that should not matter as they are produced lazily?
2025-12-21 19:29:38 +0100 <c_wraith> https://www.joachim-breitner.de/publications/CallArity-TFP.pdf Well. Sometimes it gets called that.
2025-12-21 19:29:18 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 244 seconds)
2025-12-21 19:28:36 +0100 <c_wraith> that optimization was... uh.... "precise arity analysis"?
2025-12-21 19:28:00 +0100 <c_wraith> the @src database is older than the optimizations in GHC that allow foldl-via-foldr to be a good consumer.
2025-12-21 19:27:24 +0100 <probie> s/think/thing/
2025-12-21 19:27:08 +0100 <probie> which is the sort of think I was expecting to see
2025-12-21 19:27:02 +0100 <probie> Yeah, looking at the source for base `foldl k z0 xs = foldr (\(v::a) (fn::b->b) -> oneShot (\(z::b) -> fn (k z v))) (id :: b -> b) xs z0`
2025-12-21 19:25:30 +0100 <c_wraith> yeah, the @src database is not what GHC actually uses, either.
2025-12-21 19:24:59 +0100 <lambdabot> foldl f z (x:xs) = foldl f (f z x) xs
2025-12-21 19:24:59 +0100 <lambdabot> foldl f z [] = z
2025-12-21 19:24:59 +0100 <probie> @src foldl
2025-12-21 19:24:21 +0100 <milan2> Ty :)
2025-12-21 19:24:16 +0100 <c_wraith> build itself is documented at https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-List.html#v:build
2025-12-21 19:23:50 +0100 <c_wraith> see https://hackage-content.haskell.org/package/ghc-internal-9.1401.0/docs/src/GHC.Internal.Base.html#… for an example. In particular, pay attention to the long section of comments.
2025-12-21 19:23:14 +0100 <milan2> c_wraith: Now I am lost a little, could you elaborate on "build" or provide some documentation?
2025-12-21 19:22:32 +0100merijn(~merijn@host-cl.cgnat-g.v4.dfn.nl) merijn
2025-12-21 19:22:19 +0100lambda_gibbon(~lambda_gi@2603:7080:ee00:37d8:dcc4:d31b:c3d9:56cd)
2025-12-21 19:22:04 +0100 <c_wraith> Participating in that on both sides requires using both foldr and build
2025-12-21 19:21:41 +0100 <c_wraith> I think what you're getting at is foldr/build fusion
2025-12-21 19:21:20 +0100 <milan2> c_wraith: Ok, so for reverse foldl is preferable.
2025-12-21 19:20:58 +0100 <milan2> chain of foldr should not traverse multiple times?
2025-12-21 19:19:45 +0100 <lambdabot> reverse = foldl (flip (:)) []
2025-12-21 19:19:45 +0100 <c_wraith> @src reverse
2025-12-21 19:19:26 +0100 <c_wraith> sure. What's the best for implementing reverse?