diff options
| author | rtk0c <[email protected]> | 2025-09-01 13:31:50 -0700 |
|---|---|---|
| committer | rtk0c <[email protected]> | 2025-09-01 13:31:50 -0700 |
| commit | 3b3ded70587af4e780ed18697cd2be8ff48efe67 (patch) | |
| tree | 7c24e6719b2f34a7395432470c74c3e5d8ebd79b /content/blog/on-continuations.md | |
| parent | 6e3af2d649b2931b9928a6d3ef21a90bbd86c35d (diff) | |
Big spell correction, using LTeX vscode extension
which is languagetools under the hood
which I struggled immensely trying to setup in emacs back then... now I give up
Diffstat (limited to 'content/blog/on-continuations.md')
| -rw-r--r-- | content/blog/on-continuations.md | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/content/blog/on-continuations.md b/content/blog/on-continuations.md index 918f85d..d57cc22 100644 --- a/content/blog/on-continuations.md +++ b/content/blog/on-continuations.md @@ -35,7 +35,7 @@ which is indeed fascinating, though now _how_ it works and _why_ seem to hide th **Theofanis:** ...sure? -**Asimoula:** We should now then take a detours out of mathematics and theory land, and dive into the dirty waters of real CPUs and implementations. After that, we'll climb on mountain of asynchronous programming, so we can see a different way for using continuations—at the same time so we can look at it from a different, perhaps much higher vantage point. In this way, we'll not be blinded by the great city of Scheme and its fortress of walls, and be able to see the cloud of continuation in its full shape. +**Asimoula:** We should now then take a detour out of mathematics and theory land, and dive into the dirty waters of real CPUs and implementations. After that, we'll climb on mountain of asynchronous programming, so we can see a different way for using continuations—at the same time, so we can look at it from a different, perhaps much higher vantage point. In this way, we'll not be blinded by the great city of Scheme and its fortress of walls, and be able to see the cloud of continuation in its full shape. But enough babbling about, let's jump in: @@ -58,13 +58,13 @@ The Callstack ``` **Theofanis:** Yes, that seems to make sense, now that you talk about. I do seem to recollect about this. -_hesitating, for he being a JavaScript programmer by trade doesn't quite have the C model on top of the head_ +_Hesitating, for he being a JavaScript programmer by trade doesn't quite have the C model on top of the head_ -**Asimoula:** And so as you see, when we return from `bar()`, for hypothetically, we place the return value at a predetermined location, and read the "return address" from another predetermined location, and `jmp` to it. The frame of `bar()` is now free reign for anybody else to write on top of.[^calling-convention] In particular that return address points to a special chunk inside the assembly of `foo()`, that takes care of things after `call`ing `bar()`. But the details are unimportant for us right now. +**Asimoula:** And so as you see, when we return from `bar()`, for hypothetically, we place the return value at a predetermined location, and read the "return address" from another predetermined location, and `jmp` to it. The frame of `bar()` is now free rein for anybody else to write on top of.[^calling-convention] In particular that return address points to a special chunk inside the assembly of `foo()`, that takes care of things after `call`ing `bar()`. But the details are unimportant for us right now. **Theofanis:** Right. -**Asimoula:** Now if you take your hand, and cover up the part of the stack for variables of `bar()` and its babbage, and squint your eyes a little bit, so might realize a magical thing that seems to be happening here: for all we know, Deina who works on `bar()` has just wrote a few bytes into `<return value>` and `jmp`ed to another address at `[rsp+4]`, and he seem to have magically teleported to a place where the blinking lights and whistling crowd resumes into motion, in middle of `foo()`. +**Asimoula:** Now if you take your hand, and cover up the part of the stack for variables of `bar()` and its babbage, and squint your eyes a little bit, so might realize a magical thing that seems to be happening here: for all we know, Deina who works on `bar()` has just written a few bytes into `<return value>` and `jmp`ed to another address at `[rsp+4]`, and he seems to have magically teleported to a place where the blinking lights and whistling crowd resumes into motion, in middle of `foo()`. **Theofanis:** That does seem sort of magical, if you put such metaphors on top of it. @@ -126,7 +126,7 @@ To that idea, _CPS is a property that some programs have. CPS can be obtained ei **Asimoula:** You got it exactly right, my friend. -As some bonus chatter, an naive `call/cc` machinery by stack copying can be quite slow. It would literally copy the entire execution stack, megabytes of data, to the heap, and replace it when reentering the continuation. +As some bonus chatter, a naive `call/cc` machinery by stack copying can be quite slow. It would literally copy the entire execution stack, megabytes of data, to the heap, and replace it when reentering the continuation. Non-naive implementations like [Chicken](https://www.more-magic.net/posts/internals-gc.html) exists, by rewriting the entire program to be CPS. This way, `call/cc` is free because literally everything is already a continuation. But this comes at the tradeoff that everything, even the code that does not _explicitly use_ continuations, are just a little bit slower. @@ -141,7 +141,7 @@ Read on at your own risk (or benefit). [^demonic-breathe]: What I mean by this is `setjmp`/`longjmp` traditionally have a bad reputation among programmers, that it allows non-local control flow ("goto considered harmful"). Also this metaphor isn't all that helpful to showing what continuations are *supposed to* enable; C programs really don't use `setjmp`/`longjmp` similarly to continuations at all. I guess a little bit? -[^calling-convention]: These are all made up for the convenience for the demonstration. I don't remember if any real calling convetions work in this exact way, but even if they do, things like parameters, register spillage, and stack pointer handling are omitted here. Don't take it too seriously. +[^calling-convention]: These are all made up for the convenience for the demonstration. I don't remember if any real calling conventions work in this exact way, but even if they do, things like parameters, register spillage, and stack pointer handling are omitted here. Don't take it too seriously. [^stack-dir]: Usually, the callstack is said to grow downwards (lower address means deeper callstack), based on that most calling conventions do it this way. I am going to call it "upwards" because it probably makes more sense to more people. |
