@Josh: I'm going to try to answer both of your posts in this one reply. IMO, having more restrictive rules for AS is "ok" if we can make it PAYG, which it sort of is. You should be able to use plain objects if you don't want Closure's minification. I think you can set your compiler options to make that happen. Then if you want Closure's minification/renaming, you will need to do more work. IMO, if you are building truly enterprise-class applications, you want to get rid of plain objects. And if you want to future-proof code to target future runtimes, you want to move away from dynamic objects. Royale should give you choices. Maybe we should change our default compiler options so that don't turn on Closure's renaming. I think way back we felt that we wanted to show how small the output would be for a good first impression.
From your other post, you mentioned replacing interfaces in the typedefs with Object. I think that may be the right thing to do. It is risky to try to add a new concept to ActionScript like a "dynamic interface". Changing that kind of thing in the compiler involves the BURM which is still a very difficult piece of code. It is more under our control, and easier for our committers to understand, if we change ExternC (the typedefs compiler) to generate annotations on the APIs. I would recommend we use metadata to record the "interface" for a parameter of type Object. The transpiler will check the metadata. And then you will be able to use plain objects more. I think we should still provide classes and conversion functions for those who do want to get rid of Object literal and try to go fully strong-typed. The JS transpiler can strip out conversion functions. That is easy compared to trying to change how types are matched in an assignment or parameter. FWIW, an AVM developer took the time to fully strongly-type a chunk of code for Flash several years ago and it had a significant boost in performance. The same may be true in JS and future runtimes someday. IMO, the Royale framework developers will still need to write code to support Closure's renaming. I think it is possible and not too onerous. But if others want to drop Closure renaming entirely, then that's what we'll do. I've been assuming that Closure advanced optimization has some pay-off that folks will want and Royale being the best at surviving those optimizations would be an advantage for us, but I could certainly be wrong. Thoughts? -Alex On 1/10/19, 9:43 AM, "Josh Tynjala" <joshtynj...@apache.org> wrote: > 3) That other classes linked into your final JS file can dictate what keys are renamed Again, we're seeing Closure's advanced renaming causing trouble and making us jump through hoops. We've already seen that it makes JSON difficult to use, and Harbs needed a new compiler option added so that he could write normal code. It makes passing object literals to native JS APIs more difficult for the same reason. It made it so that public variables on classes now need a compiler warning! We keep being forced to use ActionScript with very restrictive rules, and it feels like a different language now. Most JavaScript developers use minifiers, but few use Closure's advanced renaming because they don't want to deal with all of this. - Josh On 2019/01/10 08:47:24, Alex Harui <aha...@adobe.com.INVALID> wrote: > Let me try to respond to everyone in this one post: > > @Josh: I don't think we would ever disallow the use of Object literals in Royale. But I expect there to be more and more reasons to avoid using them over time. Already we know that: > 1) The IDE's don't really know what to code-hint when you type "{" > 2) That Closure Compiler will rename keys in plain objects > 3) That other classes linked into your final JS file can dictate what keys are renamed > In the future, I expect that some runtime environments will be faster with sealed classes than dynamic classes. There were cases in Flash where dynamic was slower than sealed classes. So, I am still planning a compiler option to tell you where you are using Objects in case you want to know. > > @Harbs: I am not a language/compiler expert, but I do not think that languages typically have literals that are automatically coerced to types. I believe the AST node tree of the literal can be reduced/compiled/transpiled without knowing that it is part of an assignment statement. I believe your proposal is to change that, and I am concerned about the compiler performance and language issues that could arise from that. I would strongly recommend we don't do that and stay with constructs that are more common to other languages. > > After reading all of the other input on this thread, I would recommend instead that we leverage conversion functions for those who like to use Object literals. I am also changing my proposal to only do this hack for Event and MouseEvent's init objects because they have too many rarely used properties in their init object. For BlobPropertyBag and other small classes, we should just create classes that implement the interface. I've done internal classes so far, but we should probably make them public classes. > > The reason I think conversion functions are best is because AS already has them and JS does too, and future runtimes/platforms will probably allow them. In AS, there is a XML conversion function as well as an XML class. JS is proposing (in the link from Mark) to have ToInt8 and similar functions for typed arrays. So, you could have a toEventInit() conversion function (or we could just call it EventInit and put it in a package and further, auto-import that package). It would take an Object literal and return the converted object (or lie, just like the factory functions will). Then the code to write looks like: > > var blob:Blob = new Blob([text], toBlobPropertyBag{ type: 'text/plain' }); > > Or even: > > var blob:Blob = new Blob([text], BlobPropertyBag{ type: 'text/plain' }); > > The conversion function would be written like this: > > /** @royaleignorecoercion BlobPropertyBag */ > package org.apache.royale.conversion > { > > public function toBlobPropertyBag(value:Object):BlobPropertyBag > { > return value as BlobPropertyBag; > } > } > > Royale-config.xml could auto import org.apache.royale.conversion.* so you wouldn't have to import anything in your source code > > Thoughts? > -Alex > > On 1/7/19, 9:53 AM, "Josh Tynjala" <joshtynj...@apache.org> wrote: > > > Avoid plain objects entirely if you can. Future runtimes will support class definitions, but may not support object literals. > > Object literals are a core part of the ActionScript language, though. ActionScript sits in this really cool place where it can mix strong typing and dynamic typing. I'd hate to see ActionScript lose one of its advantages. If ActionScript targeted a future runtime where it had to disable features like object literals, that would be tragic. > > Now, I'm not saying that it's a bad idea to agree on stricter rules for developers working on the Royale framework. That's smart. However, I strongly believe app developers and developers of other libraries should be able to use the ActionScript language they've grown to love over the years, including the dynamic parts. > > > Google is sort of acknowledging my philosophy by replacing the init objects with interfaces. > > As I understand it, Google Closure Compiler's implementation of interfaces is more like TypeScript's than ActionScript's. With Closure, I don't think that you have to explicitly implement an interface because the compiler is smart enough to check object literals. > > - Josh > > On 2019/01/07 10:41:16, Alex Harui <aha...@adobe.com.INVALID> wrote: > > Harbs, > > > > I am only proposing this hack specifically for the init object issue (#4). > > > > For every other scenario, I have always and will probably always recommend classes. If you recall, I have proposed adding a "super-strict" warning in the compiler that catches all references to plain object to make it easier to replace every place you are using plain object with a class. Google is sort of acknowledging my philosophy by replacing the init objects with interfaces. > > > > If class definitions were smaller, I would probably have just created classes for each init object interface, but I don't want to add the weight and clutter doc and code-hinting. It just isn't worth it for the obscure init options. > > > > Avoid plain objects entirely if you can. Future runtimes will support class definitions, but may not support object literals. > > > > -Alex > > > > On 1/7/19, 2:29 AM, "Harbs" <harbs.li...@gmail.com> wrote: > > > > To me, there’s a bigger issue we’re grappling with: > > > > For better or for worse, dealing with untyped objects is a reality in web development. Web is and will be an important target for Royale for the foreseeable future. We need a pattern which best deals with this. > > > > Untyped object can come in the form of: > > 1. JSON > > 2. API requests which have specific parameters. > > 3. Interop with external JS. (Something I’ve had to deal with a lot.) > > 4. Native JS APIs such as the case of BlobPropertyBag that we’re discussing as an example. > > > > We need to settle on a pattern which deals with these cases. Alex is saying that using “as” every time we need to avoid a compiler complaining is not a good pattern. I agree with that. > > > > Alex is proposing factory functions. > > I’m proposing “dynamic interfaces” or “typedef” declarations as Greg pointed out. > > > > HTH, > > Harbs > > > > > On Jan 7, 2019, at 12:01 PM, Olaf Krueger <m...@olafkrueger.net> wrote: > > > > > > Hi, > > > sorry for annoying you but there's something which I'd like to understand: > > > > > > If I understand it correctly, the issue is caused by the recent Google > > > Closure thing which expects typed constructor parameters now. > > > If I got it right, Google Closure is used for the JS target only. > > > > > > So, it seems to me that this is a "JS target only" issue which is currently > > > resolved by Yishay's commit [1]. > > > Even if this is maybe not nice, my understanding is that this is only needed > > > for the JS target, within the "COMPILE::JS" sections. > > > > > > So, my question is why this issue needs to be resolved "cross-platform" for > > > other targets. > > > Is it because of an assumption that other targets may also expect typed > > > constructor parameters? > > > > > > The other question is why we are allowing the usage of these plain objects > > > as parameters at all. > > > Alex probably already explained it but I don't get it entirely. > > > Is it why it would be too much overhead to create all those needed classes > > > and interfaces? > > > (In case of performance, or in case of effort, ...?). > > > > > > Thanks in advance! > > > Olaf > > > > > > [1] > > > var blob:Blob = new Blob([text], { type: 'text/plain' } as BlobPropertyBag); > > > > > > > > > > > > > > > -- > > > Sent from: https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-royale-development.20373.n8.nabble.com%2F&data=02%7C01%7Caharui%40adobe.com%7Ca6a4773efce94859ecf508d677231c0f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636827390014656932&sdata=09BHnsCzxxwNnMIwWbkE2aO4GmJ98sHimSPXqUmYKo8%3D&reserved=0 > > > > > > > > > > >