Live data from Hacker News

Tail-call optimization added to 6to5 compiler

github.com

1–10 of 33 posts

Re: Tail-call optimization added to 6to5 compiler

#2
I was literally complaining today about the fact that no-one seems to have yet implemented that part of the ES6 standard yet[1], and yet now here it is.

As someone chiefly interested in .js for it's 'functional curious' side, the new features in ES6 have me really excited.

Re: Tail-call optimization added to 6to5 compiler

#3
post #2

I was literally complaining today about the fact that no-one seems to have yet implemented that part of the ES6 standard yet[1], and yet now here it is. As someone chiefly interested in .js for it's 'functional curious' side, the new features in ES6 have me really excited.

Which parts of es6 would you call 'functional curious'?

Re: Tail-call optimization added to 6to5 compiler

#5
post #3
post #2

I was literally complaining today about the fact that no-one seems to have yet implemented that part of the ES6 standard yet[1], and yet now here it is. As someone chiefly interested in .js for it's 'functional curious' side, the new features in ES6 have me really excited.

Which parts of es6 would you call 'functional curious'?

What I mean is, JS in general is not a Lisp, nor is it a functional language.

But it does have a number of key basics in place. It has anonymous, first-class functions and objects. It has a very handy function composition syntax (chaining dot-notation feels almost like Haskell sometimes, if uglier). It has map(), filter(), and reduce(). You can, somewhat torturously, wrangle a Y-combinator in it even.

But in practice, it's still missing some basic toys. The lack of TCO means that while yes you have handy function composition and a basic smattering of first-class functions, recursive solutions aren't really viable, which makes many classic functional approaches impossible when it comes to implementing the stuff that isn't there yet. You have to kludge around it with mutation and for loops and such. As well, you also run into issues with the object-oriented focus at times: first-class functions are all well and good, but not that useful when so many things aren't functions but methods or operators, requiring even more heavy use of lambdas than I would in a Lisp.

ES6 goes further in the direction of supporting the functional style and making it more pleasant to write. Arrows offer neater lambda syntax, let and const offer better control of scope and enforced immutable variables, and of course offering proper TCO opens up a lot easier implementation of classic recursive functions. I'm even a little curious about the possibilities of iterators and generators; my experience implementing an RNG in Heresy using Racket's generators suggested that they can prove a powerful tool in the functional programmer's toolbox for solving certain kinds of problems traditionally thought to be quite non-trivial to write from a functional approach.

ES6 does come a little closer to actually living up to Crockford's hype with these changes. It's something I'm very excited to keep learning and playing with, and it was something of a relief to find a niche for the happy little Schemer in me in an otherwise very mainstream, mostly-imperative language.

Re: Tail-call optimization added to 6to5 compiler

#6

I wonder if this implementation idea is general enough that it could be added to clojure anr script.

Clojure has recur, which is tail recursion that detects not being in the tail. I prefer that to implicit tails with quiet , expensive fails like scheme.

Re: Tail-call optimization added to 6to5 compiler

#7
post #6

I wonder if this implementation idea is general enough that it could be added to clojure anr script.

Clojure has recur, which is tail recursion that detects not being in the tail. I prefer that to implicit tails with quiet , expensive fails like scheme.

Tail call optimization is more than optimized tail recursion.

Recur provides an explicit form of support for the latter, but not the former.

Re: Tail-call optimization added to 6to5 compiler

#8
post #5
post #3

Earlier quoted context omitted.

Which parts of es6 would you call 'functional curious'?

What I mean is, JS in general is not a Lisp, nor is it a functional language. But it does have a number of key basics in place. It has anonymous, first-class functions and objects. It has a very handy function composition syntax (chaining dot-notation feels almost like Haskell sometimes, if uglier). It has map(), filter(), and reduce(). You can, somewhat torturously, wrangle a Y-combinator in it even. But in practice…

There is a lot of good stuff in there.

I have to ask, though: what the tap-dancing Christ was the purpose of the new Symbol objects? They're completely alien to any other symbols implementation I've seen.

They aren't global by default, they don't compare equally to one another, and even the global ones can't really be used for, say, KV lookups in a global table. WTF?

Re: Tail-call optimization added to 6to5 compiler

#9
post #6

Earlier quoted context omitted.

Clojure has recur, which is tail recursion that detects not being in the tail. I prefer that to implicit tails with quiet , expensive fails like scheme.

Tail call optimization is more than optimized tail recursion . Recur provides an explicit form of support for the latter, but not the former.

I wonder whether you could add a tail-call construct to Clojure, not just a tail-recursion construct. But I guess, to preserve JVM semantics, you'd need a trampoline or so.

Re: Tail-call optimization added to 6to5 compiler

#10
post #5

Earlier quoted context omitted.

What I mean is, JS in general is not a Lisp, nor is it a functional language. But it does have a number of key basics in place. It has anonymous, first-class functions and objects. It has a very handy function composition syntax (chaining dot-notation feels almost like Haskell sometimes, if uglier). It has map(), filter(), and reduce(). You can, somewhat torturously, wrangle a Y-combinator in it even. But in practice…

There is a lot of good stuff in there. I have to ask, though: what the tap-dancing Christ was the purpose of the new Symbol objects? They're completely alien to any other symbols implementation I've seen. They aren't global by default, they don't compare equally to one another, and even the global ones can't really be used for, say, KV lookups in a global table. WTF?

I believe they're similar to uninterned symbols in Lisp, i.e. what you get in Common Lisp from make-symbol (or gensym). The main intended use-case seems to be to get "private" property names, by conjuring up a fresh name-like thing is not equal to any other name-like thing, and not findable/enumerable in the usual way either. You can then monkey-patch that into a class or do whatever other nefarious thing you were planning.

I agree it's a somewhat confusing name, since interned symbols are the more familiar kind of symbol in other languages, especially in the modern era (older Lisps made more extensive use of uninterned symbols).

Post reply on HN