You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Ovidiu Predescu <ov...@cup.hp.com> on 2002/01/03 02:27:09 UTC

Re: [RT] Managing Flow and Resources

Hi Judson, and Happy New Year!

[I've Cc-ed the mailing list as well.]

I hope this reply does not come too late ;-), but I left on holidays
the day after you sent the message, and didn't have time to respond to
it.

On Thu, 20 Dec 2001 13:28:57 -0600, Judson Lester <ju...@irev2.com> wrote:

> On Wednesday 19 December 2001 04:17 pm, you wrote:
> > On Wed, 19 Dec 2001 13:41:58 -0600, Judson Lester <ju...@irev2.com> wrote:
> <snip/>
> > > > But at the same time, would it be even better if you didn't have to
> > > > think about it altogether and program like you'd do for your command
> > > > line?
> > >
> > > Being able to avoid the management of the session would help a lot.
> > > And yes, minimizing the amount of new pardigm to be learned would
> > > make everything gravy.  Putting desktop developers in a position to
> > > quickly be coding web apps is veryt attractive.
> >
> > The biggest difference from a normal programming language are these
> > hidden non-local exits, which are somewhat equivalent to a goto
> > instruction. It's quite a tricky, yet powerful mechanism.
> 
> I'm not so sure it's very tricky.  It seems to me that it ought be presented 
> more as a special 'System.exit().'  And for that reason, I wonder if there 
> ought to be a 
> 
> send-response-page(...) 
> and
> send-exit-page(...)
> 
> or something, on the grounds that it distinctly seperates an exit point and 
> an 'instruction.'  This raises the assocaited question: ought not "response 
> pages" have a different structure from an "exit-page"?  And how?  Or is every 
> send-page() call a potential exit (a reasonable assumption, since it 
> might/should include a navigation option, which would break the flow)?  And 
> what about the reverse: is every send-page(exit.xml) a potential response 
> returned?
> 
> Answering my own question: it seems most sensible that every
> send-page(query.xml) be a potential exit (with the issues of clean
> up variables, etc.) and that a send-page(exit.xml) not be allowed to
> return (and so should be a different call: to send-exit-page(...)
> for instance).
> 
> It's actually the send-page(query.xml) call that concerns me more, since I 
> think any semantic component of the flow-language will need to be considered 
> in the following context: "What if this is used across a send-page(...) and 
> the send page doesn't return?"  I'm reminded of finally clauses in Java 
> exception handling.

I don't think we can have a distinction between an exit page and a
"normal" page. In fact you can have pages that have both exit links,
and returning links. The distinction between the pages in not in the
way they are invoked (send-page vs. send-exit-page), but in the
information encoded in the page, which is and _should be_ external to
the control flow logic.

An application developer should not be concerned with "What if this is
used across a send-page(...) and the send page doesn't return?". It is
very possible that the user may not hit the "continue" URL on the
page, thus doing a non-local exit in a different context of the
application. At some point the application framework will invalidate
and garbage collect the continuation object, making the URL reference
invalid.

That's why I said the model is very much different than what we are
used to, and may be difficult to grasp.

> <snip>Because someone has too</snip>
> > > Another, equally valid question is what will emphasize SoC, and keep
> > > business logic in its place (with the subquestion: what relationship
> > > do flow and business logic have?  I propose that they are not
> > > identical, and that their intersection should be limited to flow's
> > > dependance on business logic)?  If variable assignment must come
> > > from Java code, because flow units can't return anything, it becomes
> > > very difficult to use flowmaps for business logic.
> >
> > I argue that we do need to have functions that return values. I've
> > shown in a previous message how such functions are useful.
> >
> > The distinction between flow and business logic is a bit blurry, and I
> > would say it's probably not a good idea to remove functionality from
> > the language just to enforce separation of concerns. Why should a
> > calculator application for example need to use Java to do it's logic,
> > when the flow logic can do additions and substractions? I think we
> > should let the developer choose the right mix he/she wants. This may
> > lead to messy programs in the beginning, but with the right patterns
> > explained to people, I think it's easier for people to write using the
> > right mix.
> >
> 
> To borrow an aphorism: FS.  I'd be very leery of a system where a
> language designed to control the flow of complex requests could be
> used to easily implement a calculator.  The power of the best
> systems comes from the simplicity and ease of use.  I'd say it's
> definitely not a good idea to add functionality that doesn't
> directly serve the purpose of the language because it might be
> useful.
> 
> <aside>If it were hard, I could cope.  For an example of what I
> please qv Inform and the Z-Machine.  Short version: Inform is a
> language for writing Adventure style 'interactive fiction', but if
> you're willing to code directly in the assembly language of the
> ZMachine, you can get it to play Tetris.</aside>

