Both solutions have been implemented in FalconJx, I'm moving on. EdB
On Fri, Dec 28, 2012 at 1:25 AM, Frank Wienberg <fr...@jangaroo.net> wrote: > On Thu, Dec 27, 2012 at 2:33 PM, Erik de Bruin <e...@ixsoftware.nl> wrote: > >> Frank, >> >> I did read your blog, I'm not that stubborn ;-) >> > > Good to hear, I was beginning to suspect you are ;-) > > >> I think you're addressing an edge case (passing 'undefined') to make >> your point, but that is fine as it helps focus me on getting the >> optimal solution. I say optimal, not perfect, for a reason, which is: >> > > Sorry, but I don't get your point. Even if you think I discovered an edge > case that might not make such a big difference in practice, what speaks * > against* my solution? > > - It resembles the original ActionScript semantics > - It is easy to understand (look for the number of actual parameters, > and if there are not enough of them, ...) > - It is easy to generate and doesn't need any more generated code than > your solution > - It is more efficient than your solution > - Mike already implemented it > > > >> >> As long as we're talking edge cases, I noticed your blog also invokes >> one to make it's point, namely using an untyped parameter. Your >> function signature is "insult(s = 'fool')". Only when the parameter >> you're setting a default for is untyped will it's value be >> 'undefined', which you are testing for in your blog. In all cases= >> where you declare a type for the parameter ("insult(s:String = >> 'fool')"), the value assigned to it when you pass 'undefined' is the >> initial for that type, i.e 'null' for String and Object, NaN for >> Number, 0 for int, false for Boolean, etc.. >> >> I'm not sure how your solution provides for this? Mine doesn't either, >> mind you, but I gave up perfection for simplicity very early in this >> thread ;-) >> > > It does not. I consider this case another problem. That's why I used an > untyped parameter to demonstrate how ActionScript handles default parameter > values. > > In ActionScript, it is simply not allowed to stuff a wrong value into a > typed parameter or variable. And it is not allowed to leave out a required > (= non-optional) parameter. > However, there are some cases where implicit type conversion (coercion) > takes place. Your example of a parameter of type String that is passed > undefined is an example of coercion and has nothing to do with default > parameter values. It is the same as assigning undefined to a local variable > of type String: the variable is null afterwards. Only that the "assignment" > happens in the function call. > So far, we do not perform any type checking at run-time. Why? Because we > rely on the compiler refusing to compile in case of type errors. So we > wouldn't add any code inside the function that checks whether > parameter sactually contains a > String, because we expect the calling code to have been type-checked. > In the same sense, we should not add code inside the function to check for > undefined and then assign the initial value for the type (here: null), > because a variable of type String should never be undefined in the first > place. Instead, this coercion should be generated in the *calling* code! > Why? Because if 90% of the calling code can be statically proven to use the > correct type (ruling out the value undefined for a String), always doing a > dynamic check for undefined at run-time would be waste and inefficient. > Note that TypeScript, too, refrains from generating any JavaScript code > that does type checking; all type checking is done at compile time. > Coercion of a literal value like undefined to a String can simply be done > at compile time. However, in case of complex untyped values used as typed > values, we'd have to do type *coercions* at run-time. E.g. imagine we have > some veryComplicatedFunction():*, and an ActionScript expression of > foo(veryComplicatedFunction()), we'd have to translate it to > foo(coerceToString(veryComplicatedFunction())). > If we plan to implement type coercions like in ActionScript (at least > somewhere in the future), here is another argument against checking a > parameter for undefined to assign its default value: once we have > implemented coercion, the function body would not "see" undefined, but null, > and could not distinguish it from a null explicitly given by the caller. > And handing in null for a String parameter with a default value of 'foo', I > dare say, is no longer an edge case and thus should behave like in "real" > ActionScript. Using the arguments.length approach, the called function can > tell the difference and behave correctly. > > Last but not least, what about coercion if the function is called directly > from JavaScript? Well, then, we have a problem, anyway, because we also do > not type-check. We could either mimic ActionScript's ExternalInterface for > code meant to be called from JavaScript and add type checking and coercion > code there (in a wrapper function), or live with possible errors at > run-time for a simpler and more efficient solution. > > Sorry I had to say all that, please please nobody cite XKCD's "someone's > wrong on the internet" again! ;-) > > Greetings > -Frank- -- Ix Multimedia Software Jan Luykenstraat 27 3521 VB Utrecht T. 06-51952295 I. www.ixsoftware.nl