Well, some says JS is just JS and I disagree with that statement because it is al about how you write JS. JQuery is popular this days but limited developers by slowing down runtime over 100x times.

Impossible to make mobile web application with acceptable performance level when mobile platform is another factor of 10 in slow down.

How do you thing your solution perform vs goog. This is my only concern I was trying to rise from begining of Falcon JS thread. Looking at your examples they may feel simple indeed, but this very structure:

<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="hello-world"src="amd/hello-world.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="as3/trace"src="amd/as3/trace.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="as3/is"src="amd/as3/is.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="classes/com/acme/B"src="amd/classes/com/acme/B.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="classes/com/acme/A"src="amd/classes/com/acme/A.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="classes/com/acme/I"src="amd/classes/com/acme/I.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="classes/com/acme/sub/IOther"src="amd/classes/com/acme/sub/IOther.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="classes/com/acme/sub/ISub"src="amd/classes/com/acme/sub/ISub.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="shim"src="amd/shim.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="runtime/defineClass"src="amd/runtime/defineClass.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="as3/bind"src="amd/as3/bind.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="runtime/defineInterface"src="amd/runtime/defineInterface.js">
<scripttype="text/javascript"charset="utf-8"async=""data-requirecontext="_"data-requiremodule="shims"src="amd/shims.js">

Is way beyond vanilla JS approach.

Dan

On 12/20/2012 8:59 PM, Frank Wienberg wrote:
Hi Erik,

my proposal is not at all about UI frameworks, so I'll try to answer the
part about (not) using "goog" / Google Closure Compiler.

I agree on the strengths of GCC as being "not only a JS optimiser, it's an
actual compiler" when you want to write class-oriented JavaScript code
manually and maybe use other parts of the "goog" library, and then optimize
your code for deployment.
But I see its strengths turned to weaknesses in our setting. Let me explain
why.

    - *waste:* no need to parse and reverse-engineer JavaScript when we
    already have a detailed class-oriented model of what we want to generate.
    Optimizing JavaScript code directly from the ActionScript source gives us
    much more knowledge about context (thus we don't need any proprietary
    annotations!) and thus at least the same potential to optimize, and even
    faster because we save the time to generate and parse the intermediate
    format.
    - *JavaScript readiness:* I think my prototype shows how easy it is to
    simulate ActionScript language features in modern JavaScript. The central
    utility function that implements a small domain-specific language to
    declare a class (defineClass.js) has about 60 lines, and it implements more
    AS3 language features than your "goog"-approach currently does (interfaces
    with is/as, lazy class initialization for static code, real private
    members). A few polyfills are only required to support IE < 9. Goog's
    base.js file alone has over 1500 lines, and even if you leave out comments,
    it is still factor 10 larger. The minified complete application is only 5k.
    Isn't that small enough?
    - *tool/vendor dependency:* we add a dependency on a complex tool that
    will also have bugs which we cannot fix. I do not replace "goog" / GCC
    by "multiple libraries", but only use one other tool, namely RequireJS, as
    an AMD implementation that can invoke an optimizer (comes with Uglify 2,
    but can also use GCC or any other JS optimizer you want) after linking.
    Using AMD, we rely on an open standard and not something Google invented
    and maintains.
    - *separation of concerns:* "goog"/GCC does at least five things for
    FalconJS: 1. simulate classes / inheritance / super calls, 2. solve
    cross-browser issues, 3. manage dependencies (require / provide), 4. link
    all code needed for an application and 5. minimize/optimize JavaScript
    code. Instead of relying on one tool "to rule them all", I chose a "best of
    breed" approach, allowing a "make or buy", and if "buy", choose the best
    tool, *for each concern*. Currently, my answers are 1. too easy in
    generated ECMAScript 5 to bother, 2. use ES5 polyfills for IE < 9, 3. use
    AMD module layout (implemented by RequireJS), 4. use the RequireJS
    "optimizer" tool (rather a "linker"), 5. use any JavaScript minifier you
    like. The last answer will probably later change to 5. optimize JS code
    directly during generation (quick win examples: shortening variable names,
    simple function inlining).
    - *testing:* using GCC does not free us from testing optimized code, so
    this is no argument against generating optimized code directly in the
    cross-compiler. But testing both versions is no big deal, as once set up,
    we expect the exact same results/behavior when running the production code
    as when running the debug code, so we can run the same integration tests
    twice.
    - *source maps:* letting GCC generate a source map does not help, as it
    can only produce a source map from production JavaScript code back to the
    "human readable" JS code we fed in. In contrast, we want a direct (!)
    mapping from production JavaScript code back to ActionScript source code.
    While I wouldn't recommend using the "goog" library, I *do* recommend
    GCC as a JavaScript optimizer and as a Java library to generate source maps
    (I already used it successfully in the Jangaroo compiler to generate
    generated-JS->AS3 source maps!).

