2025/01/20

Newest at the top

2025-01-20 03:46:02 +0100 <monochrom> Yeah you're just trading heap for stack. It's why I was so worked up about limited stack and unlimited heap.
2025-01-20 03:45:47 +0100 <geekosaur> that's what I said, wall-o-wtf 🙂
2025-01-20 03:45:39 +0100hgolden(~hgolden@2603:8000:9d00:3ed1:6ff3:8389:b901:6363) hgolden
2025-01-20 03:45:29 +0100 <albet70> I like this talks even I don't understand now, it's very inspired :)
2025-01-20 03:45:00 +0100 <int-e> monochrom: Heh. So if you use Cont or other (a -> r) -> (b -> r) -> r Haskell-level continuations, then at runtime, you have thunk-level CPS (continuations are stored in thunks until needed)
2025-01-20 03:43:58 +0100hgolden(~hgolden@2603:8000:9d00:3ed1:6ff3:8389:b901:6363) (Remote host closed the connection)
2025-01-20 03:43:29 +0100Adran(~adran@botters/adran) Adran
2025-01-20 03:42:44 +0100merijn(~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 265 seconds)
2025-01-20 03:41:25 +0100 <monochrom> Ooops, s/small//
2025-01-20 03:40:07 +0100 <monochrom> In this case, context is synonym for continuation.
2025-01-20 03:39:55 +0100 <geekosaur> unless they drowned in the wall-o-wtf
2025-01-20 03:39:47 +0100 <monochrom> If you then try to go a bit lower level, you say: push the context (or representation of) on the stack, bring the redex to the front and work on it, afterwards pop the context and look for the next redex, etc.
2025-01-20 03:39:26 +0100 <int-e> geekosaur: *surely* one of the many answers we've come up with was satisfactory
2025-01-20 03:38:15 +0100 <monochrom> At a high level, it goes like this. Given an evaluation order, you can factor each to-be-evaluated expression into redex and context. Redex means the small subexpression to evaluate right now, context is the rest.
2025-01-20 03:38:05 +0100merijn(~merijn@128-137-045-062.dynamic.caiway.nl) merijn
2025-01-20 03:37:50 +0100 <geekosaur> you know we probably lost albet70 long ago…
2025-01-20 03:37:31 +0100peterbecich(~Thunderbi@syn-047-229-123-186.res.spectrum.com) peterbecich
2025-01-20 03:33:51 +0100 <monochrom> Fortunately! PLT people have noticed a commonality over all evaluation orders. The "some things" is called... continuations. You can always say "continuation stack" and it will be always right.
2025-01-20 03:32:42 +0100 <monochrom> Once you fix an evaluation order, you will realize you need a stack for some things. Eager and lazy have opposite "some things", but both will need a stack.
2025-01-20 03:30:07 +0100 <int-e> Well, not sure. But the chances are good.
2025-01-20 03:29:28 +0100 <int-e> Anyway. Understanding Haskell low-level execution is quite difficult. I'm sure I'm getting it subtly wrong.
2025-01-20 03:28:13 +0100 <int-e> (the strictness analyser can spoil the fun of course)
2025-01-20 03:27:42 +0100 <int-e> because that *tail-recusively* builds a huge thunk that is then entered, entering a chain of subthunks all at once
2025-01-20 03:27:21 +0100merijn(~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 244 seconds)
2025-01-20 03:26:58 +0100 <int-e> But the thunk thing explains why `foldl (+) 1 [1..1000000]` used to overflow the stack (before stacks were made extensible)
2025-01-20 03:26:17 +0100 <geekosaur> (in a profiling report, you do get an indication of call stacks of some flavor)
2025-01-20 03:26:01 +0100 <int-e> (GHC does way too much inlining, for starters. And you'd need to anticipate strictness analysis too.)
2025-01-20 03:25:28 +0100 <int-e> Details get murky quickly. You won't be able to discern most of these things at the source code level.
2025-01-20 03:24:01 +0100 <geekosaur> I know you can piggyback on the mechanism to get a "stack trace" (with +RTS -xc) *but* profiling must be enabled for it to work; I presume that provides something resembling a call stack
2025-01-20 03:23:59 +0100 <int-e> AIUI, fundamentally, entering a thunk allocates a stack frame. This extends to strict functions (which can be thought of as a thunk that is entered immediately, but GHC won't allocate the thunk)
2025-01-20 03:23:32 +0100 <c_wraith> ghc uses the stack for nested evaluation of thunks. That often corresponds with nested function calls, but not always.
2025-01-20 03:22:43 +0100merijn(~merijn@128-137-045-062.dynamic.caiway.nl) merijn
2025-01-20 03:22:28 +0100 <geekosaur> (possibly it's all exception frames. note that in Haskell you must be in IO to handle an exception, so things are a bit different than they are for pure code anyway)
2025-01-20 03:21:33 +0100 <geekosaur> in GHC Haskell these frames don't correspond to calls the way they do in more procedural languages; but I don't recall what they do correspond to.
2025-01-20 03:20:36 +0100 <probie> "true" CPS codeâ„¢ (with TCO) doesn't allocate stack frames
2025-01-20 03:18:38 +0100 <geekosaur> in all cases it works backwards up stack frames until it finds one with an exception handler
2025-01-20 03:17:42 +0100 <monochrom> THANK YOU!
2025-01-20 03:17:22 +0100 <int-e> The game we're playing could be called "pick your favorite abstraction to think about your code".
2025-01-20 03:17:18 +0100 <geekosaur> exceptions pretty much require it
2025-01-20 03:17:02 +0100 <geekosaur> so does GHC for that matter
2025-01-20 03:16:54 +0100 <geekosaur> so does C++
2025-01-20 03:16:51 +0100 <geekosaur> it does stack unwinding
2025-01-20 03:16:43 +0100 <int-e> On a different level, the answer is no; you can't have a pure function with an early return. Obviously not; that wouldn't be pure.
2025-01-20 03:16:36 +0100 <monochrom> I'm going to go out on a limb that Python achieves that by compiling an exception language to CPS low level code.
2025-01-20 03:15:58 +0100 <int-e> Which you can read as ParsecT wrapping a function that takes *four* continuations
2025-01-20 03:15:39 +0100 <c_wraith> You need to make significant changes, because the whole point is that you're replacing nested function calls with continuations
2025-01-20 03:15:38 +0100 <int-e> For example, look at this https://hackage.haskell.org/package/parsec-3.1.18.0/docs/src/Text.Parsec.Prim.html#ParsecT
2025-01-20 03:15:23 +0100 <int-e> The answer is yes but you have to change all your functions to take continuations as arguments. (Whether you do that using Cont or not is up to you.)
2025-01-20 03:15:18 +0100 <monochrom> int-e: :( XD
2025-01-20 03:15:10 +0100 <c_wraith> It's an invasive intervention