[TransWarp] peak.web.forms (was re: State of the Onion)

Roché Compaan roche at upfrontsystems.co.za
Sun Aug 10 07:28:45 EDT 2003

* Phillip J. Eby <pje at telecommunity.com> [2003-08-09 23:35]:
> At 08:18 PM 8/9/03 +0200, Roché Compaan wrote:
> >* Phillip J. Eby <pje at telecommunity.com> [2003-08-09 17:43]:
> >> >During our
> >> >discussion I thought that we don't really need "field" and that widgets
> >> >can do all that you propose a field should do. I am still not convinced
> >> >this is necessary separation, but I'll have to think about it some more.
> >>
> >> Widgets shouldn't be mutable, but a widget class by itself will not 
> >contain
> >> sufficient parameterization for its instances.  Therefore, there are two
> >> different objects at runtime: an object that describes the fixed 
> >properties
> >> of the widget, and one that describes its state with respect to its 
> >current
> >> usage within the web hit.
> >
> >Why can't widgets manage state or why must they be immutable? They are
> >not really loaded with services. In my mind they have to do very little:
> >render a value and *maybe* store a value. In fact why do they have to
> >keep any state at all - the values they need for rendering come from
> >either the request or an object.
> If they don't have state, then every method called has to have additional 
> parameters passed in, *and* there is a tighter coupling to the external 
> objects.  If a widget looks at the request and the object, it is coupled to 
> both.  Let's say we had a new data source we wanted to load a form from: to 
> do this would require changing every single widget.

What I have been proposing all the time is *exactly* a total decoupling
from the data source. A widget doesn't look at the request or the
object, the *only* thing it does is render a widget with a value that is
supplied to it by the form. The widget doesn't know where the value
comes from.

> Using the form-and-field approach, the form can have methods like 
> 'loadFromRequest()' or 'loadFromObject()', or you can write external 
> functions that manipulate a form and its data.  This is a greatly reduced 
> coupling.

Yes, and it is in methods like these that I see the form supply widgets
with values.

> In general, I prefer to introduce more objects, and have each object 
> responsible for a distinct role.  Such objects are usually much more 
> flexible, reusable, and maintainable.

But this is not a clear cut science - a lot of designs suffer from
layers of unnecessary indirection and abstraction which makes something
that is ultimately flexible impossible to maintain.

> For example, the model I've 
> described so far could readily be adapted to a non-web GUI.  One would 
> simply replace the "field" class with one that would also hold an actual 
> GUI widget, and would get/set the data from the GUI widget instance, rather 
> than keeping the data in itself.

I am not convinced that that GUI widgets will even fit into this
framework. Most GUI frameworks already have the infrastructure we are
talking about in place and I don't think of this as a kind of AnyGUI
form framework - that is redefining the scope massively.

> (Yes, of course there'd be more to such a 
> port than that, but it would still be better than having to rewrite all the 
> widgets so they don't expect to have a REQUEST object!)

Won't be necessary - see my explanation above.

> In short, it's my "design sense" that asserts it be done this way.  There 
> are many logical justifications, as you can see, but I don't actually think 
> about such "background" reasons for things when I design, I just "know" how 
> it should be, and can (sometimes) explain my reasons later.  Such 
> horizontal concerns (things that apply to more than one kind of 
> application) are "background" thoughts for me.

My design sense says, do the simplest think possible to solve the
problem, don't define the problem too widely, and don't be afraid to
build and throw away many prototypes on the way to your goal.

> >> >precisely because there may be differences between "modes". Sometimes
> >> >you just want to remove widgets on the edit form that are visible on the
> >> >add form. If the differences are overwhelming then create another form.
> >>
> >> I'd prefer the objects to control their own destinies here.  If there are
> >> things that should be different, this should be specified by the form or
> >> widget definitions, not by application code at runtime.
> >
> >If it is allowed to manipulate a form instance then I see no problem
> Really, I don't want this to be the normal circumstance.  Writing the last 
> email made it clear to me that forms want to drive the application, not the 
> other way around.

It is not that clear to me. I really think it is common to manipulate
widgets on a form at runtime. Just think of a form where most of the
widgets are the same for all users but some users are presented with
additional widgets. I wouldn't want to create a form for each user just
to cope with this. And what if the whole form is constructed from a
datasource at runtime. Let's say I allow users to add custom fields to a
form or let them build new forms for editing objects all together.
Surely a separate framework for this shouldn't be necessary.

> Maybe I want too much.  :)  But I generally find it better to know what 
> direction I'd like to go, because I can always scale down the vision if the 
> budget doesn't allow it, but it's harder to change something that's already 
> built with a more limited scope in mind.  Of course, this has to be 
> balanced against YAGNI-ism, but adaptation offers a powerful YAGNI weapon.

I find its easier to broaden scope than to scale down as long as you
have objects with clearly defined responsibilities.

> For example, suppose we made classes that corresponded to "abstract" 
> widgets, and then used adaptation to turn them into HTML widgets, wxPython 
> widgets, etc.?  Not only that, but we could make the adaptation specific to 
> an individual form, using protocols.Variation.  Anyway, one reason I want 
> to look at XForms again, is that they had a specification/model for a set 
> of abstract widgets that could then be mapped to specific widget 
> implementations using CSS and the like.  I think that in our case we could 
> use pwt:define's in place of CSS.
> An interesting thought - many GUI systems these days use XML as a 
> basis...  besides HTML, there's also wxPython's XML resource format, and 
> Mozilla's XUL.  All of these can be rendered with peak.web.templates, so 
> there do seem to be some intriguing possibilities for future GUIs.
> >I think I should just make a prototype so that we have something
> >concrete to work from. I find it difficult and frustrating to only talk
> >about this.
> Feel free.  I, on the other hand, don't know enough yet about what I want, 
> to make anything.  From my POV, this is all still far-off brainstorming, 
> similar to where the existing peak.web stuff was a few months ago.  What we 
> ended up with in developing the existing peak.web tools looks *very* 
> different from any of the things Ty and I first talked about, so I'm glad I 
> didn't rush to build any of the things we first talked about.
> But, if you want a forms framework *now*, rather than possibly waiting a 
> few months, then rolling your own is indeed a good plan.  Meanwhile, I've 
> been wondering when XForms might become important/relevant to 
> peak.web.  Now that I've realized I'm trying to reinvent it, perhaps I 
> should just go see if we can port it instead.  :)

I don't need it *now*, but I see building prototypes as part of the
brainstorming process and I think it will help focus our discussion more
and clarify some of the ideas we throw around.

I have a very good idea of what I want and it is an area where I
can make a direct contribution to peak.web, but I want to make that
contribution in the PEAK idiom.

Roché Compaan
Upfront Systems                 http://www.upfrontsystems.co.za

More information about the PEAK mailing list