The Missing Tool In Scripting World
Few days ago I was having beers with @aadsm and @sleistner and we were talking about languages and, of course, JavaScript too.
That night I have realized there is a missing process, or better tool, that could open new doors for JavaScript world.
Engineers from different companies are trying on daily basis to perform this optimization at runtime, or better Just In Time, but believe me that's not easy task, specially with such highly dynamic language as JavaScript is.
Even worst task is the tracing option: at runtime each reference is tracked and if its type does not change during its lifecycle, the code could be compiled as native one.
The moment a type, an object structure, or a property changes, the tracer has to compile twice or split the optimizations up to N exponential changed performed in a single loop so that this tracer has to be smart enough to understand when it's actually worth it to perform such optimization, or when it's time to drop everything and optimize only sub tasks via JIT.
There is also a disadvantage in this process ... if some unexpected input occurs runtime, the whole logic could crash, be compromised, or exit unexpectedly.
Latter part is what will rarely happen in scripting world, but it can be also a weak point for application stability and reliability since things may keep going but who knows what kind of disaster an unexpected input could cause.
Try to imagine these tests cover 100% of code, a really hard achievement on web due feature detections and different browsers behaviors, but absolutely easy task in node.js, Rhino, CouchDB, or any JS code that runs in a well known environment.
The differential Mocking approach to solve the web situation requires time and effort but also what JS community is rarely doing, as example, is to share mocks of same native objects in both JS and DOM world. This should change, imo, because I have no idea how many different mocks of XMLHttpRequest or document we have out there and still there is no standard way to define a mock and listen to mocked methods or properties changes in a cross platform way.
Let's keep trying imagine now ... imagine that our tests cover all possible input accepted in each part of the module.
Try to imagine that our tests cover exactly how the application should behave, accordingly with all possible input we want to accept.
It's insane to use typeof or instance of operator per each argument of each function .... this will kill performances, what is not impossible is to do it in a way that, once in production, these checks are dropped.
Since with non tested input we can have unexpected behaviors, I would say that our application should fail or exit the moment something untested occurs .... don't you agree?
How many less buggy web apps we would have out there ? How much more stable and trustable could we be ?
The process I am describing does not exist even in statically typed languages since in that case developers trust unconditionally the compiler, avoiding runtime misbehavior tests ... isn't it ?
Just try to imagine ...
That night I have realized there is a missing process, or better tool, that could open new doors for JavaScript world.
The Runtime Nightmare
The main difference between scripting languages and statically typed one is the inability to pre optimize or pre compile the code before it's actually executed.Engineers from different companies are trying on daily basis to perform this optimization at runtime, or better Just In Time, but believe me that's not easy task, specially with such highly dynamic language as JavaScript is.
Even worst task is the tracing option: at runtime each reference is tracked and if its type does not change during its lifecycle, the code could be compiled as native one.
The moment a type, an object structure, or a property changes, the tracer has to compile twice or split the optimizations up to N exponential changed performed in a single loop so that this tracer has to be smart enough to understand when it's actually worth it to perform such optimization, or when it's time to drop everything and optimize only sub tasks via JIT.
Static Pros And Cons
As I have said, statically typed languages can perform all these optimizations upfront and create, as example, LLVM byte code which is highly portable and extremely fast. As example, both C and C++ can be compiled into LLVM.There is also a disadvantage in this process ... if some unexpected input occurs runtime, the whole logic could crash, be compromised, or exit unexpectedly.
Latter part is what will rarely happen in scripting world, but it can be also a weak point for application stability and reliability since things may keep going but who knows what kind of disaster an unexpected input could cause.
What If ...
Try to imagine we have created unit tests for a whole application or, why not, just for a portion of it (module).Try to imagine these tests cover 100% of code, a really hard achievement on web due feature detections and different browsers behaviors, but absolutely easy task in node.js, Rhino, CouchDB, or any JS code that runs in a well known environment.
The differential Mocking approach to solve the web situation requires time and effort but also what JS community is rarely doing, as example, is to share mocks of same native objects in both JS and DOM world. This should change, imo, because I have no idea how many different mocks of XMLHttpRequest or document we have out there and still there is no standard way to define a mock and listen to mocked methods or properties changes in a cross platform way.
Let's keep trying imagine now ... imagine that our tests cover all possible input accepted in each part of the module.
Try to imagine that our tests cover exactly how the application should behave, accordingly with all possible input we want to accept.
It's insane to use typeof or instance of operator per each argument of each function .... this will kill performances, what is not impossible is to do it in a way that, once in production, these checks are dropped.
Since with non tested input we can have unexpected behaviors, I would say that our application should fail or exit the moment something untested occurs .... don't you agree?
How many less buggy web apps we would have out there ? How much more stable and trustable could we be ?
The process I am describing does not exist even in statically typed languages since in that case developers trust unconditionally the compiler, avoiding runtime misbehavior tests ... isn't it ?
The Point Is ...
We wrote our code, we created 100% of code coverage and we created 100% of expected inputs coverage. At this point the only thing we are missing to compile JavaScript into LLVM is a tool that will trace, and trace only, the test while it's executed and will be able to analyze all cases, all types, all meant behaviors, all loops, and all function calls, so that everything could be statically compiled and in separate modules ... how great would this be if possible today?Just try to imagine ...
Comments
Post a Comment