`return await foo defer bar` possible?
I am working with streams using the highland.js library, and I want to use ICS to flatten the christmas tree code shape when using flatMap.
I need to return a stream inside each function.
Here is an example:-
directories = readdirp root: root, depth: 0, entryType: 'directories'
directories = h(directories).flatMap (entry) ->
{fullPath} = entry
findReadme(fullPath).flatMap (file) ->
file = h fs.createReadStream file.fullPath, 'utf8'
comment = file.split().take(1)
await comment.flatMap defer firstLine
if !_(firstLine).contains("#")
h [{entry, firstLine}]
else
h []
So I would need to do something like the following, where return await would return the return the value of the function (which would only make sense for sync functions i.e. streams/promises).
return await h(directories).flatMap defer entry
{fullPath} = entry
return await findReadme(fullPath).flatMap defer file
h [file]
...
I ran up against a similar issue today: A function containing an await block can no longer return a value. For instance, saving the handle to an i/o request in order to abort it. A simplified example:
Regular Coffee
headersHelper = (cb) ->
options = {url: "https://google.com"}
return http.request options, (err, res) ->
cb res.headers
headers = []
addHeaders = (h) -> headers.push h
handles = (headersHelper addHeaders for i in times)
... elsewhere ...
user.on "search.change", -> handle.abort() for handle in handles
Iced
headersHelper = (cb) ->
options = {url: "https://google.com"}
await http.request options, defer err, res
cb res.headers
Could be...?
headersHelper = (cb) ->
options = {url: "https://google.com"}
return await http.request options, defer err, res
cb res.headers
Of course this would only work at the first await block, it's a bit awkward. However, not returning a value at all goes against Coffee's philosophy of every function being an expression.
I understand the reasoning behind "Awaits No Longer Work As Expressions", where previously the async result was returned from the await block. Here we are simply looking for synchronous return from the expression directly following await.
Looking deeper at @vjpr's suggestion to flatten a chain of expressions by returning at each await block, seems like if anything should be default behavior. If we consider the regular coffee version of his proposition, the default would be to return the function result unless explicitly designed otherwise:
directories = h(directories).flatMap (entry) ->
{fullPath} = entry
findReadme(fullPath).flatMap (file) -> ## IMPLICIT RETURN ##
file = h fs.createReadStream file.fullPath, 'utf8'
comment = file.split().take(1)
comment.flatMap, (firstLine) -> ## IMPLICIT RETURN ##
if !_(firstLine).contains("#")
h [{entry, firstLine}]
else
h []
So the question in my mind is now, must it be possible to avoid returning a value from await? There could be a vawait ("void await") that returns void (i.e. current behavior).