Avi Bryant replied with a few questions to my last post about continuations. I’ll pop back some answers in a minute.
My biggest issue with continuation based programing is not the details of how it works. Programming with web sites using continuations seems to put the application in the drivers seat. Letting the application drive is easier to program for (See, I admitted it. :) And I do grok that aspect of continuations). But, this goes utterly against the most basic underlying strength of world wide web - that the web is as stateless as possible. That statelessness encourages many of the positive ways we work on the web and also encourages disparate data from totally different sources to be tied together.
Let’s take a small project I was working on last week. It’s an online questionnaire of “professional skills” done for the HR guys at that company so they can give up attaching word docs to emails. On the web admin back-end, and HR guy can pick a person, and view that persons competed data (the questions of which are customized to the jobs the person is interested in and the type of “employee” the person is.)
So, written to my understanding of continuations, we would have something like:
h4. Continuation style:
def personDetailsApp person = get-person() showPersonDetails(person) end
h4. “Stateless” style:
- personPicker.rb
#passing in where the picker should go to showPersonPicker("personDetails.rb")
- personDetails.rb
#person coming from request vars showPersonDetails(person)
The HR user pops in, picks a person, and gets their details. In both sets of code all is easy and well. This is a really trivial example, maybe too trivial.
But in real life on this project, that simple continuation style code would not have worked for me. First, HR guys need to email around links to a persons info. Also there was another, non web based, HR app that we quickly modified so that from a person’s details in the app, you could push a button and their web browser would launch pointing at that person’s questionnaire. Because of the stateless way the site was programmed (except for authentication), both of these required no modifications to the sites code at all. Heck, someone could spend five minutes and make a javascript bookmarklet that would let an HR guy highlight someone’s name on the internet and pull up their info.
Logically, there is no reason why picking a person on a web based form must proceed viewing their details. By using the stateless style, any program, web based or not, my code or not, that can generate a url with the users name in the query string can direct an authorized user to the person’s details.
It is this disconnect between individual “pieces” on the web that allows so much rich intertwinglyness.
With continuations, at least as far as I can see, this is lost and has to be explicitly added? And explicitly adding “statelessness” would defeat the purpose of continuations?
Now you guys are smart people, and you use and love continuations, therefore there is probably still perhaps something I’m missing. Any pointers on where to look for it?
In Avi’s comments on his post, he says “managing flow (continuations vs. state machines)”. Rather than a state machine, what I am usually trying to build is an application with very little required flow - almost stateless. (Yes, you have to register to use the system. And if you visit a page without logging in, it lets you log in, and then puts you back to the page you first requested.)
I do agree that continuations would be better than stateless for multipage forms, but I don’t usually use multipage forms. :P
The above in this post is the major thing I see with continuations. The following is just a few replies to Avi’s post and is a side show from my main quest for wisdom.
bq. What’s the first page the user sees? How obvious is this?
There is not one. That’s the whole point. The first page the user sees depends on wether the data was submitted or not. If they did not submit anything, they get a form that allows them to. If something external to this code is putting the amount and rate data in, then they see the result.
bq. What’s the order of pages the user sees after that? If this isn’t fixed, what determines the order?
Again, that’s the entire point. :P If incorrect data is submitted, they get a page displayed that lets them fix it. If good data, they see the answer.
bq. How would I change the order if I wanted to? If say, I decided I wanted to ask for amount first, and then rate, how many different pieces of code (and templates!) would I have to change?
I’m cheating, and asking both at once, as you mentioned in the comments. :P So their is no order.
bq. Say I had to ask for 10 different variables instead of 2. How would I abstract the validation code so that I could reuse it easily?
My orginal code is indeed ugly. It follows the principle of Do The Simplest Thing That Could Possibly Work. Real code would have the error checking inside a calculator object. and reuse of validation methods would be easy. My old example could be rewritten as:
$amount = $_REQUEST['amount']; $rate = $_REQUEST['rate']; $action = $_REQUEST['action']; if($action == "calc"){ $calc = new interestCalculator(); $calc->setData($amount, $rate); if($calc->validData()){ showResult($calc->answer()); }else{ //Passing in an array of errors to be displayed showForm($calc->getErrors()); } }else{ showForm(); }
But of course, I am still comparing using one form to Chris’ code using multiple ones.
(Remember, the second half of this post is minor. First part is the meat of the matter.)