You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Robert Zeigler <ro...@scazdl.org> on 2008/10/31 22:13:12 UTC

Re: Type Coercion Issues

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 <ni...@gmail.com>  
> 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  
>> <hl...@gmail.com> 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: dev-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>
>>
>
>
>
> -- 
> Howard M. Lewis Ship
>
> Creator Apache Tapestry and Apache HiveMind
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org


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


Re: Type Coercion Issues

Posted by Francois Armand <fa...@linagora.com>.
Kevin Menard wrote:
> It seems this issue is going nowhere.  All I can say at this point is that I
> agree with Robert's sentiments.  Despite the lack of strong showing on this
> thread, I've heard the same concerns voiced by numerous other users,
> particularly on IRC.
>   
[...]

If the issue need some voice, there is mine ;) More seriously, it's 
really something that come quite often in the ML and on irc.
> Once again, it's not that it's technically broken.  It's that in nearly
> every other avenue, Tapestry goes out of its way to work out context for the
> developer.  A lot of niceties go on behind the scenes and contribute to the
> beauty of the framework.  In this case, it breaks away from that philosophy,
> wipes its hands of the messy part and puts everything on the developer's
> shoulders.  And it feels like this was the result of the evolution of the
> type coercion system rather than a legitimate design decision . . . i.e.,
> given what we know now up front, I believe the design would have been
> radically different than it is now, working more for the developer.
>   
I can't agree more, thank you Keven for this summary.
I also think that this is not the kind of big architectural move that 
should be change before the 5.0 final : we *really* need a stable, even 
non perfect, framework, quickly. I mean, I, the developper, now that 
5.0.2 was more stable in alpha than other "final" product (out of the 
mind, hmmm, maven ?). But when I explain to my chief that T5 is now in 
"beta", since too years, he is asking if it's google, and if it's really 
cleaver to use such a non final product (it's a caricature, but ideas 
are here).
But perhaps it would be a good point to try improve that point for the 5.1 ?

-- 
Francois Armand
Etudes & Développements J2EE
Groupe Linagora - http://www.linagora.com
Tél.: +33 (0)1 58 18 68 28
-----------
InterLDAP - http://interldap.org 
FederID - http://www.federid.org/
Open Source identities management and federation


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


Re: Type Coercion Issues

Posted by Kevin Menard <ni...@gmail.com>.
It seems this issue is going nowhere.  All I can say at this point is that I
agree with Robert's sentiments.  Despite the lack of strong showing on this
thread, I've heard the same concerns voiced by numerous other users,
particularly on IRC.
Once again, it's not that it's technically broken.  It's that in nearly
every other avenue, Tapestry goes out of its way to work out context for the
developer.  A lot of niceties go on behind the scenes and contribute to the
beauty of the framework.  In this case, it breaks away from that philosophy,
wipes its hands of the messy part and puts everything on the developer's
shoulders.  And it feels like this was the result of the evolution of the
type coercion system rather than a legitimate design decision . . . i.e.,
given what we know now up front, I believe the design would have been
radically different than it is now, working more for the developer.

-- 
Kevin


On Mon, Nov 3, 2008 at 1:51 PM, Robert Zeigler <ro...@scazdl.org> wrote:

>
> 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 <ro...@scazdl.org>
>> 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 <ni...@gmail.com>
>>>> 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 <hl...@gmail.com>
>>>>> 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: dev-unsubscribe@tapestry.apache.org
>>>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>>>>
>>>>>>
>>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Howard M. Lewis Ship
>>>>
>>>> Creator Apache Tapestry and Apache HiveMind
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>
>>>
>>>
>>
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator Apache Tapestry and Apache HiveMind
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>

Re: Type Coercion Issues

Posted by Robert Zeigler <ro...@scazdl.org>.
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 <ro...@scazdl.org>  
> 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 <ni...@gmail.com>  
>>> 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 <hlship@gmail.com 
>>>> >
>>>> 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: dev-unsubscribe@tapestry.apache.org
>>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>>>
>>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>>
>>>>
>>>
>>>
>>>
>>> --
>>> Howard M. Lewis Ship
>>>
>>> Creator Apache Tapestry and Apache HiveMind
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>
>>
>
>
>
> -- 
> Howard M. Lewis Ship
>
> Creator Apache Tapestry and Apache HiveMind
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org


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


Re: Type Coercion Issues

Posted by Howard Lewis Ship <hl...@gmail.com>.
As I commented in the issue, your last example can take an
EventHandler, not a Object[], and work properly.

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?

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.


On Fri, Oct 31, 2008 at 2:13 PM, Robert Zeigler <ro...@scazdl.org> 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 <ni...@gmail.com> 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 <hl...@gmail.com>
>>> 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: dev-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>
>>>
>>
>>
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator Apache Tapestry and Apache HiveMind
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

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