(accidentally left out es-discuss when I responded to Norbert… response if 
below)

On Monday, 3 September 2012 at 13:20, Marcos Caceres wrote:

> Hi Norbert,  
>  
> On Saturday, 1 September 2012 at 00:31, Norbert Lindenberg wrote:
>  
> > On Aug 31, 2012, at 7:17 , Marcos Caceres wrote:
> >  
> > The way I understand it, backwards compatibility means that code that runs 
> > on an old version without exceptions continues to run on the new version 
> > with the same results. It does not mean that code that takes advantage of 
> > new capabilities in the new version will get the same results on the old 
> > version.
>  
> You are correct, lets call this graceful degradation or fault tolerance. I 
> guess it does not matter what we call it, so long as it's understood that 
> desired behaviour is that the API continues to work on old runtimes when if 
> new options are made available without significant code changes (such as 
> wrapping code in try/catch blocks).  
> > > Bogus hypothetical example - ES i18n.next introduces "formal", where the 
> > > day always has the first letter capitalised:
> > >  
> > > {day: "formal"}
> >  
> >  
> > Let's assume weekday - the day property currently has only "numeric" and 
> > "2-digit", therefore no letters.
> >  
> > > Because of this throw behaviour, the introduction of "formal" in a future 
> > > spec would potentially break all existing implementations today. If this 
> > > behaviour is left as is, (1) all calls to the i18n API will need to be 
> > > wrapped in try/catch (as a preemptive measure as the introductions of a 
> > > new option value would cause a throw). As a side effect, (2) users on old 
> > > browsers could be negatively impacted in the future without the knowledge 
> > > of the developer.
> >  
> >  
> > Applications only have to wrap their calls in try/catch if they use a new 
> > option value and want to run on old browsers that may not understand the 
> > new value.
>  
> The problem with the above is that the developer may not even know that the 
> API throws - if the developer runs their code on only browsers that support 
> "formal" then she would never know there was a problem. The above also 
> assumes the code is being maintained by the developer. The developer may 
> choose not to care about particular users or may not have access to (or even 
> be aware of) their application failing on particular browsers.  
>  
> As I've stated before, the current API design is allowing developers to 
> unknowingly exclude users. By simply providing a fallback, this problem goes 
> away.  
> > It's similar to how they have to check whether new API exists if they want 
> > to run on browsers that may not have that API yet.
>  
>  
>  
> I don't think the API design should rely on workarounds that have emerged to 
> overcome issues with the Web platform (i.e., feature testing and duck typing 
> are in many ways a failing of the platform, and not something that should be 
> built on, IMHO). APIs should not rely on having to be wrapped in support 
> checking code as it makes code much more inefficient, harder to read, and 
> less maintainable. Compare:
>  
> //always gonna get something the user understands…  
> var ldate = (new Date()).toLocaleString("en", {day: "formal"});  
>  
> To:
> if(window.Intl !== undefined){
> try{
> var ldate = (new Date()).toLocaleString("en", {day: "formal"});
> }catch(e){
> //ok, gotta try something else…
> ...
> }
> }
>  
> Also, feature detection is usually done at the most basic level: like 
> window.hasOwnProperty("Intl"); and not try/catch every possible option in the 
> an API. Take a look at Modernizr:
>  
> http://modernizr.com/downloads/modernizr.js
>  
> Most tests are pretty simple (in a good way): in as far as they most just 
> test "if (x in y) return true/false". In most cases, actual functionality is 
> not tested - just presence of a given host object, method, or attribute.  
> > Applications probably also would not have to wrap all calls - I think 
> > modern applications run a sequence of tests early on to detect which of the 
> > features they want to use are supported, and then adjust their behavior 
> > accordingly (polyfill, dumb down, ask the user to upgrade, ...).
>  
>  
>  
> This assumes a lot of sophistication on the part of developers. History shows 
> that most developers don't do unit testing or any other kind of testing.  
>  
> The API should make no assumptions about the code around it - the assumed 
> context should not matter (i.e., wrapped in try/catch or not should not 
> factor into the API design). To be clear: the API should be designed to be 
> testable, but it should be assumed that it will *not* be tested.  
> > In this specific case, checking whether "formal" is supported also lets 
> > applications decide what to do if "formal" is not supported.
>  
>  
>  
> This assumes that runtimes are the same across platforms or that the 
> developer has access to all the platforms on which she is required to test.  
> > Most likely, it would choose "long" instead because it's closer to "formal" 
> > than "numeric", which would be the default used by the implementation.
>  
>  
>  
> The choice of value is not really important here. What is important is that 
> the API continue to return something useful to the user irrespective of the 
> developer's fumble.  
> > > For the case of (1), developers may not even be aware that the API throws 
> > > (or has thrown) for a particular set of users using an outdated browser - 
> > > I personally found that it throws by accident. This would lead to (2), 
> > > which unfairly punishes users without the developer's knowledge - causing 
> > > the application to potentially stop working all together if the exception 
> > > is not caught.
> >  
> >  
> >  
> >  
> > Web developers generally need to be aware that there are different browser 
> > versions with different capabilities - that's not new. They decide whether 
> > IE 6 is the baseline or IE 9, and then check for features that were 
> > introduced after the baseline version.
>  
> That's simply impossible to do in most cases and puts a massive financial and 
> technological burden on developers: imagine you had to own a copy of Windows 
> XP, Vista, 7, and Windows 8… as well as then have a Mac and a machine to test 
> Linux, as well as a range of iOS devices, Android Devices, Windows Phone 7 
> and 8, a Blackberry, etc. etc. The number of browser engines and environments 
> that ES is being used on continues to grow, this task simply becomes 
> impossible - which is also why I argue that the API needs to be more fault 
> tolerant.  
>  
> The above also assumes that the software is being maintained: what happens if 
> the developer adds "formal" then stops maintaining the software, but it's 
> still used by people?  
>  
> This is also compounded by the fact that release cycles are changing - it is 
> impossible to test every possible version of Chrome and FireFox since they 
> started their rapid release cycle… To make matters worst, if a particular 
> browser vendor decides tomorrow to abandon support for Windows XP, that 
> potentially leaves millions of people out in the cold… I don't think IE10 
> will be supported by XP. Fast-forward 5-10 years, Windows 8 becomes the new 
> Windows XP - and IE10 will be the new "IE6" with millions stuck on that 
> version.  
>  
> And from a user's perspective, those who can't afford latest and greatest 
> software (or who has no option to update their browsers, like in iOS) risk 
> being deliberately or accidentally excluded by developers.
>  
> Also, setting a baseline sets a bad practice (and is fundamentally against 
> the core principles of "one Web"): developers should never target a 
> particular baseline - they unfortunately have to do this sometimes, but it's 
> certainly not something that should be assumed in the design of an API.  
>  
> > > IMHO, falling back to defaults, or by ignoring bogus values, would make 
> > > the API degrade gracefully without negatively impacting users (that is 
> > > something I really like about the API today - it does that if you feed it 
> > > bogus language tag or bogus option it does not understand). I think it 
> > > should be the same for option values.
> >  
> > > I would also argue that having the above throw is inconsistent with the 
> > > rest of the API. The API already provides nice fallbacks to defaults in 
> > > most cases. For example, today (without i18n API support), calling any of 
> > > the to*LocaleString() simply "just works" - overcoming side-effect 2 
> > > above and not punishing users with an exception. I think most developers 
> > > would expect that kind of fallback behaviour - you are guaranteed to get 
> > > a date/time/number that the user will understand (even if it's not as 
> > > pretty as a custom formatted one):
> > >  
> > > x.toLocaleTimeString("en", {foo: "bar"})
> > > //"12:00:00 AM"
> > >  
> > > x.toLocaleTimeString("klingon", {foo: "bar"})
> > >  
> > > //"12:00:00 AM"
> > >  
> > > …and so on… which is a great graceful fallback behaviour .
> >  
> >  
> > Yes and no. For structurally invalid language tags, it will throw. For 
> > structurally valid tags that it just doesn't recognize, it will use 
> > fallbacks. And there has been a lot of discussion about these fallbacks 
> > between some internationalizers who want a lot of flexibility to do what 
> > they think is best for the user, and TC 39 members who want behavior fully 
> > specified so that it's predictable and consistent across implementations.
>  
> I personally think the behaviour of the API with regards to language tags is 
> reasonable because it checks language-tag structure, but does not throw when 
> the browser does not know the language: i.e., it behaves in a future proof 
> manner that degrades gracefully. This is exactly how I think the options 
> should work too for unknown options: so long as the option is a String, it 
> should behave the same way as with language tags - i.e., fall back to 
> something gracefully when the value is unknown.  
> > > If the spec authors want to "warn" developers that they've used an 
> > > unsupported option value, maybe put into the spec to call 
> > > "console.warn()" or similar, if available. That allows developers to know 
> > > they've used something unsupported/unknown/or misspelled without 
> > > punishing users - mobile safari and Chrome do this already for 
> > > meta-viewport values, so there is some helpful precedence here. Yes, 
> > > relying on "console.warn" is non standard, but this could just be 
> > > specified as non-normative text by just saying where appropriate in the 
> > > spec:
> > >  
> > > "Optionally, warn the developer that the option value is unsupported by, 
> > > for example, calling console.warn() or similar if available to the 
> > > implementation."
> > >  
> > > I think all modern browsers support the console object, and so does 
> > > Node.js.
> >  
> >  
> > ECMAScript is used in more environments than just browsers and Node.js, and 
> > TC 39 is generally staying away from making any specific requirements on 
> > the host environments. Clause 16 of the Language spec specifies precisely 
> > which errors must be reported when, but says nothing about how to report 
> > them.
>  
> That's fine, but my argument is really about not forcing developer errors 
> onto users (users can't do anything about those problems). It's simple to 
> specify a fallback in the spec that protects users from developer error (and 
> makes developers lives easier because they can feel confident that the API 
> will always return something the user is likely to understand - as it does 
> today).  
> > > On the other hand, if the developer wants to check if what they inputed 
> > > as options is supported by the API, they can call .resolvedOptions() and 
> > > manually verify that all their options were understood by the browser. So:
> > >  
> > > var formatter = new v8Intl.DateTimeFormat(x, {day: "formal"}),
> > > options = formatter.resolvedOptions();
> > >  
> > > if(options.day !== "formal"){
> > > //no formal support, need to use something else
> > > options.day = "long";
> > > formatter = new v8Intl.DateTimeFormat(x, options),
> > > }
> > > … continue…
> >  
> >  
> >  
> >  
> >  
> > Actually, options.day !== "formal" does not mean that the implementation 
> > doesn't understand "formal" - it could also be that the requested locale 
> > happens not to have "formal" day names, while the implementations supports 
> > "formal" and other locales have such names.
>  
> Correct, but the above still holds as, IMO, "the right way"™ for a developer 
> to check if the API understood what the developer wanted (without the need to 
> throw an exception).  
> > > Note that there is precedence also in other APIs to not throw exceptions 
> > > on bogus options. For example, the Geolocation API does not throw in the 
> > > following cases and simply "just works" (tested in Chrome):
> > >  
> > > var l = function(e){console.log(e)};
> > > navigator.geolocation.getCurrentPosition(l, l, {maximumAge:"bananas"});
> > > navigator.geolocation.getCurrentPosition(l, l, {maximumAge:Node})
> > > navigator.geolocation.getCurrentPosition(l, l, {maximumAge:{}})
> >  
> >  
> >  
> >  
> >  
> > Is that good? Without looking at the WebIDL spec, what are the maximumAge 
> > values derived from "bananas", Node, or {}? Although, I'm afraid you can 
> > provide the same nonsense in some options of the Internationalization API...
>  
> It's good in as far that it's robust. In all bogus cases, the geolocation API 
> simply falls back to 0: "If a PositionOptions parameter was present, and its 
> maximumAge attribute was defined to a non-negative value, assign this value 
> to an internal maximumAge variable. If maximumAge was defined to a negative 
> value or was not specified, set the internal maximumAge variable to 0".  
>  
> Thanks for discussing this. Hopefully I've presented a coherent argument as 
> to why I think the change is important and clearly outlined the benefits for 
> both developers and users.  
>  
> Looking forward to this API being finalised and landing in browsers soon! :)  
>  
> Kind regards,
> Marcos



_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to