Looks like they were dealing [1] with a similar question.
[1] https://github.com/HaxeFoundation/haxe/issues/4526 ________________________________ From: Greg Dove <greg.d...@gmail.com> Sent: Monday, January 7, 2019 9:57:33 AM To: dev@royale.apache.org Subject: Re: Official Hack Proposal (was Re: [royale-asjs] branch develop updated: Fix implicit coercion error) Harbs, the approach you're describing is also similar to Haxe's anonymous structures and typedefs which are also compile-time only (but broader than just getter/setters and regular methods in terms of typing). It works across all Haxe's (many) targets, including swf. On Mon, Jan 7, 2019 at 8:37 PM Harbs <harbs.li...@gmail.com> wrote: > There are three advantages to Typescript-style interfaces: > > 1. There’s less typing and passing around objects is easier. > 2. Plain objects are actually type checked. Instead of lying to the > compiler by using “as”, the compiler can check that the required properties > exist and are spelled correctly. > 3. They completely disappear at runtime. “True” interfaces add bulk at > runtime needed for reflection and the like. > > > Why would it be huge? > > From experience, the time spent casting and spellchecking plain objects is > very time consuming when you have a need for lots of plain objects. This > happens more often than you’d like in the “real world”… > > I’m envisioning two types of interfaces: > > 1. Classic interfaces like we have now. This would offer runtime checking > and reflection. It would also offer type safety for future strongly typed > languages. > 2. “Dynamic” or “Virtual” interfaces would offer type checking for dynamic > objects at compile-time only. > > I’m thinking of maybe decorating interfaces with [Dynamic] or [Virtual] to > tell the compiler that it’s a “fake” interface. > > Maybe we can support these kinds of interfaces in SWF output by simply > converting the type to “Object”. You wouldn’t get the runtime checking, but > you’d still get the compile-time checking. > > It might be possible to do something similar in Swift or Java, etc. too. > > Thoughts? > > Harbs > > > On Jan 7, 2019, at 8:37 AM, Alex Harui <aha...@adobe.com.INVALID> wrote: > > > > Feel free to make the changes. I personally am trying to ensure > type-safety instead of weaken it. It is only this case where the cost is > starting to outweigh the benefits. > > > > Why would it be huge? Why should we encourage the use of plain objects > intead of classes? It feels to JS-specific. Future runtimes might have > strict type-safety. > > > > -Alex > > > > On 1/6/19, 10:05 PM, "Harbs" <harbs.li...@gmail.com> wrote: > > > > Personally, I would like to have us support TypeScript-type > interfaces where plain objects that have the correct properties pass the > check.[1] > > > > I have no idea how difficult this would be for SWF-compatible code, > but even if it’s supported for JS-only code, that would be a huge > production booster. > > > > My $0.02, > > Harbs > > > > [1] > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.typescriptlang.org%2Fdocs%2Fhandbook%2Finterfaces.html&data=02%7C01%7Caharui%40adobe.com%7Cfa1d122c210040df53f508d67466149e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636824379116010891&sdata=aZ9bIxvZMH%2B0uk146HD81DtGSZbFgOgDB%2FE7sf3%2BXA0%3D&reserved=0 > < > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.typescriptlang.org%2Fdocs%2Fhandbook%2Finterfaces.html&data=02%7C01%7Caharui%40adobe.com%7Cfa1d122c210040df53f508d67466149e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636824379116010891&sdata=aZ9bIxvZMH%2B0uk146HD81DtGSZbFgOgDB%2FE7sf3%2BXA0%3D&reserved=0 > > > > > >> On Jan 7, 2019, at 6:03 AM, Alex Harui <aha...@adobe.com.INVALID> > wrote: > >> > >> I just fixed a bug in the compiler, and now we are getting more of > these implicit coercion errors because the recent Google Closure Typedefs > now specify interfaces as parameters to certain contructors (or maybe they > always did and the compiler is now getting better at catching these errors). > >> > >> Code that looked like: > >> > >> var blob:Blob = new Blob([text], { type: 'text/plain' }); > >> > >> or > >> > >> customEvent = new window.Event(type, {bubbles: bubbles, cancelable: > cancelable}); > >> > >> now results in a compiler error because the plain objects don't > implement whatever interface of properties the constructor expects. I > think Google Closure did this so that the properties in the plain object > don't get renamed by the minifier. > >> > >> One solution, that Yishay tried in this commit was simply to lie to the > compiler and tell it that the plain object was a BlobPropertyBag. And > while that is the "least amount of code" solution, I didn’t like that > solution because it looks funny to have lots of places in our code where a > plain object is coerced to a type. > >> > >> So, I went and created classes that implement BlobPropertyBag and other > interfaces. I didn't like adding the weight of additional class > definitions but the classes I did were small, just a couple of properties. > However, for Event,there is a pretty big list of properties just to specify > bubbles and cancelable. The compiler was not catching that plain object > before, but now with the fix I just made it will. And I’m not sure it is > worth adding a large class with lots of properties. > >> > >> So, I thought of a third idea which is a hack between what Yishay tried > and the interface implementations I did, which is to have a factory that > returns an instance of the interface, but actually returns a plain object. > As long as no code actually tests that the instance implements the > interface, it should work. And that would localize the coercion of a plain > object to an interface in relatively few known places in our code. > >> > >> The pattern would be to create a top-level factory function() unless it > makes sense to add it to a class so for Blob it might look like: > >> > >> /** > >> * @royaleignorecoercion BlobPropertyBag > >> */ > >> public function createBlobPropertyBag():BlobPropertyBag > >> { > >> // return a plain object but fool the compiler into thinking it is an > implementation of the interface > >> return {} as BlobPropertyBag; > >> } > >> > >> IMO, this also future-proofs the code in case we ever run where there > is runtime type-checking and need to someday return a real concrete > instance that implements the interface. > >> > >> Thoughts? > >> -Alex > >> > >> > >> On 12/26/18, 11:02 PM, "Yishay Weiss" <yishayj...@hotmail.com> wrote: > >> > >> Sounds good, feel free to revert. > >> > >> > >> > >> ________________________________ > >> From: Alex Harui <aha...@adobe.com.INVALID> > >> Sent: Thursday, December 27, 2018 3:43:45 AM > >> To: dev@royale.apache.org; comm...@royale.apache.org > >> Subject: Re: [royale-asjs] branch develop updated: Fix implicit > coercion error > >> > >> I don't think we should hack it like this. Casting a plain object to > a type makes the code look strange, and it might not minify correctly. I > have a different fix I hope to put in shortly where we actually pass in an > instance of the BlogPropertyBag. > >> > >> -Alex > >> > >> On 12/26/18, 6:57 AM, "yish...@apache.org" <yish...@apache.org> > wrote: > >> > >> This is an automated email from the ASF dual-hosted git > repository. > >> > >> yishayw pushed a commit to branch develop > >> in repository > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitbox.apache.org%2Frepos%2Fasf%2Froyale-asjs.git&data=02%7C01%7Caharui%40adobe.com%7Cfa1d122c210040df53f508d67466149e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636824379116010891&sdata=yJZu6zHWQqpZacfNbaA2XjUrY5%2BRjSFlxyLRWaDxnTo%3D&reserved=0 > >> > >> > >> The following commit(s) were added to refs/heads/develop by this > push: > >> new 2f127d4 Fix implicit coercion error > >> 2f127d4 is described below > >> > >> commit 2f127d459ee807f197950e11af947c623c270369 > >> Author: DESKTOP-RH4S838\Yishay <yishayj...@hotmail.com> > >> AuthorDate: Wed Dec 26 16:57:33 2018 +0200 > >> > >> Fix implicit coercion error > >> --- > >> > .../src/main/royale/org/apache/royale/storage/file/DataOutputStream.as | 2 > +- > >> > .../apache/royale/storage/providers/AndroidExternalStorageProvider.as | 2 > +- > >> > .../royale/org/apache/royale/storage/providers/WebStorageProvider.as | 2 > +- > >> 3 files changed, 3 insertions(+), 3 deletions(-) > >> > >> diff --git > a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as > b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as > >> index cff76eb..55eab71 100644 > >> --- > a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as > >> +++ > b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/file/DataOutputStream.as > >> @@ -117,7 +117,7 @@ public class DataOutputStream extends > EventDispatcher implements IDataOutput > >> public function writeText(text:String):void > >> { > >> COMPILE::JS { > >> - var blob:Blob = new Blob([text], { type: > 'text/plain' }); > >> + var blob:Blob = new Blob([text], { type: > 'text/plain' } as BlobPropertyBag); > >> _fileWriter.write(blob); > >> } > >> COMPILE::SWF { > >> diff --git > a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as > b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as > >> index ea79a5b..cf05a73 100644 > >> --- > a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as > >> +++ > b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/AndroidExternalStorageProvider.as > >> @@ -199,7 +199,7 @@ package org.apache.royale.storage.providers > >> > _target.dispatchEvent(newEvent); > >> }; > >> > >> - var blob:Blob > = new Blob([text], { type: 'text/plain' }); > >> + var blob:Blob > = new Blob([text], { type: 'text/plain' } as BlobPropertyBag); > >> > fileWriter.write(blob); > >> }, function(e):void { > >> var > errEvent:FileErrorEvent = new FileErrorEvent("ERROR"); > >> diff --git > a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as > b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as > >> index 1632bfa..dd9c84c 100644 > >> --- > a/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as > >> +++ > b/frameworks/projects/Storage/src/main/royale/org/apache/royale/storage/providers/WebStorageProvider.as > >> @@ -199,7 +199,7 @@ package org.apache.royale.storage.providers > >> > _target.dispatchEvent(newEvent); > >> }; > >> > >> - var blob:Blob > = new Blob([text], { type: 'text/plain' }); > >> + var blob:Blob > = new Blob([text], { type: 'text/plain' } as BlobPropertyBag); > >> > fileWriter.write(blob); > >> }, function(e):void { > >> var > errEvent:FileErrorEvent = new FileErrorEvent("ERROR"); > >> > >> > >> > >> > >> > >> > > > > > > > >