-
Notifications
You must be signed in to change notification settings - Fork 157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Please add supports to "async await" keywords #683
Comments
Long time ago I opened question about async callbacks. So I vote - Yes we need it. But I have concerns about async await syntax. I think we should use promises |
I disagree about JSX, since it's just as easy to use the traditional LiveScript syntax, anyways. And it's quite nice. # Taken from an example from the second link
{table, thead, tr, th, tbody} = React.DOM
product-table = React.create-class do
render: ->
last-category = null
table null,
thead null,
tr null,
th null, 'Name'
th null, 'Price'
tbody null,
@props.products |> map ->
if it.category isnt last-category
product-category-row do
category: it.category
key: it.category
else
last-category = it.category
product-row do
product: it
key: it.name |
The JSX compiler should allow one to write code in LiveScript (or CoffeeScript etc.) instead of JavaScript, not the other way around. And it's better to put different requests in different issues. |
My point was that plain LiveScript doesn't necessarily need such syntax for Also, keep in mind that CoffeeScript's JSX compiler is a completely
|
@IMPinball My answer was intended for the OP. Sorry for not making that clear. I agree with you. |
@blvz No problem. |
What syntax do you propose when the function has parameters? |
maybe let it simply be closer to the es7 syntax(make 'async, await' a reserved words):
what do you think? |
👍 |
Keep in mind making it a non-contextual reserved keyword like that |
@IMPinball , you are right, "async" should be only treated as a keyword only if it is located before the function declaration. It will probably solve this problem. |
Maybe treat it initially similar to yield, but throw if it doesn't validate Although I do caution in that the whole thing is still yet to be Thankfully, async-await appears to be stabilizing, but I don't think it'll Just a few notes worth mentioning. (I'm okay with this specific case.) On Wed, Jun 24, 2015, 03:33 Yuriy Yazlovytskyy [email protected]
|
I'm looking forward this feature! |
I have a branch up that implemented this feature. I was unable to incorporate a method to determine if the |
+1 |
+100 |
At least caolan/async doesn't have a default export, so the idea of prefixing wouldn't be impractical. But, I have a question: in a language with backcalls, function composition, and concise function syntax, why couldn't we do something like this? JavaScript needs /**
* It does return the return value of the function, but forces async calling of
* the callback and async handling of errors after the first async call.
*
* f = async (await, ...args, next) !->
* if args.length == 1 => throw new Error 'bad!' # throw sync error
* v <-! await fs.readFile \foo, \utf8 # do an async call
* if isBad v => throw new Error 'bad!' # throw async error
* next v # return the value
*
* f (err, data) ->
* process.exit 1 if err?
* console.log data
*
* You can even make methods out of this. You just have to remember
* to bind each backcall.
*
* class Reader
* (@file) ->
* read: async (await, ...args, next) !->
* v <~! await fs.readFile @file, \utf8 # do an async call
* next v # return the value
*/
# Example utility combinator
async-reduce = curry async (await, f, start, xs, next) !->
unless next?
[next, xs] = [start, xs]
[start, ...xs] = xs
switch xs.length
# Fast path simple cases
| 0 => throw new TypeError 'Reduce of empty array with no initial value'
| 1 => await f, start, next
# The meat
| _ =>
i = 0
await f, start, xs[0], ret = !->
| i++ == gs.length => next null, res
| otherwise => ret |> await f, res, xs[i]
# `readdir` example
zip-index = -> [[x, i] for x, i in it]
cons = (a, b) --> [a, b]
readdir = async (await, dir, next) !->
next |> await fs.readdir, dir,
(map -> path.join dir, it)
>> (cons next)
>> apply async-reduce do
(acc, file, next) !-> await fs.stat, file, (stat) !->
| stat.isDirectory! => await readdir, file, next << (++)
| otherwise => next acc ++ [file]
[]
listing <-! readdir path.resolve 'path/to/dir'
console.log listing
# CSON config example
read-config = async (await, file, next) !->
contents <-! await fs.readFile file, \utf8
config = CSON.parse contents
config.ignore = config.ignores # alias
next config
config <-! read-config \file.cson And yes, with that, I just made the error-first convention effectively a monadic Also works well with LiveScript's function composition operators, as I used in the |
If you would like, I can see about publishing an npm module for it (using the JS version). |
+1000. I bet async funcs will land in v8 before TCO does https://chromium.googlesource.com/v8/v8.git/+/d08c0304c5779223d6c468373af4815ec3ccdb84 |
We'd need to bikeshed on the syntax a bit. I'm not against it at all, but I want te ES6 version (sorry @kkirby) |
|
@vendethiel what do you mean by "The ES6 version"? |
We should compile to literal async/await syntax, not generate promise code ourselves |
@vendethiel Plus, it's already been shipping in Edge, and V8 has also implemented it IIRC (although it's not shipping yet). I don't see why it would need compiled, and if it does for some reason, there's Babel among others that can do it. |
👎 for Also, 👎 for |
ok fish it is then. |
Here's my ideas: # normal definition
readConfig = (config) >->
validate <!> readFile config
# back call
do ->
doSomething!
file <-< iterate files
validate <!> readFile file
# bound definition
class Reader
readAll: ->
Promise.all <| @files |> map (file) >~>
@validate <!> readFile file
# curried definition
readFrom = (dir, file) >-->
validate <!> readFile path.resolve dir Annotated JS translation: // # normal definition
// readConfig = (config) >->
// validate <!> readFile config
let readConfig = async function (config) {
return validate(await readFile(config));
};
// # back call
// do ->
// doSomething!
// file <-< iterate files
// validate <!> readFile file
;(function () {
doSomething();
iterate(files, async function (file) {
return validate(await readFile(config));
});
})();
// # bound definition
// class Reader
// readAll: ->
// Promise.all <| @files |> map (file) >~>
// @validate <!> readFile file
class Reader {
readAll() {
return Promise.all(map(file => {
return this.validate(await readFile(config));
})(this.files));
}
}
// # curried definition
// readFrom = (dir, file) >-->
// validate <!> readFile path.resolve dir
let readFrom = curry$(async function (config) {
return validate(await readFile(config));
}); |
|
I vote for the I don't even use certain features of LS which only seem to exist to bring terse readable code into the terse-as-fuck-fizz-buzz-code-golfing-world-cup league. |
@vendethiel I thought about that already... I couldn't think of anything else right off, but I'm open to alternative ideas. |
@vendethiel Oh, then I don't understand the context of your apology. If I recall correctly, my branch only adds async/await keywords to the resulting code. In my promise generator branch, I do actually generate the code on the LS side, but my async/await branch does not. Regardless, no apology needed! |
Like what? If you're referring to things like implicit switches from functions, that's idiomatic among a large number of users. If you're referring to partial application, partially applied operators, etc., those are also common. I've also used other similar things as well. They're useful in smaller projects and utilities, where the simple is even simpler, but I wouldn't recommend some of them everywhere, as it doesn't scale well, just like how point-free style eventually becomes pointless after a while. # This is one of my favorite functions when using vdom libraries.
# I can just use indentation for vdom work.
a = -> [.. for &]
m '.god', a do
m '.parent', a do
m '.child'
m '.child'
m '.child'
m '.parent', a do
m '.child'
m '.child'
m '.child'
# Without this function, you'd have to do this:
m '.god', [
m '.parent', [
m '.child'
m '.child'
m '.child'
]
m '.parent', [
m '.child'
m '.child'
m '.child'
]
]
# Let's make our Gulp tasks a bulleted list
run = -> [.. for &].reduce (a, b) -> a.pipe b
require! {
gulp
'gulp-livescript': livescript
'gulp-uglify': uglify
}
gulp.task 'compile', ->
run do
* gulp.src 'src/**/*.ls'
* livescript bare: true
* uglify do
compress:
global_defs: {-DEBUG}
* gulp.dest 'dist' I will also note that there is a place for highly terse, borderline-obscure languages that look halfway to line noise. There are three general-purpose languages, APL, J, and K, which are general-purpose languages that are stupidly fast at processing arrays and large amounts of data, and the extreme terseness makes them extraordinarily powerful, albeit with a very high barrier of entry (J and K are descendants of APL). Regular expressions are also a very terse, powerful DSL, but it's easy to shoot yourself in the foot if you're not careful. |
Have to agree with @vendethiel, Would strongly prefer we just use |
yeah, I'm in general against adding more symbol stuff. |
I'm starting to fall more in favor of new keywords for this, too. It's harder to come up with something symbolic without either looking obscure and/or appearing to clash with other symbols. |
Yeah, we have enough crazy symbols I think |
I'm surprised no one brought up #836 . |
It has multiple outstanding ergonomics issues that need addressed.
…On Wed, Feb 1, 2017, 02:12 Yin Zhong ***@***.***> wrote:
I'm surprised no one brought up #836
<#836> .
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#683 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AERrBLjasA0b6q28VsyVe8yfm7kDeXrpks5rYDBQgaJpZM4Ds91y>
.
|
async/await is in the standards now |
#978 is merged! |
Examples:
es7 async await keywords:(I can use babeljs to compile es7 es6 to es5)
should compile to:
not:
The text was updated successfully, but these errors were encountered: