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" <[email protected]> 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 <[email protected]> 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" <[email protected]> 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 <[email protected]>
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%7C8b3226bfed304f67e5eb08d674c91213%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636824804315710037&sdata=clHAQCFDGeGvihF4TGWRwlGzy5DQtmFI5iEiKoiu%2Fys%3D&reserved=0
>
>
>
>