Administrator
|
Hi,
So if you run this code on AS public var s:String; public var o:Object; public var i:int; public var n:Number; public var b:Boolean; public function init():void { trace(s); trace(o); trace(i); trace(n); trace(b); } You get: null null 0 NaN false null but on JS you get: undefined undefined 0 undefined undefined undefined Now with strings, objects and Arrays you can get issues with === and !== as they are null on one platform and undefined on an another - as discussed in the other thread. But the issue is worse with Numbers and Booleans as there are additional concerns. Performance is also an issue as JS doesn't know what type they are and will be slowed down by implicit casting. For example this code will not do as you expect and say b is true when it is not as undefined != false. var b:Boolean; if (b == false) { trace(“b is false”); } else { trace(“b is true”); } Luckily isNaN(undefined) returns true, NaN != undefined so that may cause some issues as well. Thanks, Justin |
Good points. I'm all for initializing more than we do now. Even if we don't
achieve parity with all types, Booleans should definitely default to false and Numbers to NaN, if they aren't explicitly initialized with a value, in my opinion. - Josh On Jun 3, 2017 7:27 PM, "Justin Mclean" <[hidden email]> wrote: Hi, So if you run this code on AS public var s:String; public var o:Object; public var i:int; public var n:Number; public var b:Boolean; public function init():void { trace(s); trace(o); trace(i); trace(n); trace(b); } You get: null null 0 NaN false null but on JS you get: undefined undefined 0 undefined undefined undefined Now with strings, objects and Arrays you can get issues with === and !== as they are null on one platform and undefined on an another - as discussed in the other thread. But the issue is worse with Numbers and Booleans as there are additional concerns. Performance is also an issue as JS doesn't know what type they are and will be slowed down by implicit casting. For example this code will not do as you expect and say b is true when it is not as undefined != false. var b:Boolean; if (b == false) { trace(“b is false”); } else { trace(“b is true”); } Luckily isNaN(undefined) returns true, NaN != undefined so that may cause some issues as well. Thanks, Justin |
Sounds like there is no one right answer, so we should offer choices in
compiler output. To me, if there are valid and common AS coding patterns that don't require initialization, I would happily use them and make changes where warnings detect unsafe usage. IOW, for var b:Boolean; I believe in AS, there is no way to have if (b === false) Have any semantically different meaning than if (b) This latter pattern is fastest and smallest. If we ever add optimizing to the compiler, it might the first pattern to the latter. IMO, we are not here to be able to reproduce every line of JS ever written by writing AS, we are purposefully limiting the kinds of JS you can write by making you use AS, so you don't screw yourself over and have improved developer productivity. We won't let you assign types that mismatch, or have the wrong number of parameters. So once you agree that we only want to support AS semantics in JS, then we can see where we must initialize, and where we might want to offer options. My 2 cents, -Alex On 6/4/17, 6:38 PM, "Josh Tynjala" <[hidden email]> wrote: >Good points. I'm all for initializing more than we do now. Even if we >don't >achieve parity with all types, Booleans should definitely default to false >and Numbers to NaN, if they aren't explicitly initialized with a value, in >my opinion. > >- Josh > >On Jun 3, 2017 7:27 PM, "Justin Mclean" <[hidden email]> wrote: > >Hi, > >So if you run this code on AS >public var s:String; >public var o:Object; >public var i:int; >public var n:Number; >public var b:Boolean; > >public function init():void { > trace(s); > trace(o); > trace(i); > trace(n); > trace(b); >} > >You get: >null >null >0 >NaN >false >null > >but on JS you get: >undefined >undefined >0 >undefined >undefined >undefined > >Now with strings, objects and Arrays you can get issues with === and !== >as >they are null on one platform and undefined on an another - as discussed >in >the other thread. > >But the issue is worse with Numbers and Booleans as there are additional >concerns. Performance is also an issue as JS doesn't know what type they >are and will be slowed down by implicit casting. > >For example this code will not do as you expect and say b is true when it >is not as undefined != false. > >var b:Boolean; > >if (b == false) >{ > trace(“b is false”); >} >else >{ > trace(“b is true”); >} > >Luckily isNaN(undefined) returns true, NaN != undefined so that may cause >some issues as well. > >Thanks, >Justin |
Administrator
|
Hi,
> I believe in AS, there is no way to have > > if (b === false) > > Have any semantically different meaning than > > if (b) One will check for false the other true so they have opposite meaning. You'll also note I stated “b == false” not “b === false”. Currently for an uninitialised variable b == false will equal true on AS but false on JS > This latter pattern is fastest and smallest. If we ever add optimizing to > the compiler, it might the first pattern to the latter. I hope not as it will produce a lot of errors. You’ll also need to consider b == condition where the condition evaluates to false but b is undefined, again you will get the result of true on AS and false on JS. Thanks, Justin |
Administrator
|
In reply to this post by Josh Tynjala
Hi,
> Booleans should definitely default to false and Numbers to NaN, if they aren't explicitly initialized with a value Anyone have a differing option? Thanks, Justin |
Agree with this two, as for the rest I would not touch them.
Piotr |
In reply to this post by Justin Mclean
It sounds like there are differing opinions. Some folks want all booleans
to be initialized to false, just in case someone uses a pattern like: if (someBoolean === false) I would rather find where I've written that pattern so I can manually change it to: if (!someBoolean) since there is no semantic difference in AS. And then I can avoid the expense of initializing boolean variables. We don't have to agree. We can teach the compiler to do both. -Alex On 6/7/17, 5:23 PM, "Justin Mclean" <[hidden email]> wrote: >Hi, > >> Booleans should definitely default to false and Numbers to NaN, if >>they aren't explicitly initialized with a value > >Anyone have a differing option? > >Thanks, >Justin |
Administrator
|
Hi,
> if (someBoolean === false) II think you may be missing the point? The issue is with: if (someBoolean == false) Not: if (someBoolean === false) Thanks, Justin |
Administrator
|
Hi,
Also how wold you fix this? if (someBoolean == (complex expression that equals false)) Thanks, Justin |
In reply to this post by Justin Mclean
I’m probably missing the point too.
Since an uninitialize boolean would be undefined, undefined == false, so that’s okay. undefined !== false, so that’s not okay. Oh. One sec. I actually just tried it in JS and I see that undefined != false. That’s weird. I don’t think I ever realized this (or I forgot it long ago) so: var a; if(a) // is falsy if(a==true)//falsy but: if(a==false)//also falsy Harbs > On Jun 9, 2017, at 1:12 AM, Justin Mclean <[hidden email]> wrote: > > Hi, > >> if (someBoolean === false) > > II think you may be missing the point? The issue is with: > > if (someBoolean == false) > > Not: > > if (someBoolean === false) > > Thanks, > Justin |
Administrator
|
HI,
> Oh. One sec. I actually just tried it in JS and I see that undefined != false. That’s weird. Yep that’s the issue. Thanks, Justin |
Thanks for pointing it was == and not ===, but I must still be missing
something. If a variable is of type Boolean in AS (not JS), is there a difference between these three patterns: If (b) If (b == true) If (b === true) Or these three? If (!b) If (b == false) If (b === false) I don't think there is, and so for me, I would rather not have the output JS initialize b to false and would rather have the compiler catch were I wrote anything other than (b) or (!b). I'd happily replace them and save code. But again, I don't think we have to agree. The compiler can be taught to respond to options to initialize everything as well detect unnecessary code. Thanks, -Alex On 6/8/17, 3:40 PM, "Justin Mclean" <[hidden email]> wrote: >HI, > >> Oh. One sec. I actually just tried it in JS and I see that undefined != >>false. That’s weird. > >Yep that’s the issue. > >Thanks, >Justin |
I suspect that the if(b == true) and if(b == false) patterns aren't out of
the ordinary in real-world code. I hope the default will be to initialize Booleans to false and that you'll need to opt into the other behavior. - Josh On Fri, Jun 9, 2017 at 3:38 PM, Alex Harui <[hidden email]> wrote: > Thanks for pointing it was == and not ===, but I must still be missing > something. If a variable is of type Boolean in AS (not JS), is there a > difference between these three patterns: > > If (b) > If (b == true) > If (b === true) > > Or these three? > > If (!b) > If (b == false) > If (b === false) > > I don't think there is, and so for me, I would rather not have the output > JS initialize b to false and would rather have the compiler catch were I > wrote anything other than (b) or (!b). I'd happily replace them and save > code. > > But again, I don't think we have to agree. The compiler can be taught to > respond to options to initialize everything as well detect unnecessary > code. > > Thanks, > -Alex > > On 6/8/17, 3:40 PM, "Justin Mclean" <[hidden email]> wrote: > > >HI, > > > >> Oh. One sec. I actually just tried it in JS and I see that undefined != > >>false. That’s weird. > > > >Yep that’s the issue. > > > >Thanks, > >Justin > > |
Administrator
|
In reply to this post by Alex Harui-2
Hi,
> If a variable is of type Boolean in AS (not JS), is there a > difference between these three patterns. No as a boolean can only have the values of true and false and defaults to false in AS. If you take the same code and run it in the browser it can now have three values, true, false and undefined and it defaults to undefined. Currently this is cause bugs as undefined != false in JS. For example this program with incorrectly get "B is true” in the browser and “B is false” in the flash player. <?xml version="1.0" encoding="utf-8"?> <js:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:js="library://ns.apache.org/flexjs/basic" applicationComplete="init()"> <js:valuesImpl> <js:SimpleCSSValuesImpl/> </js:valuesImpl> <fx:Script><![CDATA[ protected function init():void { var b:Boolean; if (b == false) { trace("B is false"); } else { trace("B is true"); } } ]]></fx:Script> <js:initialView> <js:View percentWidth="100" percentHeight="100"> </js:View> </js:initialView> </js:Application> It is however a simple example and the same issue will also occur in any case where you end up comparing a freshly defined boolean (i.e. undefined) with an expression that evaluates to false so just converting (b == false) to (!b) would not be enough to solve the issue. Thanks, Justin |
Administrator
|
Hi,
And this particular rabbit hole goes a lot deeper. Any guesses what these two expression give? false && undefined undefined && false If you expect them to have the same answer you would be incorrect. Does this matter? Well try this code on both platforms: var a:Boolean; var b:Boolean = false; var c:Boolean = false; if ((a && b) != c) { trace("True"); } else { trace(“False); } You’ll get “False” in the flash player and “True” in JS. And again this is a simple example the RHS would be a much more complex expression that equates to false and you’ll still have this bug. Thanks, Justin |
In reply to this post by Justin Mclean
The general principle is optimization. Optimization looks for specific
patterns. What you wrote below is not one of the patterns. Would be fun to see how often that pattern exists though. IMO, it would not make sense to initialize every boolean because 1% of the boolean expressions require optimization if alternative patterns exist that allow for smaller code. But again, we don't have to agree, just provide compiler options. -Alex On 6/8/17, 3:17 PM, "Justin Mclean" <[hidden email]> wrote: >Hi, > >Also how wold you fix this? > >if (someBoolean == (complex expression that equals false)) > >Thanks, >Justin |
Administrator
|
HI,
> The general principle is optimization. Optimization looks for specific > patterns. What you wrote below is not one of the patterns. Not one of what patterns? BTW Initialising the Boolean to false also optimises the seed by a factor of two. i.e. twice as fast. > Would be fun to see how often that pattern exists though. From a quick glance (not testing)it exists in serval places in the existing SDK. Thanks, Justin |
Administrator
|
Hi,
I think we may be talking cross purposes here to be clear - IMO this is not an optimisation issue this it’s a serious bug. Justin |
I agree that this is a serious bug.
- Josh On Jun 9, 2017 10:49 PM, <[hidden email]> wrote: > Hi, > > I think we may be talking cross purposes here to be clear - IMO this is > not an optimisation issue this it’s a serious bug. > > Justin |
Administrator
|
Hi,
So to summarise this thread. - discussing if Boolean be initialised to false and Numbers to NaN - Code can act differently on AS and JS when these initialisers are not present - Josh and I think this a serious bug - Harbs also sees the issue - Piotrz also wants Booleans and Numbers to be initialised - Alex thinks this is an optimisation issue I’ve went ahead and made the change and checked into a new initialization branch of falcon. Testing with a real world application gave no notable size increase and improved performance by 10% on JS. Mostly I would guess due to use of == and != in the framework and implicit casting that goes on when when comparing uninitialised variables. Thanks, Justin |
Free forum by Nabble | Edit this page |