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&amp;data=02%7C01%7Caharui%40adobe.com%7Cfa1d122c210040df53f508d67466149e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636824379116010891&amp;sdata=aZ9bIxvZMH%2B0uk146HD81DtGSZbFgOgDB%2FE7sf3%2BXA0%3D&amp;reserved=0
> <
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.typescriptlang.org%2Fdocs%2Fhandbook%2Finterfaces.html&amp;data=02%7C01%7Caharui%40adobe.com%7Cfa1d122c210040df53f508d67466149e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636824379116010891&amp;sdata=aZ9bIxvZMH%2B0uk146HD81DtGSZbFgOgDB%2FE7sf3%2BXA0%3D&amp;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&amp;data=02%7C01%7Caharui%40adobe.com%7Cfa1d122c210040df53f508d67466149e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636824379116010891&amp;sdata=yJZu6zHWQqpZacfNbaA2XjUrY5%2BRjSFlxyLRWaDxnTo%3D&amp;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");
> >>
> >>
> >>
> >>
> >>
> >>
> >
> >
> >
>
>

Reply via email to