Type coercion is involved, but that's not mutually exclusive with polymorphism. Type coercion itself is a polymorphic operation, since it applies to parameters of multiple different types.
you have a function that takes something that is polymorphic in the sense that I can be added. A string and a number aren't the same type, but they share some kind of interface.
The term is not merely a recent appropriation. Parametric polymorphism is a concept from functional programming and formal type theory, with application far beyond just JavaScript.
the code for the example is just ~100 LOC - it's a showcase of a library called "Iroh", which brings dynamic code analysis to the whole ES5 syntax. If you're wondering what the essence behind the example is, then I really recommend to give these links a try:
I'm not sure how relevant my code is, but I did something similar using Proxies[0] for a game engine built on javascript (RPG Maker MV) following some useful advice I found online[1].
I presume that the same type of logic could be used to make more powerful loggers.
Proxies are definitely a nice catch, but won't allow full code instrumentation. Iroh doesn't use proxies but patches the submitted code to allow full code instrumentation including call tree recording and full ES5 code support.
If you're wondering what the patched code looks like:
Interesting! One of the main challenges of Iroh was to always keep track of all branches (calls, ifs, loops..) correctly. All listeners provide an indent value which represents the level of branch deepness and can be used in code flow visualizations. When your program is inside a function->loop->if and a return is inside there, then you have to manually leave if->loop until you get to according function to return on.
edit: I figured it out myself, just replace ASSIGN with MEMBER ! Awesome!
I've been thinking of how to do this statically for a while now, but dynamically is good enough, as it still will be able to point out the bug before you even start debugging. I think this is game changing and will make things like Typescript feel like stone-age. I'm currently working on an editor/IDE for JavaScript and I can just add a check-box like "static typing" and you'll get warnings every time a variable or function parameter change type.
As for actual implementations, I used it in a small analyzer for RPG Maker MV plugins[1] that roughly does what you want with very little actual code[2].
yes, but you have to manually select which objects to watch, eg in your script, it goes through the window object and adds the Proxy observer to a set of classes. But Iroh doesn't use Proxies. With Iroh you can trigger an event for example "Iroh.MEMBER" and check if the property is undefined.
I only observe certain classes because observing anything and everything is not convenient. Nothing prevents you from doing
`window = new Proxy(window, handler)`
(or more generally, to Proxy the global object) where the handler replaces anything with a Proxied version of it either once a trap triggers (yu-gi-oh style) or immediately.
Then again, I did not write the specification for `Proxy` and Iroh is cool. It probably has plenty of use-cases where Proxy would not do a good job. I'm just showing what we have right now.
I think the interest for the HN crowd should be the enabling technology, which is Proxy[0]. It provides a way for user code to trigger on property definition & access, as well as function invocation. Dynamic debugging is a good first application of this technology, but is by no means comprehensive.
This is great. Is there anything similar for Scala applications? I had wanted to do something similar to reverse an ETL pipeline of a codebase I do not have control of. The idea would be to send some data through the pipeline and watch it as it is stored in variables and transformed.
29 comments
[ 3.0 ms ] story [ 64.5 ms ] threadyou have a function that takes something that is polymorphic in the sense that I can be added. A string and a number aren't the same type, but they share some kind of interface.
[0]: https://docs.oracle.com/javase/tutorial/java/IandI/polymorph...
http://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.h...
also, polyfill (hip) === shim (no longer hip)
the code for the example is just ~100 LOC - it's a showcase of a library called "Iroh", which brings dynamic code analysis to the whole ES5 syntax. If you're wondering what the essence behind the example is, then I really recommend to give these links a try:
Github: https://github.com/maierfelix/Iroh
More examples: https://maierfelix.github.io/Iroh/examples/index.html
Cheers!
I presume that the same type of logic could be used to make more powerful loggers.
[0]:https://github.com/ldd/plugin-analyzer [1]:http://exploringjs.com/es6/ch_proxies.html#sec_proxies-expla...
If you're wondering what the patched code looks like:
Input:
Output:More importantly, you are entirely right about ES5 support. Babel doesn't polyfill Proxies, and the google polyfill is not as powerful.
edit: I figured it out myself, just replace ASSIGN with MEMBER ! Awesome!
I've been thinking of how to do this statically for a while now, but dynamically is good enough, as it still will be able to point out the bug before you even start debugging. I think this is game changing and will make things like Typescript feel like stone-age. I'm currently working on an editor/IDE for JavaScript and I can just add a check-box like "static typing" and you'll get warnings every time a variable or function parameter change type.
Here's a minimal fiddle doing just that: https://jsfiddle.net/6v82dj01/
As for actual implementations, I used it in a small analyzer for RPG Maker MV plugins[1] that roughly does what you want with very little actual code[2].
[0]: http://exploringjs.com/es6/ch_proxies.html#sec_proxies-expla... [1]: https://github.com/ldd/plugin-analyzer [2]:https://github.com/ldd/plugin-analyzer/blob/master/plugin-an...
`window = new Proxy(window, handler)`
(or more generally, to Proxy the global object) where the handler replaces anything with a Proxied version of it either once a trap triggers (yu-gi-oh style) or immediately.
Then again, I did not write the specification for `Proxy` and Iroh is cool. It probably has plenty of use-cases where Proxy would not do a good job. I'm just showing what we have right now.
0 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
//> const $$STx89 = Iroh.stages["$$STx89"]; //> var $$frameValue = void 0; //> $$STx89.$45(27) //> $$STx89.$44($$frameValue = i = $$STx89.$35(25, 0, "i", null, $$STx89.$30(26, 23))); //> $$STx89.$46(27, $$frameValue) //>
Well done.
https://sequential.js.org/live.html#DYewhgJgFA5AFgFwQBwM4C4D...