-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Annotated tail call syntax (still valid es6/5) #11
Comments
btw, I think it maybe a proper time to introduce annotations in Javascript, annotations are particular useful hints for compiler optimizations, but does not change its semantics significantly |
PTC is about making You would not implement |
@bterlson of course, it is a toy example, any decent transpiler can make self recursive call into a loop. The real case is for mutual tailcall. I believe it will be helpful to make JS a better backend |
Currently when we compile OCaml into Javascript, in some cases, it will cause stackoverflow(Ocaml support tailcall properly), I believe other transpiler will suffer the same issue. Having annotated valid ES6/5 syntax tail call will make JS a better functional language backend. |
The OCaml case is interesting... If an OCaml transpiler emitted a |
I've already made this case here: #1 (comment) And here: #4 In both cases, the tone of the responses in the threads seems to suggest doubt/disagreement that this position matters (much). :/ |
@bterlson Here is an example of stackoverflow due to lack of tailcall support on the JS backend: https://github.com/ejgallego/jscoq/issues/13 tailcall is an advanced feature that I don't mind a verbose explicit syntax, but it would be much helpful to make it valid ES6/5 Syntax, since it takes time for browser to catch up |
A bunch of transpilers would appreciate a valid syntax (not just ocaml), like scalajs, typescript, babel, clojurescript, purescript, elm etc. |
I don't believe that ignoring the tail aspect is a valid implementation. It changes behavior by making the space complexity asymptotically lower, which is a significant, non-backwards-compatible change, both for browsers with fixed and variable sized stacks (and both of these are widespread). Using an invalid syntax for tail calls is, therefore, a feature, not a bug. Independent of STC vs PTC: Developers should not write code using tail calls unless they are executing in an environment which will eliminate the stack frame. Transpilers should not eliminate |
Tailcall is an essential feature in functional language, think about in c you don't have loop. Introducing an incompatible syntax will make it not relevant in next 3 years IMHO. We can have something like /**tailcall**/ return ... The transpiler can do it best to convert tailcall into loop offline, which means in most old browsers, it still work, but in modern browsers, it can handle larger data. |
What is the difference between Fwiw, no one here is contesting the utility of tail calls. We recognize that this is essential for some languages. What I don't yet understand is why it's valuable that PTC syntax is valid non-PTC syntax (ie. why ES6 syntax and semantics are preferable to those proposed here). |
@bterlson thanks for recognizing the importance of tailcall ! For a functional language which tries to target JS as a backend, it will typically do two things: first it will try to pin-point which functions are (mutual)recursive functions and try to convert it into a loop. However, when it can not (some mutual recursive tail calls can get really complex), it can emit code like this /*@taicall@*/ return ... Note that it's not that user can choose not to use tailcall, since in pure functional languages, recursion is the only proper control flow. It helps a lot if it's still valid ES5 syntax, since transpilers don't need maintain two backends. As I said before, maybe it is time to introduce a comment based annotation syntax. FYI, ocaml itself supports tailcall, no matter user have |
I'm not sure I understand. Even with no syntax at all, you /still/ have to figure out when it's safe to deploy code that relies on tail calls, since it just WON'T RUN without an engine's implementation of PTC. There is no way to cheat around that, regardless of syntax, if the loop conversions don't work in all cases. |
Specifically, "we have to figure out the client's capability to deploy proper code" is true in either proposal. Either you have to test whether a client has PTC (presumably by calling a recursive function a suitable number of times to observe whether PTC is enabled) or STC (presumably by detecting if |
Basically it is impossible to compile proper functional languages into Javascript without tailcall support(unless you go with trampoline, which is too slow in practice). However, given the smartness the transpiler can be, it is not a problem in practice (especially when the data is not too large), so for functional languages which rely on tailcall, it will do its best effort on old browsers which does not support tailcall, but it expects modern browsers eventually catch up. |
I don't think best effort makes much sense here. It would only work for toy programs, not real applications. Until it is supported natively in the target browser, it is important that cross-compilers use a trampoline or other strategy when the user code calls for a tail call. |
Even the whole ocaml compiler is bootstrapped in browser, I don't think if it is |
@bobzhang, the counter argument is that syntactic tail calls actually help the users, because it gives them a way to have their assumptions checked. That should particularly aid those who have not fully mastered tail calls yet. |
@rossberg-chromium That's fair. May major concern is that If you have a look at es6 vs es5 from the traspiler's point of view, the only major language semantic differences is tailcall. It is a pity that we step back on this point. |
@bobzhang and |
@ljharb that's runtime feature, not language feature :-) |
ES2015 includes tons of core language semantics changes. Basic operations like If you want to write future-proof code, and are OK with current browsers, then you can simply continue to not use the tail call feature. |
There is a drawback of current syntax tail call proposal, it is not valid ES6/5 syntax. which means people will not take it serious for years. Even a transpiler could not take advantage of it.
Suppose we have some syntax like this( I know this is a horrible syntax, but hope my ideas are clear):
The code above is still valid code under any JS engine, it just happens to more efficient when tailcall enabled.
FWIW, ocaml has a tailcall attribute like this
I believe having a valid es6/5 syntax will help the adoption of tailcall, all transpilers(including babel or typescript) will beneift from it
The text was updated successfully, but these errors were encountered: