Hologram v0.8.0 is out! This release brings JavaScript interoperability - the most requested feature since the project’s inception. You can now call JS functions, use npm packages, interact with Web APIs, instantiate classes, and work with Web Components - all from Elixir code, with zero latency on the client side.
Special thanks to @robak86 for extensive help with the JS interop API design. Thanks to @ankhers for contributing Web Components support and to @mward-sudo for a language server compatibility fix and :unicode module refactoring.
Thank you @mward-sudo! It was a massive amount of work indeed - I think @robak86 aged about 5 years during the API design sessions alone. The fact that he still answers my phone calls is either a testament to his patience or evidence that he hasn’t figured out how to block a number yet… Or maybe he just picks up out of morbid curiosity about what I’ll ask next.
I’m sure y’all considered this as part of the design but I can’t help but think how clean it’d be to drop the brackets and create the list as an implementation detail under the hood.
Unfortunately there are two problems with dropping the brackets:
List ambiguity - JS.call(:obj, :processList, [1, 2, 3]) becomes impossible to distinguish between one argument (the array [1, 2, 3]) and three separate arguments.
Arity clash - JS.call/2 calls a standalone function, JS.call/3 calls a method on a receiver. If args were optional, JS.call(:Decimal, :toNumber) could be either call/2 with one arg or call/3 with no args.
The explicit args list is also consistent with Kernel.apply/3, which always requires the args list. I actually considered naming it JS.apply at one point, so the parallel is intentional.