Live data from Hacker News

Porffor: A from-scratch experimental ahead-of-time JS engine

porffor.dev

41–50 of 148 posts

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#43

I have thought about doing this and I just can't get around the fact that you can't get much better performance in JS. The best you could probably do is transpile the JS into V8 C++ calls. The really cool optimizations come from compiling TypeScript, or something close to it. You could use types to get enormous gains. Anything without typing gets the default slow JS calls. Interfaces can get reduced to vtables or may…

You say you have "thought about doing this"..."[but] you can't get much better performance", then describe the approach requiring things that are described first-thing, above the fold, on the site.

Did the site change? Or am I missing something? :)

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#44

It's awesome to see how more JS runtimes try to approach Wasm. This project reminds me to Static Hermes (the JS engine from Facebook to improve the speed of React Native projects on iOS and Android). I've spent a bit of time trying to review each, so hopefully this analysis will be useful for some readers. What are the main commonalities and differences between Static Hermes and Porffor? * They both aim for JS test26…

Just wanted to say I really appreciated the high-quality comparison. How something compares to existing work is my #1 question whenever I read an announcement like this.

Thanks!

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#45

It's awesome to see how more JS runtimes try to approach Wasm. This project reminds me to Static Hermes (the JS engine from Facebook to improve the speed of React Native projects on iOS and Android). I've spent a bit of time trying to review each, so hopefully this analysis will be useful for some readers. What are the main commonalities and differences between Static Hermes and Porffor? * They both aim for JS test26…

You make it sound bad to rely on LLVM.

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#46

It's awesome to see how more JS runtimes try to approach Wasm. This project reminds me to Static Hermes (the JS engine from Facebook to improve the speed of React Native projects on iOS and Android). I've spent a bit of time trying to review each, so hopefully this analysis will be useful for some readers. What are the main commonalities and differences between Static Hermes and Porffor? * They both aim for JS test26…

Contributor for Porffor here! I think this is a great comparison, but Porffor does technically support promises, albeit synchronously. It's a similar approach to Kiesel, https://kiesel.dev/.

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#47

It's awesome to see how more JS runtimes try to approach Wasm. This project reminds me to Static Hermes (the JS engine from Facebook to improve the speed of React Native projects on iOS and Android). I've spent a bit of time trying to review each, so hopefully this analysis will be useful for some readers. What are the main commonalities and differences between Static Hermes and Porffor? * They both aim for JS test26…

Good comparison and thanks! A few minor clarifications: - Porffor isn't fully self-hosted yet but should be possible hopefully! It does partially compile itself for builtins (eg Array.prototype.filter, Math.sin, atob, ...) though. - As of late, Porffor does now support basic async/promise/await! Not very well yet though.

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#48

I have thought about doing this and I just can't get around the fact that you can't get much better performance in JS. The best you could probably do is transpile the JS into V8 C++ calls. The really cool optimizations come from compiling TypeScript, or something close to it. You could use types to get enormous gains. Anything without typing gets the default slow JS calls. Interfaces can get reduced to vtables or may…

Contributor to Porffor here! I actually disagree, there's quite a lot that can be improved in JS during compile time. There's been a lot of work creating static type analysis tools for JS, that can do very very thorough analysis, an example that comes to mind is [TAJS](https://www.brics.dk/TAJS/) although its somewhat old.

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#49
post #32

Earlier quoted context omitted.

I think the even bigger elephant in the room is that TypeScript's type system is unsound. You can have a function whose parameter type is annotated to be String and there's absolutely no guarantee that every call to that function will pass it a string. This isn't because of `any` either. The type system itself deliberately has holes in it. So any language that uses TypeScript type annotations to generate faster/small…

So - I know this in theory, but avoided mentioning it because I couldn’t immediately think of any persuasive examples (whereas subtype polymorphism is a core, widely used, wholly unrestricted property of the language) that didn’t involve casts or any/unknown or other things that people might make excuses for. Do you have any examples off the top of your head?

Here's an example I constructed after reading the TS docs [1] about flow-based type inference and thinking "that can't be right...".

It yields no warnings or errors at compile stage but gives runtime error based on a wrong flow-based type inference. The crux of it is that something can be a Bird (with "fly" function) but can also have any other members, like "swim" because of structural typing (flying is the minimum expected of a Bird). The presence of a spurious "swim" member in the bird causes tsc to infer in a conditional that checks for a "swim" member that the animal must be a Fish or Human, when it is not (it's just a Bird with an unrelated, non-function "swim" member).

    type Fish = { swim: () => void };
    type Bird = { fly: () => void };
    type Human = { swim?: () => void; fly?: () => void };

    function move(animal: Fish | Bird | Human) {
      if ("swim" in animal) {
        // TSC infers wrongly here the presence of "swim" implies animal must be a Fish or Human
        onlyForFishAndHumans(animal); 
      } else {
        animal;
      }
    }

    function onlyForFishAndHumans(animal: Fish | Human) {
      if (animal.swim) {
        animal.swim(); // Error: attempt to call "not-callable".
      }
      // (receives bird which is not a Fish or Human)
    }

    const someObj = { fly: () => {}, swim: "not-callable" };
    const bird: Bird = someObj;

    move(bird);

    // runtime error: [ERR]: animal.swim is not a function
[1] https://www.typescriptlang.org/docs/handbook/2/narrowing.htm...
Post reply on HN