Closed coffeescriptbot closed 6 years ago
From @mitar on 2016-12-13 03:02
I do not like this. It goes against the CoffeeScript indentation semantics. Why would this:
item, index <- someArray.forEach
console.log item
Be clearer than:
someArray.forEach (item, index) ->
console.log item
From @edemaine on 2016-12-13 03:32
I'm no expert, but I think the idea is to avoid deep nesting of callbacks. Instead of the current
$.get 'ajaxtest', (data) ->
$('.result').html data
$.get 'ajaxprocess', data, (processed) ->
$('.result').append processed
you could write
data <- $.get 'ajaxtest'
$('.result').html data
processed <- $.get 'ajaxprocess', data
$('.result').append processed
(based on an example from LiveScript docs)
This seems neat, but I wonder about two things: how do you specify which argument to put the callback (LiveScript uses _
to specify this, which conflicts with Underscore and CS REPL...), and how do you deal with error callbacks? (I don't see what LiveScript does with error callbacks... maybe not a big deal?)
One other thing: the operator @celicoo is proposing is apparently <-!
from LiveScript. There are also <-
, <~
, <--
, <~~
, which are all unindenting versions of the corresponding right-arrow operator...
From @lydell on 2016-12-13 06:09
jashkenas/coffeescript#2762
From @DomVinyard on 2016-12-13 09:56
I'm no expert, but I think the idea is to avoid deep nesting of callbacks
async/await
From @edemaine on 2016-12-13 15:03
@lydell Nice find. Presumably, any discussion should continue over there.
@DomVinyard I'm still learning Promises/async/await (I was corrupted too early by IcedCoffeeScript and now I can't figure it out). Can the example above be written cleanly with async/await? It definitely can with IcedCoffeeScript:
await $.get 'ajaxtest', defer data
$('.result').html data
await $.get 'ajaxprocess', data, defer processed
$('.result').append processed
Hopefully I'm not too biased toward IcedCoffeeScript which I already know, but to me this feels a lot more clear notationally, in particular which argument is the callback. Also you can do awesome things like await for ... defer
which you couldn't do with <-
as I understand it.
From @celicoo on 2016-12-13 16:28
@mitar The main idea of backcalls is to avoid callbacks hell, as the title (and @edemaine) suggest, i use Livescript and it is fantastic.
@DomVinyard I don't think it's necessary to compare backcall's benchmark to async/await to know that backcalls are definitely faster, once it doesn't generate any kind of code, it's just pure callbacks.
From @mitar on 2016-12-13 19:24
Hm, so if the idea is just to remove indentation level, maybe we could just have an operator for that? Like:
someArray.forEach (item, index) -> \
console.log item
From @nilskp on 2016-12-14 16:40
Any callback is trivially converted into a Promise.
To use @edemaine's example:
$.get 'ajaxtest', (data) ->
$('.result').html data
$.get 'ajaxprocess', data, (processed) ->
$('.result').append processed
That could be rewritten into:
new Promise (cb) -> $.get 'ajaxtest', cb
.then (data) ->
$('.result').html data
new Promise (cb) -> $.get 'ajaxprocess', data, cb
.then (processed) ->
$('.result').append processed
From @mitar on 2016-12-14 19:53
Any callback is trivially converted into a Promise.
Not if the first argument of the callback is an error.
From @nilskp on 2016-12-14 20:03
@mitar, why not? Can you give an example?
From @mitar on 2016-12-14 20:06
I mean, if you just blindly pass promise's resolve
as a callback to an API, which passes an error as the first argument, then your promise will resolve with an error, and never reject correctly.
From @nilskp on 2016-12-14 20:09
Of course. Nothing should be done blindly. It has to match the method signature.
From @mitar on 2016-12-14 20:15
So, can you show the above example of converting to Promises with function calls which expect node.js style callbacks with errors as first arguments? Maybe then is clearer why backcalls are cleaner.
From @nilskp on 2016-12-14 20:17
I'm not familiar with node.js style callbacks. If you provide an example, I'll rewrite it to promises, and we can see if it's doable.
From @nilskp on 2016-12-14 20:23
Here's a couple of ways I can think of:
# Function type 1
fOne = (value, cb) -> # something
new Promise (cb) -> fOne 42, cb
.then (error, result) ->
if error? then alert "Oh noes: #{error}"
else alert result
# or
new Promise (cb) -> fOne 42, cb
.then (errorOrResult) ->
if resultOrError instanceof Error then alert "Oh noes: #{resultOrError}"
else alert result
alternatively:
# Function type 2
fTwo = (value, errCB, resCB) -> # something
new Promise (resCB, errCB) -> fTwo(42, errCB, resCB)
.then (result) -> alert result
.catch (err) -> alert "Oh noes: #{err}"
From @DomVinyard on 2016-12-15 15:24
Vote to close with no action
From @GeoffreyBooth on 2016-12-19 07:51
Reminds me a lot of https://github.com/jashkenas/coffeescript/pull/4144, with many of the same issues that that proposal had.
From @Inve1951 on 2017-07-27 03:41
From @cloudle on 2017-10-07 16:24
Really love to see jashkenas/coffeescript#4144. It definitely should be on CS2.. pipe really shine on many other places.
From @celicoo on 2016-12-12 23:45
Would be great if we had backcalls as livescript:
CS6:
ES6: