On Oct 31, 2008, at 10/317:08 PM , Howard Lewis Ship wrote:

As I commented in the issue, your last example can take an
EventHandler, not a Object[], and work properly.

See below.

Given that in the majority of cases, these objects (esp. ValueEncoder
and Translator) are automatically provided and therefore invisible to
the (new) developer, what's the issue?

See below.



I think you're missing part of the point: similar APIs but very
different expectations, especially in terms of what to say and how to
say it when things go wrong.


I don't think I'm missing the point at all. Your response in paragraph 1 (EventHandler) is precisely the point. The EventHandler signature was introduced precisely to handle the situation I mentioned where it was occurring in certain situations with the form component (I reported that bug, as well). Before, event handlers were simple to understand: the parameters you receive are the parameters you provide. And then we added a caveat: except when the type is Object[]; then it's a list of strings. And now we've added another caveat: except when the type is EventHandler; that's a "magic" object provided by the framework. And this "magic parameter" is a direct result of the complications of the type-coercion system. It's one more thing to have to learn. Part of the initial appeal of T5 vs. T3 or T4 was, in many aspects, its simplicity. But the framework is gradually becoming more and more complicated, with more and more edge-cases to have to catalogue. Nowhere is that more apparent to me than in Type Coercion. And that is the point. Which brings us to point 2.

Point 2: Given that in the /majority/ of cases these objects are automatically provided, it makes it that much more difficult for a developer to determine what he/she did wrong when coercion fails or when coercion isn't automatic.

Point 3: I grasp the differences in expectations and the differences in contexts. But this argument raises two concerns: 1) It relies on very subtle code nuances that most novice users of the framework will miss, and therefore be confused by.
    2) There are fundamentally still two different processes occurring:
                a) coercion of a value in one type to that same value as 
another type
                b) Handling of problems arising from coercion failures.
3) In some cases, there are even more than two processes, such as Translator, which can also perform preliminary validation.

I agree that the need to handle each of the coercion /failures/ separately is real. I just think that having four different set of services that also do the /coercion/ (even if they ultimately defer to a single system) is the wrong way to handle this.

All arguments notwithstanding, the type coercion issue hasn't driven me from using T5. :) On the whole, it's a beautiful framework. Which is what makes the type-coercion blemish all the more ugly.

Cheers,

Robert


On Fri, Oct 31, 2008 at 2:13 PM, Robert Zeigler <[EMAIL PROTECTED]> wrote:
This thread is a little stale, apologies, but it's been a crazy month, and
this topic deserves more consideration.

As a long time user of Tapestry (since T3) and an early adopter of T5 (since ~T5.0.0), my experience with type coercion has been love/hate. But mostly
hate.
When there was only TypeCoercer to think about, things were much simpler. There was only one possible path of type coercion for the entire system,
and, importantly, things ... just... worked.

With the introduction of:
Translator
ValueEncoder
PrimaryKeyEncoder

We have not one, but FOUR systems of type coercion.

I know that Howard has expressed concern over separation of concerns as being the motivator for the additional conversion interfaces, but I submit that the additional interfaces, in fact, pollute separation of concerns.

Take Translator: it's trying to act both as a type coercion system (value
-> string and back) and as a first-pass validation system.
or:
PrimaryKeyEncoder: acting both as a simplistic batching mechanism (by
stashing the set of keys used into the form, and providing a mechanism to convert those keys back to values en masse) and as a type coercion system
(value -> serializable and back)

I'm not disputing the utility of any of the functions provided by the
various systems. I'm disputing the complexity of the system. For a novice user, it's confusing and adds additional learning-burden that doesn't need
to be there.

Consider, for example, trying to learn a few of the built-in components:

textfield: translator
Context of links: /normally/ value encoder and decoder (quietly). Except when your handler takes a type of Object[]. And then you get back strings, and if you don't explicitly arrange for the ValueEncoder to do the decoding, tapestry tries to use TypeCoercer, which screws up. (See example later).

DateField: I would expect translator, but, hey, no, it's not... it's a
java.text.DateFormat.
Grid: ?? No explicit encoding mechanism provided. Presumably.... value
encoder?
Loop: PrimaryKeyEncoder (<sarcasm>since, clearly, the only thing we're /ever/ going to loop over is a database entity with a serializable primary
key</sarcasm>)
AjaxFormLoop: PrimaryKeyEncoder
Select: PrimaryKeyEnco.... oh... wait... ValueEncoder. Shucks. Just when I thought I was starting to get this straight. Oh, right, unlike with Loop, I
might want to use non-entities in a Select.  Clear as mud.
textarea: translator
textfield: translator


Because I've been using tapestry, and T5, for a long while now, I can
understand the rationale behind each of these choices.  But from the
perspective of a new user, the framework appears schizophrenic.

In fact, the framework doesn't even always "get it right". Take the
following example:

public class SomeComponent {
@Parameter
private Object[] parameters;

@Component(parameters="context=inherit:context")
private ActionLink someAction;

@Inject
private ComponentResources resources;

void onActionFromSomeAction(Object[] parameters) {
    resources.triggerEvent("SomeComponentEvent",parameters,null);
}
}

This seems to be perfectly legitimate code. And is potentially a very powerful paradigm. However, try using "SomeComponent" with a hibernate
entity encoded via the value encoder in the hibernate module, and the
framework explodes. The cause, after some digging, is that the framework encodes values into the url using a value encoder, but the decoding will be done by type coercer (in the above example). There is a workaround: provide your own event context that uses value encoder. But there shouldn't /need/
for a workaround.  Type coercion should just work, with absolutely no
thought from the user. Ironically, this was the case when all we had was TypeCoercer. But the additional interfaces obscure that simplicity and
reliability.

Robert

On Sep 15, 2008, at 9/159:53 AM , Howard Lewis Ship wrote:

On Mon, Sep 15, 2008 at 4:31 AM, Kevin Menard <[EMAIL PROTECTED]> wrote:

I'll test this is the next few days, but don't expect to see anything
problematic.

I guess the whole RC thing snuck up on me though. I'd really like to
see the whole type coercion system looked at again.  I know we've
ping-ponged on this a few times, but the framework has evolved a fair
bit since then and I do think it's worth another look.  As Robert
pointed out in TAPESTRY-2491, we have four ways of doing type
coercion:

Translators

Very tied into form mechanics; not general purpose; used for moving
between strings and arbitrary values.  User input based, with hooks
for client-side validation.





ValueEncoders

Specific to encoding a value into a string, for use inside a URL or
something similar.  Really means for entity values, rather than user
input values.

PrimaryKeyEncoders

Similar to ValueEncoders, but not necessarily a String, just a
Serializable.  Also meant for entity values. Includes a performance
optimization that allows many entities to be efficiently pre-loaded.

TypeCoercers

Very low-level; used in tapestry-ioc, not just tapestry-core. Designed
to be combinable.   Primarily meant for converting parameters from
actual types to desired types but often used as the basis of the other
three.


While I can appreciate the value of each being used in a particular
context, it seems as though the framework is even inconsistent with
its usage at times. Any custom implementation of one almost implies
an implementation of the others and more often than not a simple
adapter is used because the code is so common between them all.  It
strikes me as something that's perhaps over-engineered and the
practicality of a single interface may trump the separation of
concerns benefit. I think it's one of the framework's "gotchas" that
we could address without much hassle.

I still see the simularities as pretty shallow, and the differences as
pretty deep.


If we do decide to keep the system as is, I guess that's fine as well. It's not really broken. But, I would like to see some discussion on
it leading to some decisive path.

--
Thanks,
Kevin



On Sat, Sep 13, 2008 at 7:18 PM, Howard Lewis Ship <[EMAIL PROTECTED] >
wrote:

I've fixed a few more bugs for 5.0.15 and updated the Maven and
src/bin distributions, as previously discussed here.


I've created and uploaded a release of Tapestry 5.0.15, ready to be
voted upon.  This is the release candidate.

The files are uploaded to:

http://people.apache.org/~hlship/tapestry-releases/

and a Maven repository:

http://people.apache.org/~hlship/tapestry-ibiblio-rsynch-repository/

Please examine these files to determine if a new preview release,
5.0.15, is ready.

I've also created a 5.0.15 tag in Subversion:

http://svn.apache.org/viewvc/tapestry/tapestry5/tags/releases/5.0.15/

On a successful vote, I'll move the files from these directories to
the proper distribution directories.

Vote will run for three days; on success I'll move the voted artifacts
into place and send out appropriate notifications.

I'm looking forward to having several weeks of exposure of the release candidate. If no critical, unpatchable errors occur, this can be the 5.0 GA. I'm already looking forward to doing some ambitious things in
the 5.1. release.


Howard M. Lewis Ship: +1 (binding)

--
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





--
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





--
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to