You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It has been suggested various times to align the use of the === operator to what JS/TS would do, which came also up again in a recent issue (I don't remember which one), suggesting to replace our special === semantics with changetype<usize>(a) == changetype<usize>(b) in standard library code, which is about the only place where this is of importance. Overall this change would make === and == behave exactly the same for string operands and drop the special meaning of someObject === someObject, replacing it with something else where necessary.
Considering the general confusion introduced by this, I am leaning towards this solution. Thoughts?
This turns out to be a bigger feat than expected. Because a === null compiled down to an i32.eq(a, 0) that was precomputable by Binaryen, but a A#__eq(0) isn't anymore, leading to all sorts of issues that must be solved first. Take for example
functiontest(): string{if(a!==null)returna;// now results in an "is possibly null" errorreturn"";}
This a more general issue under the hood that we already have with anything that implements custom == / != overloads, but now surfaces due to applying it to strings in all cases.
but that will limit what the overloads can do in the identity-equal case and introduces a branch.
A proper but radical solution would be to drop support for overloads entirely and build string comparison into the compiler, with alternative solutions going into the direction of building our own interpreter.
A half-baked solution would be to disallow overriding == and != and bake only those into the compiler, but I'd say that having > etc. overloads with no way to also override == is, well, meh.
Currently thinking about moving null checking to the type system, adding a third reference type variant alwaysNull to the existing nullable and nonNullable variants, with the implication that flows then need a way to remember the "actual" type of locals in addition to the declared type at any given point.
...When I wrote the above, I forgot about the fact that is is already an operator in TypeScript (used just in types, not actual executable code). But although this could potentially introduce a new confusion, I think it would be less than the confusion of repurposing ===. Or of course you could also invent some other operator, e.g. isSame.
I'm expecting my AssemblyScript code to compile as TypeScript and produce a JavaScript program that works as a drop in replacement for the WebAssembly module. Both modules should ( eventually ) support loading with import and be 100% compatible so that A/B testing of TypeScript/AssemblyScript modules becomes trivial. I think such interoperability is more important than any convenience feature.
Activity
dcodeIO commentedon Sep 20, 2019
This turns out to be a bigger feat than expected. Because
a === nullcompiled down to ani32.eq(a, 0)that was precomputable by Binaryen, but aA#__eq(0)isn't anymore, leading to all sorts of issues that must be solved first. Take for exampleThis a more general issue under the hood that we already have with anything that implements custom
==/!=overloads, but now surfaces due to applying it to strings in all cases.dcodeIO commentedon Sep 20, 2019
The easiest solution seems to be to do the identity check as an additional one to overloads that one can't override, looking somewhat like
but that will limit what the overloads can do in the identity-equal case and introduces a branch.
A proper but radical solution would be to drop support for overloads entirely and build string comparison into the compiler, with alternative solutions going into the direction of building our own interpreter.
A half-baked solution would be to disallow overriding
==and!=and bake only those into the compiler, but I'd say that having>etc. overloads with no way to also override==is, well, meh.dcodeIO commentedon Sep 21, 2019
Currently thinking about moving null checking to the type system, adding a third reference type variant
alwaysNullto the existingnullableandnonNullablevariants, with the implication that flows then need a way to remember the "actual" type of locals in addition to the declared type at any given point.mbrowne commentedon Jun 21, 2020
Why not just introduce a new operator? I think this would avoid the confusion and probably be easier to implement too. For example:
There could also be a negative form:
...although of course that would be for convenience/readability, since
if (!(a is b))would do the same thing.mbrowne commentedon Jun 21, 2020
...When I wrote the above, I forgot about the fact that
isis already an operator in TypeScript (used just in types, not actual executable code). But although this could potentially introduce a new confusion, I think it would be less than the confusion of repurposing===. Or of course you could also invent some other operator, e.g.isSame.cyberixae commentedon Jul 15, 2020
I'm expecting my AssemblyScript code to compile as TypeScript and produce a JavaScript program that works as a drop in replacement for the WebAssembly module. Both modules should ( eventually ) support loading with
importand be 100% compatible so that A/B testing of TypeScript/AssemblyScript modules becomes trivial. I think such interoperability is more important than any convenience feature.