[Laszlo-dev] Undefined pattern in AS3

André Bargull andre.bargull at udo.edu
Mon Aug 25 09:42:25 PDT 2008


I was retrieving a value from an Object. So this should be the second 
case you've described.
> var val:Object = d[idx][key];
> if (val !== void(0)) {
(with "d" as an Array of Objects (Array.<Object>)).

 > Surely in AS2 `undefined === void 0`?
You meant AS3, right? This testcase yields the correct results in AS3 in 
respect to comparison of "void 0".
> var foo:Object = {};
> for (var i:int = 0; i < 6; ++i) {
>   Debug.write("step " + i,
>     foo['bar'] == void(0), foo['bar'] === void(0),
>     foo['bar'] == undefined, foo['bar'] === undefined);
>             
>   if (i == 0) foo['bar'] = void(0);
>   else if (i == 1) foo['bar'] = undefined;
>   else if (i == 2) foo['bar'] = "hello";
>   else if (i == 3) foo['bar'] = 123;
>   else if (i == 4) delete foo['bar'];
> }

Results:
> step 0 true true true true
> step 1 true true true true
> step 2 true true true true
> step 3 false false false false
> step 4 false false false false
> step 5 true true true true




On 8/25/2008 5:37 PM, P T Withington wrote:
> Does comparing to `undefined` work because it is actually defined, or 
> does it work because it is not defined, so the compiler has to defer the 
> comparison to run time, rather than make the observation at compile time 
> that you are making a spurious comparison?  Surely in AS2 `undefined === 
> void 0`?
> 
> But also, in keeping with our move toward JS2, we should have our 
> compiler treat `undefined`, `NaN`, and `Infinity` as constants (and 
> translate them to `(void 0)`, `(0/0)`, and `(1/0)` in the JS1 back end.  
> There is no reason for LZX to have these values be mutable.  Please file 
> an improvement request.
> 
> 
> On 2008-08-25, at 11:16EDT, André Bargull wrote:
> 
>> I was wrong with the error number, it isn't 1118, but actually 1176:
>> > 1176    Comparison between a value with static type %s and a 
>> possibly unrelated type %s.
>>
>>> Are you saying that in AS3 if you replace `void 0` with `undefined` 
>>> you won't get the coercion error?  That would be totally strange, 
>>> because `===` is not supposed to do any coercion.  It should just 
>>> return `false` if it is asked to compare unrelated types.
>> Yes, if I replace "void 0" with "undefined", everything works. But 
>> then we're back in the JS1-dilemma which you've described in your blog.
>>
>>> I think you are correct in using `*` as the type declaration when you 
>>> want to admit `void 0` as a possible value (although that means you 
>>> open it up to other "primitive" types also, which may or may not be 
>>> what you want).
>> My intention was to accept any non-undefined values and to use 
>> undefined as the marker for non-existing entries in the cache.
>>
>>
>> Original error output (unfortunately just in German):
>>>     [java] ERRORS:
>>>     [java] [(unknown): 45] line unknown: Error: Vergleich zwischen 
>>> einem Wert mit statischem Typ Object und einem m÷glicherweise nicht verw
>>> andten Typ void.
>>>     [java] FAIL: compiler returned 1
>>>     [java] Done executing compiler
>>>     [java] Intermediate file 
>>> c:\DOKUME~1\Admin\LOKALE~1\Temp\lzswf9\lzgen36335\app.swc: does not 
>>> exist
>>>     [java] Exception compiling scriptfile: 
>>> org.openlaszlo.sc.CompilerError: line unknown: Error: Vergleich 
>>> zwischen einem Wert mit statisch
>>> em Typ Object und einem m÷glicherweise nicht verwandten Typ void, in 
>>> line: if ($7 !== void 0) {
>>>     [java] org.openlaszlo.sc.CompilerException: 
>>> org.openlaszlo.sc.CompilerError: line unknown: Error: Vergleich 
>>> zwischen einem Wert mit sta
>>> tischem Typ Object und einem m÷glicherweise nicht verwandten Typ 
>>> void, in line: if ($7 !== void 0) {
>>>     [java]     at org.openlaszlo.sc.Compiler.compile(Compiler.java:397)
>>>     [java]     at org.openlaszlo.sc.lzsc.compile(lzsc.java:110)
>>>     [java]     at org.openlaszlo.sc.lzsc.compile(lzsc.java:322)
>>>     [java]     at org.openlaszlo.sc.Main.main(Main.java:10)
>>>     [java] Compilation aborted.
>>
>>
>>
>> On 8/25/2008 4:46 PM, P T Withington wrote:
>>> I thought I ran into this too, but the error turned out to be 
>>> something different:
>>>  http://jira.openlaszlo.org/jira/browse/LPP-6781
>>> Are you saying that in AS3 if you replace `void 0` with `undefined` 
>>> you won't get the coercion error?  That would be totally strange, 
>>> because `===` is not supposed to do any coercion.  It should just 
>>> return `false` if it is asked to compare unrelated types.
>>> I think this is really just a bad choice of error message on the part 
>>> of the compiler.  What it is trying to tell you is: "You declared 
>>> `old` to be of type `Object`, and on the next line, you are asking if 
>>> it could possibly be of type `Void`.  That is impossible."
>>> [So, in AS3, for any class `X`, if you declare something as of type 
>>> `X` you are implicitly declaring it as `X?` (to use JS2 syntax).  
>>> That is, any var that is declared as a subclass of `Object` is also 
>>> allowed to be of type `Null`... but not of type `Void`.
>>> Brendan takes full responsibility for the 'Javascript has two nulls 
>>> mess'.  But it appears that Flex has made it a bit messier, by making 
>>> `Null` a pseudo-subclass of `Object`, but `Void` not?]
>>> I think you are correct in using `*` as the type declaration when you 
>>> want to admit `void 0` as a possible value (although that means you 
>>> open it up to other "primitive" types also, which may or may not be 
>>> what you want).
>>> On 2008-08-25, at 10:04EDT, André Bargull wrote:
>>>> In my recent changeset for RegExp-support in swf8, you'll get an 
>>>> error, if you compile the lfc for swf9:
>>>>
>>>> The simple cache class I've added accepts "Objects" as values, so I 
>>>> coded:
>>>>> function put (key:String, value:Object) :Object {...}
>>>>> function get (key:String) :Object {...}
>>>> And in these functions, I've used the "undefined"-pattern described 
>>>> in [1]:
>>>>> var old:Object = this.get(key);
>>>>> if (*old === void(0)*) {
>>>> But this gave me an AS3 compiler-error [2]:
>>>>> 1118    Implicit coercion of a value with static type Object to a 
>>>>> possibly unrelated type void.
>>>>
>>>> To get around the compiler error, I've just changed the 
>>>> type-declaration to "*" (maybe even more reasonable). So far so 
>>>> good, but we've used the "void 0"-pattern all along in our code. 
>>>> Therefore do you think it's possible to update the compiler to 
>>>> change "void 0" to "undefined" for JS2-targets, resp. the other way 
>>>> around, so "undefined" to "void 0" for JS1-targets (possibly more 
>>>> straightforward)? Just to ensure the "one code, multiple runtimes" 
>>>> idea in OpenLaszlo.
>>>>
>>>> - André
>>>>
>>>>
>>>> [1] 
>>>> http://pt.withy.org/ptalk/archives/2005/06/dont_assume_undefined_is_undefined.html 
>>>>
>>>> [2] 
>>>> http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/compilerErrors.html 
>>>>
>>
> 
> 



More information about the Laszlo-dev mailing list