[Bese-devel] Follow up to "New tutorial typos"

szergling senatorzergling at gmail.com
Thu Feb 26 09:21:02 UTC 2009


Sorry if my previous email did come through, but I've been getting no
end of trouble from common-lisp.net mailing lists. Lost emails, no
"own posts" (yes, it's ticked in the "mailing list membership
configuration" panel), etc. This time, it looks as if my last post was
truncated, so I'm including it again as an attachment. Very sorry for
the mess. (but I don't think it's my fault). Any tips on managing
using all these mailing lists? I don't even subscribe to that many...

Apologies if this seems like a rant. I'm frustrated. You don't even
deserve this... it's not your fault.
-------------- next part --------------
Hi again, sorry for the long delay in this reply. I've been slowly
hacking (on other things too) and reading UCW's source...

>2009/1/15 szergling <senatorzergling at gmail.com>:
>> Some further questions:
>>
>> In the YACLML section,
>>
>> *** YACLML: Yet another common lisp markup language.
>>
>> (defun render-message-form (name)
>>  (<:form
>>   (<:as-html "Enter a new message:")
>>   (<:input
>>    :type "text" :name (string-downcase name))
>>   (<:submit)))
>>
>> What does the form submit to? That is, what gets generated in the
>> <form> html tag?  <form action='??' action='??'>
>
>The <:FORM tag is identical in every way to the HTML <FORM/> tag. HTML
>specifies where this form is submitted, not UCW or YACLML.

Actually, I was wondering about something like

<form method="post" action="post_message.ucw">

or some such. An examination of the html produced (see example) shows
that this is not necessary. I wasn't aware (my own ignorance) that a
form without the html method & html action fields will still work
(submits to "self", so to speak). Then again, in
http://www.w3.org/TR/html401/interact/forms.html#h-17.3, the html form
action field seems to be "#REQUIRED" and "User agent behavior for a
value other than an HTTP URI is undefined."

<form
  >Enter a new message:<input name="message" type="text"
  /><input type="submit"
  /></form
>


All this is probably offtopic for a UCW discussion.

>> ----------
>>
>> *** Frames, Actions, Callbacks.
>>
>> "A frame represents an individual hit, a page rendered... an
>> interaction with the application."
>>
>> I still don't understand what a frame is. It doesn't seem to be
>> visible to a UCW user, so perhaps it should come later, since it
>> describes UCW internals? That is, show what the user would write
>> first, then show what the written code does behind the scenes.
>
>Ok, let me put it to you this way. You hit an entry point. there is
>only one link on it. You open that link twice in two new windows, and
>you now have three frames. Each frame represents a unique browser
>url.. a window. Without frames we'd only have sessions in which to
>store callbacks and actions... and that would mean only one browser
>window would actually work.. and you'd see weird errors when you clone
>windows, hit the back button, or whatever.
>
>Does that makes sense?

Thanks for the clarification. So frames are a way to represent state
in the presence of continuations. Can we think of them as, in effect,
"tree-like" structures that keep track of "immutable" state? For
example, instead of mutating state, we represent the evolution of a
counter as we increment it thus:

[The trees below are represented by lists: car <=> parent node, cdr
<=> leaf nodes, except lists, which are sub-trees. The evolution of
the values, and the tree representing them, as shown together with
some commentaries.]

1. (1) 

The initial value seen in some browser window

2. (1 2) 

The value is incremented to 2. The original 1 is still available
because we might go back. Another possibility, is that 2 might have
been a simultaneous increment & clone operation (as when someone
middle clicks on an "Increment" link), so now, we have the original
window showing 1, and a new window showing 2.

3. (1 2 2) 

Possible causes: the browser window/tab showing the 2 is cloned. Or,
the browswer window showing 1 is incremented, or "increment &
cloned"... etc

4. (1 (2 3) 2)

The value in the window showing 2 is incremented.

5. (1 (2 (3 4)) 2)  

The value in the first window (now showing 3) is incremented again.

6. (1 (2 (3 4) 3) 2)

From the first window, we click back twice, back to the screen showing
the value 2, and increment again. This results in a new branch of
values... (among other possibilities, etc)

So after step 6, the tree looks like:

1
|
+- 2
|  |
|  +- 3
|  |  |
|  |  +- 4
|  |
|  +- 3
|
+- 2

There is only 1 counter (1 state), but each frame stores a
"alternative" value of the counter. Backtracks are used to
save/restore the value from any required branch into that counter.

So, have I got the right idea? I've been trying to figure all this out
from the source, but am still trying to work out backtracking slots
(the mop bit).

;;--------------------

Now, I am also confused about another thing. Suppose a component
displays an action that does not 'answer', but has side-effects
instead. I'm not sure why this action would repeatedly get called even
when the component display is only refreshed and not clicked on.

Here is a simple example to illustrate:

(defcomponent refresh-demo ()
  ((value :initform 0
          :accessor component-value)))

(defmethod render ((c refresh-demo))
  (<:p "Current value is: "
       (<:as-html (component-value c)))
  (<ucw:a :action (incf (component-value c))
       "Increase value"))

(defentry-point "refresh.ucw" (:application *example-application*)
    ()
  (<:p "Refresh test")
  (call 'refresh-demo))


It is similar to the counter (increment/decrement) example. We have a
value which can be increased by clicking on our incf action. After the
first click on the hyperlink, I see a new incremented
value. Subsequent clicks on the hyperlink also increment the value, as
expected. However, clicking on "refresh" in my browser (after the
first increment action) also results in the value being incremented. I
expect to see the same value, since no action has been carried out,
really.

I can sort of see why this must be so I guess, since there's some "URL
propagation-like" stuff, so even a refresh is a new "hit" causing an
action. However, this also works with form actions, and seems wrong,
since nothing has been posted...

(defmethod render ((c refresh-demo))
  (<:p "Current value is: "
       (<:as-html (component-value c)))
  (<ucw:form
   :action (incf (component-value c))
   (<:input :type "submit" :value "Increase value")))

Again, try to increment once (clicking on the form button), then just
use refresh. So what have I done wrong here? Would appreciate any
pointers.





More information about the bese-devel mailing list