;-)

That's right. Nevertheless, I think it's much harder to come up with a
restricted language which has everything you need to do _only_
business logic, than to have a powerful language. For the later, it's
enough to translate that language to Scheme. For the former, you need
quite a bit of work to remove the "unnecessary" functionality out of
the language. But then how do you know you're not limiting the
expressiveness and power of the language by doing so? A user using the
system in a different way than you expected might need that little
thing you've decided is not important.

> > > > If, at the end, it comes out that it's easier to use sessions, we'll
> > > > happily forget about continuations.
> > >
> > > Reflection leads me to ask, though: is the idea I'm suggesting of
> > > continuation-based "flow units" (I have a hard time thinking of them
> > > as "functions" without returns) differ significantly from FSM/goto
> > > programming?  The difference I can see is that state transitions are
> > > seperated from input, which is fairly significant in my mind, and
> > > almost exactly what is wanted.
> >
> > The way I see the non-local exits of the functions with no return, is
> > that they take the program out the current context. It's like doing a
> > system.exit(), and starting from a different place. It is more like
> > forcing the program take on a different flow, than moving to a
> > different state.
> 
> This is a much clearer and, I think, more accurate analogy than likening 
> non-local exits to goto statements.  You get one last gasp of a message 
> ("exit(NULLPOINTERERROR); == send-exit-page("sorry-couldnt-register.xml");) 
> and then the overarching System takes control again.
> 
> > Or at least this is how they should be used, and I believe you can
> > enforce this model by giving programmatic access only to the current
> > continuation, not to the past ones. This way the programmer cannot
> > jump to an arbitrary existing continuations, only to the last one,
> > which will resume the execution of the program. This avoids the goto
> > stigma, where you can have jumps to different parts of the program.
> 
> For clarity, the equivalent of (call/cc thunk) is send-page(xyzzy.xml); right?

Yes. send-page() needs to associate the continuation object with a
URL, so that when the request is sent back, the system can find the
continuation object. It looks like this:

(define current-continuations (make-hash-table))

(define send-page
  (lambda (page pipeline object-model)
    (call/cc
     (lambda (k)
       (let ((url (k->url k)))
	 (hash-put object-model 'k-url url)
	 (hash-put current-continuations url k)
	 (cocoon/process page pipeline object-model)
	 (suicide))))))

(define handle-request
  (lambda (request)
    (let* ((url (request-get-url request))
	   (k (hash-get current-continuations url)))
      (if k
	  (k request)
	  (cocoon/process "error.xml" "error-pipeline" nil)))))


The 'current-continuations' hash table maintains an association
between URLs and continuation objects.

The send-page function takes as arguments a page, a pipeline and an
object-model hash table, which contains data to be put in the
generated page during the initial content generation. The function
passes its continuation to a function which generates a new URL for
it, puts the URL <-> continuation association in the
'current-continuations' hash table, processes the output page through
the pipeline, and then kills the current executing thread. The URL of
the continuation is passed to the generator of the pipeline, so it can
incorporate it in the generated page (this URL will point to the rest
of the computation).

When a request is received from the client, the continuation
associated with the URL is obtained and invoked. This will effectively
resume the computation after the corresponding send-page().

In practice, the handle-request will be invoked by the sitemap
logic. Each sitemap will have a hidden first entry for obtaining a
continuation from a given URL. I'm currently working on having the
sitemap logic completely implemented in Scheme, so that things are
easier (for me ;-) to write.


Greetings,
-- 
Ovidiu Predescu <ov...@cup.hp.com>
http://orion.rgv.hp.com/ (inside HP's firewall only)
http://sourceforge.net/users/ovidiu/ (my SourceForge page)
http://www.geocities.com/SiliconValley/Monitor/7464/ (GNU, Emacs, other stuff)

---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


RequestDispatchers in xsp

Posted by "Årun.Ñ" <ar...@eximsoft.com>.
Hi,
        Is there any way to use request dispatchers in my xsp page. I am
using cocoon 2 and there is a problem with the cocoons wrapper classes for
request .... to get the requestDispatcher. I cannot use the redirect
approach as there are lot of disadvantages of that like,  it is a client
pull another hit to server, network traffic, as it becomes a second request
i will not be able to get the parameters with the previous request etc ....

right now i have added a method in HttpRequest and HttpResponse and am using
the dispatcher.. will it give me any problem in future.. ????
nobody in the userlist bothered to answer ... can any of u here please throw
some light on this.

javax.servlet.RequestDispatcher rd =
((org.apache.cocoon.environment.http.HttpRequest)request).getRequestDispatch
er("hello.xml");
rd.forward(((org.apache.cocoon.environment.http.HttpRequest)request).getHttp
ServletRequest(),((org.apache.cocoon.environment.http.HttpResponse)response)
.getHttpServletResponse());



thankx in advance
Arun.N



---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Re: [RT] Managing Flow and Resources

Posted by Judson Lester <ju...@irev2.com>.
On Wednesday 02 January 2002 07:27 pm, you wrote:
> Hi Judson, and Happy New Year!
>
Back atcha, Ovidiu!  All the best in 2002!

> [I've Cc-ed the mailing list as well.]
I've been following the list with some ardor, so I'll be CCing you with my 
response.


> > > > > But at the same time, would it be even better if you didn't have to
> > > > > think about it altogether and program like you'd do for your
> > > > > command line?
> > > >
> > > > Being able to avoid the management of the session would help a lot.
> > > > And yes, minimizing the amount of new pardigm to be learned would
> > > > make everything gravy.  Putting desktop developers in a position to
> > > > quickly be coding web apps is veryt attractive.
> > >
> > > The biggest difference from a normal programming language are these
> > > hidden non-local exits, which are somewhat equivalent to a goto
> > > instruction. It's quite a tricky, yet powerful mechanism.
> >
> > I'm not so sure it's very tricky.  It seems to me that it ought be
> > presented more as a special 'System.exit().'  And for that reason, I
> > wonder if there ought to be a
> >
> > send-response-page(...)
> > and
> > send-exit-page(...)
> >
> > or something, on the grounds that it distinctly seperates an exit point
> > and an 'instruction.'  This raises the assocaited question: ought not
> > "response pages" have a different structure from an "exit-page"?  And
> > how?  Or is every send-page() call a potential exit (a reasonable
> > assumption, since it might/should include a navigation option, which
> > would break the flow)?  And what about the reverse: is every
> > send-page(exit.xml) a potential response returned?
> >
> > Answering my own question: it seems most sensible that every
> > send-page(query.xml) be a potential exit (with the issues of clean
> > up variables, etc.) and that a send-page(exit.xml) not be allowed to
> > return (and so should be a different call: to send-exit-page(...)
> > for instance).
> >
> > It's actually the send-page(query.xml) call that concerns me more, since
> > I think any semantic component of the flow-language will need to be
> > considered in the following context: "What if this is used across a
> > send-page(...) and the send page doesn't return?"  I'm reminded of
> > finally clauses in Java exception handling.
>
> I don't think we can have a distinction between an exit page and a
> "normal" page. In fact you can have pages that have both exit links,
> and returning links. The distinction between the pages in not in the
> way they are invoked (send-page vs. send-exit-page), but in the
> information encoded in the page, which is and _should be_ external to
> the control flow logic.

I agree with this, mostly, but I suspect that either you've misunderstood the 
distinction I'm making, my understanding of the distinction is shifting as I 
understand these ideas better, or I was unclear in my position.

Certainly, a send-page(...) might never return, but a send-exit-page(...) 
<emp>will</emp> never return.  And while this is encoded in the page that's 
sent quite clearly, this hardly helps when reading the code.  From the 
standpoint of someone reading this code, it's difficult to say whether a 
send-page(...) correctly terminates a flow of execution, whereas a 
send-exit-page(...) does this exactly.  Consider the gcc error about an 
execution flow without a return value...I think this behavior would be very 
valuable to emulate, but very difficult to do without an equivalent contruct 
to "return expr;".  In fact, since any Transformer in the pipeline might 
suddenly decide to add a back-to-flow link, you can't really guarantee that a 
specific send-page(...) won't come back.  From the standpoint of a flowmap 
checker, how can I tell that a flowmap is correct if send-page(...) is at the 
end of a flow?

> An application developer should not be concerned with "What if this is
> used across a send-page(...) and the send page doesn't return?". It is
> very possible that the user may not hit the "continue" URL on the
> page, thus doing a non-local exit in a different context of the
> application. At some point the application framework will invalidate
> and garbage collect the continuation object, making the URL reference
> invalid.

I didn't mean that a developer should worry about send-page(...) returning.  
I think the language designer(s) should worry about this.  I just think it 
would be particularly nettlesome, for instance, if the flow language gives 
access to resource allocation and send-page(...) makes it impossible to 
deallocate.  The best solution I can see is that somewhere the Cocoon 
framework releases those resources when the user's session expires.  That 
could be very problematic in the case of a db connection, for instance, since 
you suddenly need several orders of magnitude more db connections than you 
did.  The solution, it seems, is that the flowmap can't allocate database 
connections directly, which probably means that it can't do db lookups 
itself, or that there are blocks of some sort that forbid the use of 
send-page(...) within them.

> That's why I said the model is very much different than what we are
> used to, and may be difficult to grasp.

I think this is probably the strongest possible argument for rethinking the 
usual positions we take on formal programming languages.  The flowmap is very 
different from a traditional programming language because it solves a 
different problem.  

The fundamental difference in the problem is that the program will be 
interacting directly with a user, who will thoughtlessly shift our exectution 
point around, and wants to do repetitive tasks as little as possible, rather 
than interacting with the processor, who moves forward unless we say 
otherwise, and loves doing things over and over and over and...

The fundamental differences in the structure of the languages then, it seems 
to me, is that where a traditional language wants closures and functions that 
return, because when you're done with this task, you want to go back so you 
can do it again, a flow language wants to break things up in to steps and 
move between them, going back usually only because the user want's to, and 
without regard to what effort might be lost.  

>
> > <snip>Because someone has too</snip>
> >
> > > > Another, equally valid question is what will emphasize SoC, and keep
> > > > business logic in its place (with the subquestion: what relationship
> > > > do flow and business logic have?  I propose that they are not
> > > > identical, and that their intersection should be limited to flow's
> > > > dependance on business logic)?  If variable assignment must come
> > > > from Java code, because flow units can't return anything, it becomes
> > > > very difficult to use flowmaps for business logic.
> > >
> > > I argue that we do need to have functions that return values. I've
> > > shown in a previous message how such functions are useful.
> > >
> > > The distinction between flow and business logic is a bit blurry, and I
> > > would say it's probably not a good idea to remove functionality from
> > > the language just to enforce separation of concerns. Why should a
> > > calculator application for example need to use Java to do it's logic,
> > > when the flow logic can do additions and substractions? I think we
> > > should let the developer choose the right mix he/she wants. This may
> > > lead to messy programs in the beginning, but with the right patterns
> > > explained to people, I think it's easier for people to write using the
> > > right mix.
> >
> > To borrow an aphorism: FS.  I'd be very leery of a system where a
> > language designed to control the flow of complex requests could be
> > used to easily implement a calculator.  The power of the best
> > systems comes from the simplicity and ease of use.  I'd say it's
> > definitely not a good idea to add functionality that doesn't
> > directly serve the purpose of the language because it might be
> > useful.
> >
> > <aside>If it were hard, I could cope.  For an example of what I
> > please qv Inform and the Z-Machine.  Short version: Inform is a
> > language for writing Adventure style 'interactive fiction', but if
> > you're willing to code directly in the assembly language of the
> > ZMachine, you can get it to play Tetris.</aside>
>
> ;-)
>
> That's right. Nevertheless, I think it's much harder to come up with a
> restricted language which has everything you need to do _only_
> business logic, than to have a powerful language. For the later, it's
> enough to translate that language to Scheme. For the former, you need
> quite a bit of work to remove the "unnecessary" functionality out of
> the language. But then how do you know you're not limiting the
> expressiveness and power of the language by doing so? A user using the
> system in a different way than you expected might need that little
> thing you've decided is not important.
>

I think that's true only if you're starting with a specific language to start 
with.  I frankly am yet to be convinced that this flow language needs to be 
any more complicated than make or ant (and the "we provide the flow control, 
actual work is done by others" approach of those 'little languages' is what 
makes me think of them.)  With that in mind, I don't see the need for a 
powerful language, and I don't see the need to retask an existing language 
(XML or Java or ECMAScript, for instance) since the argument there is that 
"if you already program in Ada, this is easy!"   Having added only the 
semantics to the language that are neccesary (and I think that's an easier 
task than stripping things out), you still only have the task of translating 
the language into Scheme (or interpreting for Java, or whatever.)

> > > > > If, at the end, it comes out that it's easier to use sessions,
> > > > > we'll happily forget about continuations.
> > > >
> > > > Reflection leads me to ask, though: is the idea I'm suggesting of
> > > > continuation-based "flow units" (I have a hard time thinking of them
> > > > as "functions" without returns) differ significantly from FSM/goto
> > > > programming?  The difference I can see is that state transitions are
> > > > seperated from input, which is fairly significant in my mind, and
> > > > almost exactly what is wanted.
> > >
> > > The way I see the non-local exits of the functions with no return, is
> > > that they take the program out the current context. It's like doing a
> > > system.exit(), and starting from a different place. It is more like
> > > forcing the program take on a different flow, than moving to a
> > > different state.
> >
> > This is a much clearer and, I think, more accurate analogy than likening
> > non-local exits to goto statements.  You get one last gasp of a message
> > ("exit(NULLPOINTERERROR); ==
> > send-exit-page("sorry-couldnt-register.xml");) and then the overarching
> > System takes control again.
> >
> > > Or at least this is how they should be used, and I believe you can
> > > enforce this model by giving programmatic access only to the current
> > > continuation, not to the past ones. This way the programmer cannot
> > > jump to an arbitrary existing continuations, only to the last one,
> > > which will resume the execution of the program. This avoids the goto
> > > stigma, where you can have jumps to different parts of the program.
> >
> > For clarity, the equivalent of (call/cc thunk) is send-page(xyzzy.xml);
> > right?
>
> Yes. send-page() needs to associate the continuation object with a
> URL, so that when the request is sent back, the system can find the
> continuation object. It looks like this:
>
> (define current-continuations (make-hash-table))
>
> (define send-page
>   (lambda (page pipeline object-model)
>     (call/cc
>      (lambda (k)
>        (let ((url (k->url k)))
> 	 (hash-put object-model 'k-url url)
> 	 (hash-put current-continuations url k)
> 	 (cocoon/process page pipeline object-model)
> 	 (suicide))))))
>
> (define handle-request
>   (lambda (request)
>     (let* ((url (request-get-url request))
> 	   (k (hash-get current-continuations url)))
>       (if k
> 	  (k request)
> 	  (cocoon/process "error.xml" "error-pipeline" nil)))))
>
>
> The 'current-continuations' hash table maintains an association
> between URLs and continuation objects.
>
> The send-page function takes as arguments a page, a pipeline and an
> object-model hash table, which contains data to be put in the
> generated page during the initial content generation. The function
> passes its continuation to a function which generates a new URL for
> it, puts the URL <-> continuation association in the
> 'current-continuations' hash table, processes the output page through
> the pipeline, and then kills the current executing thread. The URL of
> the continuation is passed to the generator of the pipeline, so it can
> incorporate it in the generated page (this URL will point to the rest
> of the computation).
>
> When a request is received from the client, the continuation
> associated with the URL is obtained and invoked. This will effectively
> resume the computation after the corresponding send-page().
>
> In practice, the handle-request will be invoked by the sitemap
> logic. Each sitemap will have a hidden first entry for obtaining a
> continuation from a given URL. I'm currently working on having the
> sitemap logic completely implemented in Scheme, so that things are
> easier (for me ;-) to write.

Aha, Ovidiu!  I've found you out: you're one of those Scheme zealots trying 
to push your functional programming religion on the rest of us!  

Seriously, much as I love Scheme and Lisp (such relaxing languages...), it 
seems like, from the above, that Scheme may be, as we say here in America, a 
long run for a short slide.  What advantage is there to translating a 
language into Scheme to have it interpreted by Java?  Why not interprete the 
language directly?  As far as continuations go, it doesn't seem that the 
URL-execution point hash table would be overly difficult to implement 
directly.  

Judson









---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org