Why would I do that? Because I can :-) But seriously, using continuations in a language entirely unsuited for it is a good way to experience the tradeoffs of different styles of languages, as well as a way to learn more about how continuations work.
This code is entirely different from my Arc version, mainly because in the Arc version I decided to see if the
Because Java doesn't support first-class functions, every continuation function needs to be wrapped in a class that implements an interface, which I unimaginatively call
On the whole, mondo-bizarro worked better in Java than I expected; no Greenspunning required. It produces the expected 11213 output, proving it works. I think the Java code is actually easier to understand, since everything is explicit.
I have also found it entertaining to implement some of the complex SICP exercises in Java; maybe I'll post details later.
(The title of this article is, of course, a homage to Mathematics Made Difficult.)
Here's the code.
throw/catch
idiom could replace call/cc
; the Java code is much closer to the original Scheme. Because Java doesn't have first-class continuations, I used the Continuation-passing style of explicitly passing continuations around. Then call/cc
is simply replaced with use of the current continuation.
Continuation
. The "let" also turns into an object creation, resulting in another class. This results in a fair bit of boilerplate to handle all these classes compared to the Scheme code, but the Java code maps recognizably onto the Scheme code.
/**
* Mondo-Bizarro ported to Java.
* Based on mondo-bizarro by Eugene Kohlbecker
* ACM SIGPLAN Lisp Pointers, Volume 1, Issue 2 (June-July 1987) pp 22-28
*/
/* Original Scheme code:
(define mondo-bizarro
(let (
(k (call/cc (lambda (c) c)))
)
(write 1)
(call/cc (lambda (c) (k c)))
(write 2)
(call/cc (lambda (c) (k c)))
(write 3)))
*/
interface Continuation {
public void run(Continuation c);
}
public class Mondo implements Continuation {
public static void main(String argv[]) {
Continuation c = new Mondo();
c.run(c);
}
public void run(Continuation c) {
Continuation let = new Let();
let.run(c);
}
class Let implements Continuation {
Continuation k;
public void run(Continuation c) {
k = c;
System.out.println("1");
k.run(new C2());
}
class C2 implements Continuation {
public void run(Continuation c) {
System.out.println("2");
k.run(new C3());
}
}
class C3 implements Continuation {
public void run(Continuation c) {
System.out.println("3");
}
}
}
}
Computer history, restoring vintage computers, IC reverse engineering, and whatever
Continuations made difficult
Documentation for (almost) all of Arc
For each function, I include a description, examples, a link to the code, and a link to the wiki. I'll fill in a few gaps as time permits. I'll appreciate any feedback on the organization.
Arc: popular since 2004!
"Even tried multi" error explained
Error 404 Not found - file doesn't exist or is read protected [even tried multi]
But what is "multi"? And why does the web server act like it's doing you a big favor trying it? Is it trying multiple times, maybe?
These days, 404 messages are still common, but the "multi" message is fairly
rare.
The message was once so common, though, it spawned a
large
number
of
parodies.
I decided to get to the bottom of this, and find out what this "multi" is.
It didn't take long to discover that this message comes from the CERN httpd server, written by Tim Berners-Lee and others back in the 1990's.
A bit of poking around found the source code that generates the infamous multi message. It turns out that "multi" is short for
multi-format documents, and was a cool new feature back in 1993. It
is a technique for the server to have multiple formats of a file and provides the best one your browser can handle. For instance, suppose you try to fetch an image
So there you have it, the definitive answer to what "even tried multi" means, and a bit of web history.
/cat
. Back in the olden days, browsers weren't so good with images, so your browser might only display gifs and not jpegs. Your browser asks for /cat
and says that it can handle gifs. Now for the multi magic. The server can have multiple files, say /cat.gif
, /cat.jpg
, and /cat.png
. It looks at what your browser can accept, looks at what it has, and returns the best choice, in this case /cat.gif
. Likewise, a file could have versions in text and PDF, and the server would return the best type for your browser. Web servers still support content negotiation, but they generally don't mention it in 404 messages any more.
Arc continuation puzzle
(mondo-bizarro)
print?
(def mondo-bizarro () (let k (catch throw) (pr 1) (catch (k throw)) (pr 2) (catch (k throw)) (pr 3)) nil)Reference: ACM SIGPLAN Lisp Pointers, Volume 1, Issue 2 (June-July 1987) pp 22-28.