Christopher Oliver wrote:

Vadim Gritsenko wrote:

Christopher Oliver wrote:

Local variables are shared between continuations. This behavior is as in Scheme.



Yeah, I kind of got that part (that they are shared). What can be done about it? It really prevents lots of usecases, or makes it real headache. Any advice? Unrolling all the loops is kind of ugly, if even possible.


What is the use case causing the problem?


Ok, here is simple one. Forms wizard for editing any XML/bean containing repeating information, with back/forward navigation, and navigation bar to jump to any previous page. For a concrete example of the usecase, let's look at editing family information, and information about each member. First page, "family", will have repeater which you can populate with names of family members. After filling out first page, let's go through each member and show "member" page. This can look like:

// Shared across continuations
var bean = new Packages.my.Family();

function app() {
   var back; // Pointer to previous form
   back = step (bean, "family");
   for (var i = 0; i < bean.members.length; i++) {
       back = step (bean.members[i], "member", back);
   }
   back = step(bean, "done", back);
}

function step(bean, formID, back) {
   // Capture continuation which can be used to re-display this form
   var c = capture();

// Init form, binding, etc... Add "back" to bizData.

    form.load(bean);
    form.showForm(formID + ".display", bizData);
    form.save(bean);

   return c;
}


(navigation bar stuff is ripped out of this example) Note that "bean" variable is shared accross continuations, so you can jump back and forward and edit this same bean till you are satisfied with it. But the "i" variable declared in the app() function makes it impossible to get back to any of the "member" pages, because once you click next, you'll be presented with the "done" page (or last visited "member" page), instead of the next "member" page.


Note also how "back" is passed back and forth; this trick allows to have own "back" for each continuation. Following same pattern, I guess loop could be rewritten to:

function app() {
   var back; // Pointer to previous form
   back = step (bean, "family");
   for (var i = 0; i < bean.members.length; i++) {
       var xxx = step (bean.members[i], "member", back, i);
       back = xxx["back"];
       i = xxx["i"];
   }
   back = step(bean, "done", back);
}

function step(bean, formID, back, i) {
   // Capture continuation which can be used to re-display this form
   var c = capture();

// Init form, binding, etc... Add "back" to bizData.

    form.load(bean);
    form.showForm(formID + ".display", bizData);
    form.save(bean);

   return { "back" : c, "i" : i };
}

But this becomes *really* ugly, especially as number of variables grows... Any suggestions?

I'm thinking... Is it a good idea to capture state of all local variables, and share only global variables (if it's possible)? Will it break something else?


PS My capture() looks like this:


function capture(back, name) {
// IDEA: How about storing "back" in continuation itself: c.back = back;
// Does not fly: FOM_WebContinuation does not provide access to Continuation, and WebContinuation is not Scriptable.
var wc = Packages.my.FOMHelper.mark(cocoon, new Continuation(), back);
return wc;
}



PS I promise to write good woody sample if this issue is resolved ;-)


Vadim



Reply via email to