I think we can only really compare runtime performance and generated code
size of the two approaches when FalconJx has made some progress and we can
cross-compile a larger code base for testing.
Independent from concrete performance results, my feeling is that in the
long term, we are better off relying only on AMD for dependencies / linking
and on polyfills to make old IE as ECMAScript-5-compatible as possible.
Like in Mikes argumentation about the JBurg / BURM approach, I think that
learning the goog API, GCC's annotations and how to generate JS code so
that GCC can really optimize it and chaining our compiler with GCC
introduces unnecessary complexity. Please have a look at my JS prototype
and convince yourself how simple it is and that such magic is not
necessary! The few things you have to know / learn to understand that
format are JavaScript with some ECMAScript 5 extensions and AMD in its
purest form (something.js: define([dep1, dep2], function(dep1, dep2) { code
using dep1, dep2; return something; })). If we could agree to drop IE < 9
support, that would even make all the shim.js and polyfill stuff
(Object.js, Array...js, Function.bind.js) go away. The few files to
simulate is, as, type casts, method binding and trace would also be needed
when using "goog".
This is also a call to Mike and everybody else who thinks that digging into
the prototype would take 2 weeks or more. There's really only a few lines
of code, and some even have comments! ;-) And everything's there to test
and debug live in the browser, without even downloading, installing or
anything...
Here are the links again: live
demo<http://fwienber.github.com/as-js-runtime-prototype/> (if
you had a look at it before, please clean cache for latest version),
source<https://github.com/fwienber/as-js-runtime-prototype>,
download <https://github.com/fwienber/as-js-runtime-prototype/tags>

Greetings
-Frank-


On Thu, Dec 20, 2012 at 8:22 PM, Erik de Bruin <e...@ixsoftware.nl> wrote:

Hi,

To complete the party, a few brief comments:

- at the moment, I'm not sure what approach to the eventual UI
frameworks (AS and JS side) will take. FlexJS is one but it doesn't
(yet) have the feel of something that meets the standards that Flex
users have come to expect.

- I'm sure that Google's Closure Tools provide us with a lot of the
language features that native JS is missing. The ones it doesn't
(easily) provide, we can have the compiler "replace" as that's what
compilers do, I understand ;-) After we've finished the unit tests for
FalconJx, we can focus on "goog" compatible JS output and create an -
I expect very small - utility class to make up for the difference.

- As we are using "goog" and Closure annotations to match AS language
features, using the rest of Google's Closure Tools is really low
hanging fruit. The Closure Compiler is not only a JS optimiser, it's
an actual compiler which provides much of the features usually only,
if at all, available if you use multiple libraries. The final piece is
the Closure Builder, which takes an entire "intermediate" (i.e. human
readable) JavaScript project and, combining all the tools in the
Closure set, outputs one JS file, culling out dead code and optimising
the remaining code. I've done a lot of studying on the Closure Tools
the last few weeks and have become convinced they will provide us with
a solid language base to start building the UI frameworks on.

Having said all that, I really welcome Frank's POC and I think that we
will soon be at a point where we can converge all our efforts and
figure out a common way forward, accepting input from all previous
trails.

Mike, a question: can the FalconJx compiler tell when a 'regular'
public variable is being accessed and when a public property (with
"get" and "set" methods) is being accessed? I'm asking this because if
it can, it would make it a whole lot easier and would require a whole
lot less workarounds to get that part of the language translation
done...

TL;DR: for now I'm moving ahead with "goog" as the basis for the
language translation, but I look forward to combining the various
efforts and starting the build of a suitable replacement for the Flex
SDK :-)

EdB



On Thu, Dec 20, 2012 at 7:23 PM, Michael Schmalle
<apa...@teotigraphix.com> wrote:
Quoting Frank Wienberg <fr...@jangaroo.net>:

Hi folks,

as mentioned in another thread, I have been working on a new JavaScript
"runtime", which is what I call the way the generated JavaScript code
looks
and works like. While this thread's title has [FalconJx] in it, there is
no
reason the proposal could not be used for FalconJS, too, but I
understood
that for now, using Google Closure is a given.

Hi Frank,

Just so you know I read this, I wanted to write a couple things.

FalconJS uses the JBurg BURM which was donated by Adobe. I choose the
route
of an AST visitor framework that is handcoded for the sake of development
ease and allowing myself to try something with the time I can a lot for
this
development. As far as I see, FalconJS is not being developed by anybody
beyond the fact I read everywhere that it produces "js code". I guess if
FlaconJS is going to be considered an alternative, there has to be
developers that can work on it, I'm not one of them. I spent 1+ years
learning antlr grammar and not about to figure out all the other
prerequisites of the FalconJS code.


That being said, I have to be honest that I am in no position to either
agree or argue with what you have produced. Besides the years of hands on
experience you have with JavaScript and ActionScript issues. I would say
you
have a thing or to to add here. :)


It seems that right now, there are a handful of developers/community
members
involved in this topic of AS -> JS. I don't know what will change that
but,
it seems like we will need to decide on something that works sooner than
later.


The truth is, for me to understand what you have done and have an
opinion I
would probably need 2 or more weeks to understand what you have done. :)

I'm probably in the position of, "Show me what you want to generate
based on
the semantics involved and I will generate it" mode.

For me, my goal as it stands is to use what I have written to generate
fully
compilable ActionScript source code from Falcon's AST model. Once I have
unit tested this, I can focus on the JavaScript side without thinking
about
what I have to implement to cover all the AS conversions.

I wonder what Erik has to say... I would be interested since he has put
time
into investigation as well.

So in closing, I really have not developed javascript applications. I'm
interested in this project because having an HTML/JS target for Flex
would
allow me to do some of my audio experiments with an HTML Flex framework
in
the future for mobile applications.

This allows me the excuse for myself to put as much time into it as I
am. :)
Mike


I had the following design goals:

    - Support ActionScript 3's "differentiator" features: private
members,
    interfaces + is/as, lazy class initialization, method binding,
    getter/setter functions
    - work in IE < 9 (except for getter/setter functions)
    - Produce debuggable JavaScript code that can also be optimized for
    deployment. The debuggable code should be very similar to the
original
    ActionScript source code for every line containing executable code
    - Dependency management: load/bundle only the needed classes. Every
    compilation unit to debug should load as a separate request
    - Minimal to no runtime overhead, even in debug mode
    - Support trace()


I took the following design decisions:

    - For private members, a mix of JavaScript lexical scope and field
    renaming like in Jangaroo is used
    - To implement an efficient "is" operator, all interfaces a class
    implements are determined once for the class. I use a prototype chain
to
    inherit the interfaces implemented by the super class
    - Lazy class initialization uses a very efficient technique refined
by
    Olaf Kummer: Wherever a constructor or non-private static member is
called,
    the "self-destructing" class initialization function is checked for
    existence and, if still existing, called ("guarded" call)
    - Method binding is again borrowed from the Jangaroo Runtime: the
bound
    function is "cached" at the object under a different but unique name
so
    that it keeps its identity. This is important e.g. to be able to
