Skip to content
This repository was archived by the owner on Feb 19, 2018. It is now read-only.

CS2 Discussion: Features: Callback hell solution: backcalls #64

Closed
celicoo opened this issue Dec 12, 2016 · 20 comments
Closed

CS2 Discussion: Features: Callback hell solution: backcalls #64

celicoo opened this issue Dec 12, 2016 · 20 comments

Comments

@celicoo
Copy link

celicoo commented Dec 12, 2016

Would be great if we had backcalls as livescript:

CS6:

item, index <- someArray.forEach
console.log item

ES6:

someArray.forEach(function(item, index) {
  console.log(item);
});
@celicoo celicoo changed the title Backcalls Callback hell solution: backcalls Dec 13, 2016
@mitar
Copy link

mitar commented Dec 13, 2016

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

@edemaine
Copy link

edemaine commented Dec 13, 2016

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...

@lydell
Copy link

lydell commented Dec 13, 2016

@DomVinyard
Copy link

I'm no expert, but I think the idea is to avoid deep nesting of callbacks

async/await

@edemaine
Copy link

@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.

@celicoo
Copy link
Author

celicoo commented Dec 13, 2016

@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.

@mitar
Copy link

mitar commented Dec 13, 2016

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

@nilskp
Copy link

nilskp commented Dec 14, 2016

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

@mitar
Copy link

mitar commented Dec 14, 2016

Any callback is trivially converted into a Promise.

Not if the first argument of the callback is an error.

@nilskp
Copy link

nilskp commented Dec 14, 2016

@mitar, why not? Can you give an example?

@mitar
Copy link

mitar commented Dec 14, 2016

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.

@nilskp
Copy link

nilskp commented Dec 14, 2016

Of course. Nothing should be done blindly. It has to match the method signature.

@mitar
Copy link

mitar commented Dec 14, 2016

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.

@nilskp
Copy link

nilskp commented Dec 14, 2016

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.

@nilskp
Copy link

nilskp commented Dec 14, 2016

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}"

@DomVinyard
Copy link

Vote to close with no action

@GeoffreyBooth
Copy link
Collaborator

GeoffreyBooth commented Dec 19, 2016

Reminds me a lot of jashkenas/coffeescript#4144, with many of the same issues that that proposal had.

@Inve1951
Copy link

#4144 feels a lot better imo

@cloudle
Copy link

cloudle commented Oct 7, 2017

Really love to see jashkenas/coffeescript#4144.
It definitely should be on CS2.. pipe really shine on many other places.

@coffeescriptbot coffeescriptbot changed the title Callback hell solution: backcalls CS2 Discussion: Features: Callback hell solution: backcalls Feb 19, 2018
@coffeescriptbot
Copy link
Collaborator

Migrated to jashkenas/coffeescript#4957

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants