Compare commits
No commits in common. "5048cb8806d522b9f926b8b546df44d810b1f182" and "a36fd874ecf9d0bfb0a90de06efed49a4cd460c9" have entirely different histories.
5048cb8806
...
a36fd874ec
2 changed files with 5 additions and 15 deletions
|
|
@ -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 one’s 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 one’s program.”
|
||||||
Unfortunately, scheme programmers aren’t given that invitation.
|
Unfortunately, scheme programmers aren’t given that invitation.
|
||||||
That’s no fair!
|
That’s 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 scheme’s multiple return values; `(values v1 v2 ...)` is just <code className="long">(call/cc (lambda (k) (k v1 v2 ...)))</code>.
|
Incidentally, this helps me understand scheme’s multiple return values; `(values v1 v2 ...)` is just `(call/cc (lambda (k) (k v1 v2 ...)))`.
|
||||||
|
|
||||||
I recommend reading about continuations in Dybvig’s [<i>The Scheme Programming Language</i>](https://www.scheme.com/tspl4/further.html#g63)
|
I recommend reading about continuations in Dybvig’s [<i>The Scheme Programming Language</i>](https://www.scheme.com/tspl4/further.html#g63)
|
||||||
if you’re (justly) dissatisfied with my explanation or just want to learn more precisely how they work and their applications.
|
if you’re (justly) dissatisfied with my explanation or just want to learn more precisely how they work and their applications.
|
||||||
|
|
@ -223,12 +223,7 @@ done
|
||||||
|
|
||||||
I’ll explain this macro one part at a time.
|
I’ll 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:
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue