Continuations made difficult

For a challenge, I translated the "mondo-bizarro" Arc Continuation Puzzle into Java.

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 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.

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 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.

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.

/**
 * 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");
      }
    }
  }
}

Continue reading...

Documentation for (almost) all of Arc

I've got almost all of the Arc core documented with an alphabetical index. I've covered ac.scm, arc.arc, strings.arc, but am currently omitting the web server and applications.

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!

Did you know that Arc has been a popular computer language since 2004? Pretty good for a language released in January 2008. I discovered Arc's longstanding popularity in Computerworld's review of Paul Graham's Hackers and Painters. The review from July 2004 says, "Paul Graham, well known for developing the popular Arc computer language and other Internet technologies...". I guess they didn't realize Arc hadn't been released at the time. Hopefully we won't see them publishing job listings looking for 4 years of Arc experience.

"Even tried multi" error explained

If you were around during the early days of the web, you surely remember the message
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 /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.

So there you have it, the definitive answer to what "even tried multi" means, and a bit of web history.

Arc continuation puzzle

In case anyone thinks continuations are straightforward, I've ported Eugene Kohlbecker's classic Scheme puzzle to Arc. What does (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.

Lots more documentation

I've added lots more documentation on the Arc language: filesystem manipulation, anaphoric operations, iteration, threading, time operations, queues, and trees.

I/O in the Arc language

The Arc language provides many I/O operations. I have written an overview of them: I/O in the Arc language. This covers file I/O, string I/O, and the many operations to perform reads and writes. The operations strike me as very non-orthogonal; it's unpredictable which ones take ports, have defaults, or specify an eof value. I try to bring some organization to them.

Internals of places and setforms

The documentation continues with Internals of places and setforms. This continues where the assignment and places documentation left off. If you want to know how to create your own places and generalized variables in Arc, you're in luck.

Arc documentation table of contents

I've created a table of contents summarizing my documentation on the Arc language. (By request, it's now on the sidebar too.)