remove
    event listeners
    - Getter/setter functions map to Object.defineProperty("...", { get:
    ..., set: ...}), thus no support in IE < 9
    - To make everything else work in IE < 9, I use polyfills for
ECMAScript
    5 Object, Array and Function API
    - For keeping generated code in separate JS files, expressing
    dependencies between these files, loading them separately at runtime
and
    linking them statically into a single JavaScript file, I chose to use
    Asynchronous Module Definitions (AMD) and RequireJS (version 2.1.2)
as
the
    concrete implementation of AMD. AMD is preferred over CommonJS
because
it
    better fits web applications, as e.g. argued here:


http://blog.millermedeiros.com/amd-is-better-for-the-web-than-commonjs-modules/To
link and optimize the application, RequireJS provides an optimizer
tool
    simply called "r.js".
    - To conditionally load polyfills (for IE < 9), I use the "shim"
    RequireJS plugin
    - To achieve minimal runtime overhead, I only use helper functions to
    define the class structure once (defineClass and defineInterface). As
soon
    as the complete application structure is set up, all code executed is
    inlined
    - Since all modern browsers seem to support a "console" object with a
    "log" method, trace() is simply implemented to check for the
existence
of
    console.log() by trial-and-error (try... catch). It then
String-converts
    and concatenates all its arguments like its ActionScript sibling


*About the Example*

To specify how I think FalconJx-generated JavaScript output should look
like, I created an ActionScript example, consisting of two classes and
three interfaces. Every language feature supported by the new runtime
format gives an appearance in the code (well, I didn't add a private
static
method, because it works like a private method, only simpler).
The whole thing is a public GitHub project at
https://github.com/fwienber/as-js-runtime-prototype.
To download all files in one go as a zip or tar.gz, please use the tag
page: https://github.com/fwienber/as-js-runtime-prototype/tags.

A live demo is available on the corresponding GitHub pages at
http://fwienber.github.com/as-js-runtime-prototype/index.html
 From there, you can reach all ActionScript example sources and the
proposed
JavaScript equivalent (so far, hand-coded :-)).
To see the example in action, use the three bottom links which start the
same application in three flavors:

    - debug: Each JS file corresponding to an AS class or interface and
the
    main bootstrap file is loaded with a single request. This gives you a
nice
    1:1 mapping of source to output in the JavaScript debugger.
Additionally,
    there are some "infrastructure" files: require.js itself, the
RequireJS
    plugin "shim" (shim.js, shims.js), my AS3 runtime helpers
defineClass.js
    and defineInterface.js, and a couple of built-in AS3 functions (bind,
as,
    is, trace). If loading in IE < 9, the shim plugin loads several ES5
    polyfills.
    - linked: The whole application is merged into one JS file using the
    RequireJS optimizer "r.js" without optimizations. Thus you only have
two
    requests: require.js and hello-worls-all.js are loaded. In IE < 9,
the
    polyfills are still loaded one-by-one (I didn't bother to optimize
this
    case, but of course, it can be done).
    - minified: Same as "linked", only that require.js and
    hellow-world-all.js are minified by Uglify2. This can easily be
achieved
    using "r.js" with the parameter optimize=uglify2.


For the demo, I redirected trace() from the JavaScript console
(backed-up
in trace-console.js) to the DOM, so that you can see the log messages
directly.

Just look into the code and observe how it works in Firebug or any other
JavaScript debugger of your choice, and let me know if anything is
unclear,
missing or if you need more reasoning for the design decisions taken.
I know there are still several issues to be fleshed out (e.g.
interaction
with "native" JavaScript or package-scope variables, just to name two),
but
I think the current state is a solid core of how a modern, efficient,
self-contained, extensive and still concise JavaScript runtime format
for
Apache Flex could look like.
Please tell me what you think!

Have fun,
-Frank-

--
Michael Schmalle - Teoti Graphix, LLC
http://www.teotigraphix.com
http://blog.teotigraphix.com



--
Ix Multimedia Software

Jan Luykenstraat 27
3521 VB Utrecht

T. 06-51952295
I. www.ixsoftware.nl


Reply via email to