Newest at the top
2025-01-20 03:42:44 +0100 | merijn | (~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 +0100 | merijn | (~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 +0100 | peterbecich | (~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 +0100 | merijn | (~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 +0100 | merijn | (~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 |
2025-01-20 03:14:41 +0100 | <c_wraith> | You have to write it more like `b c (f . g . a)' |
2025-01-20 03:14:40 +0100 | <albet70> | try catch isn't cps, right? |
2025-01-20 03:13:57 +0100 | <c_wraith> | the thing, CPS doesn't work like that. |
2025-01-20 03:12:58 +0100 | <albet70> | without exception stuff |
2025-01-20 03:12:40 +0100 | <albet70> | i just wonder if cps can achive that |
2025-01-20 03:12:14 +0100 | merijn | (~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 260 seconds) |
2025-01-20 03:12:12 +0100 | <albet70> | for example in python f(g(a(b(c)))) you can throw an exception in c and catch it in f, no need to return to b, then to a, then to g |