
ToffeeScript – CoffeeScript with async syntax and some additional features - ilaksh
https://github.com/jiangmiao/toffee-script
======
mistercow
I've never really understood the problem with "callback hell" that people talk
about. The biggest annoyance I've seen from it is that indentation can get a
little out of hand, but the examples I've seen could be fixed with smarter
coding rather than new language features.

~~~
camus2
well, imagine you have 4/5 sequential db calls, and for each async call need
to write a success callback and a failure callback ... async lib helps though
defer/await programming style would be a better option.

------
barrkel
It looks like a CPS transform, which can be very useful; but I think it's
something you'd rather opt in to rather than apply everywhere.

------
stewbrew
Is there something similar (i.e. syntactic sugar/macros for defining callbacks
that provide similar functionality) for "plain" javascript as base language?

~~~
gfxmonk
StratfiedJS
([http://onilabs.com/stratifiedjs](http://onilabs.com/stratifiedjs)) does this
and more[0]. It's more heavyweight than a set of macros, but we believe the
features warrant that.

[0] including a module system, fork-join parallelism, try/catch and stacktrace
support even for async code.

(disclaimer: I joined Oni Labs to work on SJS, after struggling with my own
coffeescript fork for 6 months)

------
Hengjie
Could someone please explain what's Callback hell and why Toffee-script is
doing to resolve it? The compiled JS code looks harder to read than using
callbacks to me.

~~~
jacobolus
“Callback hell” is when you need to do many asynchronous actions / call
several asynchronous APIs with inputs to each call depending on the delayed
results of some other call(s), and you are using callbacks to organize your
control flow. Often you end up with either a large set of named functions
being passed around as callbacks, or a deeply nested hierarchy of anonymous
callbacks. Either way, control flow can be difficult to follow or reason
about, both when reading the code and when debugging. Even simple tasks take
large amounts of boilerplate code.

The generated code _is_ using callbacks. The point is that instead of writing
something like (a cleaner, but still ugly, version of) the generated code on
the right, you’d instead write the (quite easy to read) toffeescript code on
the left.

That said, I think coffeescript’s “it’s just javascript” slogan (and goal of
generating readable code) is one of its most important features. It has to be
quite a bit harder to debug than the coffeescript version, since the generated
code has control flow that’s so different looking from the input.

~~~
joeblau
What did you use to create the generated JavaScript? I'm still new to this and
trying to figure out out.

~~~
michaelmior
toffeescript is a language which has a compiler that generates Javascript.

------
tluyben2
[http://opalang.org/](http://opalang.org/) has something like that. I do find
it a lot easier than all other proposed solutions so far. Wish a language like
Clojure(script) would have something like this for general use with async
processes/callbacks (in Java/.NET running threads, in JS this).

~~~
mtrimpe
You might want to take a look at Javelin. It sounds like that's what you're
looking for. The talk InfoQ talk about it is probably the best place to start.

~~~
tluyben2
Thanks, I'm checking that!

------
MichaelGG
Is this just like C#'s async, F#'s mon^H^H^H workflows aka computation
expressions, Haskell's do notation?

~~~
gregwebs
Not at all in the case of Haskell whose IO is automatically async. You write
IO in a normal blocking style and your current thread will automatically be
suspended and resumed. You are just required to do it in the IO monad since
the language is pure.

------
EGreg
While it may be slick, it does violence to the call stack which will grow
tremendously with the size of your functions. Plus, it's very hard to optimize
any of the generated code since it contains so many jumps and context
switches.

------
doublerebel
I'm actually more excited about the Ruby-style pattern matching. The last time
I had to do that in Coffee I was wishing for that syntax.

I'll need to see more real world examples to decide if Toffee's async syntax
is better than Iced.

------
Kiro
I don't understand what the Basic example is supposed to do:

var x, y, _this = this;

a(b, function() { x = arguments[0], y = arguments[1]; return console.log(x,
y); }); ReferenceError: a is not defined

~~~
michaelmior
a is a function which would already be defined at this point. Anything after
the exclamation point is arguments to the callback function. Any following
code is wrapped in an anonymous function passed as the final argument to the
function a.

Anything on the left-hand side of the assignment (in this case, x and y) are
arguments passed to this anonymous function. A concrete example of why you
would do this would probably be useful.

