{ |one, step, back| } 1 of 1 article WikiSyndicate: full/short

The Arc Challenge   07 Feb 08
[ print link all ]

Paul Graham issues the Arc Challenge … who could resist?

Paul Graham’s Arc Challenge

You can read about the Arc Challenge here: The Arc Challenge. Go ahead a read it now, but I will summarize the challenge.

Write a web program such that:

  • The first page of the program displays nothing but a text box and a submit button. You enter some arbitrary text and press the submit button, which takes you to …
  • The second page is nothing but a single link labeled “click here”. The URL linked to must not contain the text entered in the first step (i.e. you are not supposed to pass the text as a parameter on the link). Clicking the link takes you to …
  • The third page which contains “You said: XXX” (where XXX is the text you entered in the first step).

Here’s a screen cast demoing my solution to the Arc Challenge. (We will show the code shortly).

Paul’s Solution

Paul has been working on designing Arc, his ideal programming language for the future. Given Paul’s language preferences, it is no surprise that Arc is very Lisp-like. Here is Paul’s solution written in Arc:

  (defop said req
    (aform [w/link (pr "you said: " (arg _ "foo"))
             (pr "click here")]
      (input "foo") 
      (submit)))

Paul points out that the solution is very short and elegant, only 23 nodes in the codetree. I’m sure I don’t quite understand exactly what it is doing (I’d love to see a step by step explanation of the code). He wonders what it would look like in other languages.

Several people have responded with solutions in their own languages. I’ve seen a Smalltalk Solution as well as a Ruby solution (which pretty closely mimics the Arc code from Paul) on the Arc Language Forum page that was setup for responses.

Continuation Web Servers

The Arc challenge is a perfect candidate for a continuation based server solution. And I recalled that Chad Fowler and I had written a demo continuation based server for the Continuations Demystified talk we did at RubyConf 2005. (Look for the “Poor Man’s Seaside Demo in that presentation.) I wondered how easy it be to code up an Arc challenge solution using that code base.

The key to a continuation based server is that it allows the programmer to code in a linear fashion. All the request/response nature of web interaction is completely hidden from you as a programmer.

For example, let’s pretend we wanted to solve the Arc challenge using a terminal and command line rather than a web based solution. How would you write it? Probably something like this:

  text = gets
  puts "click here" 
  gets
  puts "You said: #{text}" 

Simple, linear programming. (OK, printing “click here” is silly in a text program, but you get the idea). You ask a question and read a response. You pause for a click. You then tell the user what the result is.

Ask. Pause. Tell.

Those are our basic abstract operations for this problem. Lets rewrite our text based solution using these abstractions. We’ll put this in a file called “arc_challenge.rb”.

  Conversation.interact do |io|
    text = io.ask
    io.pause("click here")
    io.tell("You said: #{text}")
  end

I’ve introduced three operations (methods) that are provided by an I/O object (let’s ignore the interact line for now). “ask” will ask the user for input, returning the string. “pause” will pause until the user indicates he/she is ready to continue (e.g. pressing return in our command line version). “tell” sends the given string to the user.

So, what does “Conversation.interact” do? It creates the environment where the user have a conversation with the program. The interation is controlled through our ask/pause/tell functions provided by the I/O object passed to the interact block.

Here is an implementation of a text based conversation.

class TextBased
  def interact
    yield(self)
  end

  def ask(prompt=nil)
    print prompt, "  " if prompt
    gets.chomp
  end

  def pause(prompt="")
    print prompt, "  " if prompt
    gets
  end

  def tell(message)
    puts message
  end
end

Conversation = TextBased.new

To run the text based conversation, just require the text. Here’s a demo:

Arc on the Web

Well, anybody can solve the challenge in text mode. How much work do we have to do to get it on the web.

The answer: Zero!

The code Chad and I wrote for Continuations Demystified includes a web-based version of the conversation object that is ready to go. All we have to do is plug it in and run it. No changes are required to our basic Arc challenge solution.

Again, a screen demo:

Yes, we know that although we now have our Arc Challenge on the web, we haven’t quite conformed to the exact requirements of the challenge. We will handle that next.

The Final Arc Solution

The problem is that the current Web based conversation object makes all kinds of assumptions that are not appropriate for the final Arc solution.

In particular, we need to change:

  • Get rid the head line, restart link and other extraneous HTML elements.
  • Don’t keep a running log of the conversation. When you move to a new page, you start from scratch.
  • The “click here” should be a real link, not just a text box where you can press enter.

To get to here, we will have to make some modifications to the conversation web library. It turns out the changes are pretty straight forward. The whole interaction framework is controlled by the Conversation object that implements ask/pause/tell methods. You can see the changes made for the Arc challenge in the “noecho_web_based.rb” file (see the end of this post for the availability of the source code).

The Final Conversation Based Solution

In cased you missed it, here is the Arc Challenge Solution:

  Conversation.interact do |io|
    text = io.ask
    io.pause("click here")
    io.tell("You said: #{text}")
  end

Yep, it’s the exact same file we used for the text based solution. I don’t know if it is as elegant as Paul’s version, but I certainly find it easy to read and understand. (Rerun the very first screen cast in this posting if you want to see it in action again).

If you want to look at the code, there is a tarball available that contains all the continuation server demo code from Continuations Demystified talk, as well as the two new files I added for the Arc challenge. “arc_challenge.rb” is the actually solution and “noecho_web_based.rb” is the conversation library that renders the solution in the style set forth by the challenge.

Enjoy.

 

Formatted: 20-Aug-08 09:02
Feedback: jim@weirichhouse.org