Compare commits

..

No commits in common. "5048cb8806d522b9f926b8b546df44d810b1f182" and "a36fd874ecf9d0bfb0a90de06efed49a4cd460c9" have entirely different histories.

2 changed files with 5 additions and 15 deletions

View file

@ -13,7 +13,7 @@ In his 1968 letter, [<i>A case against the GO TO statement</i>](https://www.cs.u
(known only by that name), Dijkstra said “[t]he go to statement as it stands is just too primitive, it is too much an invitation to make a mess of ones program.” (known only by that name), Dijkstra said “[t]he go to statement as it stands is just too primitive, it is too much an invitation to make a mess of ones program.”
Unfortunately, scheme programmers arent given that invitation. Unfortunately, scheme programmers arent given that invitation.
Thats no fair! Thats no fair!
Fortunately, scheme has a procedure, `call/cc`, that we can use to emulate the style of control flow that `GOTO` provides. Fortunately, scheme has a procedure, `call/cc`, that we can use to emulate the control flow that `GOTO` provides.
We can use syntactic abstraction to invite scheme programmers to make a mess of their programs in a limited context. We can use syntactic abstraction to invite scheme programmers to make a mess of their programs in a limited context.
## How `GOTO` works ## How `GOTO` works
@ -146,7 +146,7 @@ operator.
The `k` that `call/cc` calls its argument with represents, roughly, the rest of the computation. The `k` that `call/cc` calls its argument with represents, roughly, the rest of the computation.
The “current continuation” is what will be executed next at the point that `call/cc` is called. The “current continuation” is what will be executed next at the point that `call/cc` is called.
Incidentally, this helps me understand schemes multiple return values; `(values v1 v2 ...)` is just <code className="long">(call/cc (lambda (k) (k v1 v2 ...)))</code>. Incidentally, this helps me understand schemes multiple return values; `(values v1 v2 ...)` is just `(call/cc (lambda (k) (k v1 v2 ...)))`.
I recommend reading about continuations in Dybvigs [<i>The Scheme Programming Language</i>](https://www.scheme.com/tspl4/further.html#g63) I recommend reading about continuations in Dybvigs [<i>The Scheme Programming Language</i>](https://www.scheme.com/tspl4/further.html#g63)
if youre (justly) dissatisfied with my explanation or just want to learn more precisely how they work and their applications. if youre (justly) dissatisfied with my explanation or just want to learn more precisely how they work and their applications.
@ -223,12 +223,7 @@ done
Ill explain this macro one part at a time. Ill explain this macro one part at a time.
First, First, `(define-syntax goto (syntax-rules () [...]))` defines `goto` as a syntax transformer (more precise name for a macro) using the `syntax-rules` pattern-matching language.
```scheme
(define-syntax goto
(syntax-rules () [...]))
```
defines `goto` as a syntax transformer (more precise name for a macro) using the `syntax-rules` pattern-matching language.
The `()` after `syntax-rules` is the empty list of literals; we don't have any special words here, so it doesn't apply. The `()` after `syntax-rules` is the empty list of literals; we don't have any special words here, so it doesn't apply.
You can read more about how `syntax-rules` works in [TSPL](https://scheme.com/tspl4/syntax.html#./syntax:s14), but we'll only be using the most basic features here. You can read more about how `syntax-rules` works in [TSPL](https://scheme.com/tspl4/syntax.html#./syntax:s14), but we'll only be using the most basic features here.
The important thing is to know that matched names are replaced in the output and that `x ...` matches/splices zero or more expressions. The important thing is to know that matched names are replaced in the output and that `x ...` matches/splices zero or more expressions.
@ -297,12 +292,7 @@ We wrap the body of `with-goto` in `(call/cc (lambda (k) ...))`.
Inside the body, if we call `k` like `(k (label))` we effectively replace the body with the result of calling `label`. Inside the body, if we call `k` like `(k (label))` we effectively replace the body with the result of calling `label`.
We accomplished a jump! We accomplished a jump!
```scheme `(set! goto (lambda (label) (k (label))))` makes `goto` do exactly this (note that function arguments have to be evaluated before the procedure call takes place).
(set! goto
(lambda (label)
(k (label))))
```
makes `goto` do exactly this (note that function arguments have to be evaluated before the procedure call takes place).
We use `(define goto #f)` combined with a `set!` because the labels we defined earlier need to be able to see the `goto` function. We use `(define goto #f)` combined with a `set!` because the labels we defined earlier need to be able to see the `goto` function.
This is what our first `with-goto` looks like when we expand it: This is what our first `with-goto` looks like when we expand it:

View file

@ -16,7 +16,7 @@ Importantly, literally nothing changes for (cool) users who (righteously) block
It is perfect [progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement). It is perfect [progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement).
## Steps ## Steps
1. Add htmx to your `<head>`: <code className="long">{`<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>`}</code> 1. Add htmx to your `<head>`: <code class="long">{`<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>`}</code>
2. Add `hx-boost="true"` to your `<body>`. 2. Add `hx-boost="true"` to your `<body>`.
3. Add `hx-preserve="true"` to stuff that is static between pages (probably a sidebar/footer). Add a unique `id` if it doesn't already have one. 3. Add `hx-preserve="true"` to stuff that is static between pages (probably a sidebar/footer). Add a unique `id` if it doesn't already have one.
4. Be happy that it works with and without JavaScript. 4. Be happy that it works with and without JavaScript.