-
Notifications
You must be signed in to change notification settings - Fork 1
Async/await #13
Description
C# started it, ES6 has it, even C++ 14 has it. Async/await is an amazingly simple construct for creating asynchronous code. Weather it's implemented with promises or continuations on the back end, we'll see later (likely continuations, since I see no indication that Brick will be event-loop based).
Regardless, the async/await keyword syntax for defining asynchronous code is a godsend; it helps create self-documenting code, simplifies asynchronous control flow, and fits snugly with already-defined chunks of brick syntax:
#=
A super-simple asynchronous IRC bot, to experiment with Brick
#=
import Net.Socket.TCP
server = "irc.freenode.org"
port = 6667
nick = "Brick"
channel = "#brick_bot"
commands = {
"!quit": |sock:Socket, _:Array<String>| async {
await sock.write("QUIT :Exiting")
await sock.destroy!
exit(0)
},
"!id": |sock:Socket, words:Array<String>| async -> boolean {
await sock.write("PRIVMSG " + channel + " :" + words.implode(" "))
}
}
async listener(sock:Socket, s:String)
if s.substring(0, 6) == "PING :"
await sock.write("PONG :" + s.substring(6, s.length))
else
let p = s.find(":")
cs = s.substring(p, s.length)
exp = cs.explode(" ")
in
if commands.has_key?(exp[0])
puts(exp[0] + "> " + exp.drop(1).implode(" "))
await commands.get(exp[0])(sock, exp.drop(1))
else
puts("> " + cs)
end
end
end
end
async main
let !sock = await TCP(server, port) in
if not !sock.success?
puts("Failed to connect to server")
else
await !sock.write("NICK " + nick)
await !sock.write("USER " + nick + " 0 * :" + nick + " bot")
await !sock.write("JOIN " + channel)
sock.listen!(listener)
end
end
end
Important notes on what I see as proper use: async isn't an used like an access modifier like in C++ or C#, instead, it's an alternate keyword for function declaration, which implies that the return type should be wrapped in an Awaitable Promise/Future. This way, if manually specifying a type declaration for an async, you needn't include that yourself. In effect, the async keyword adds the type -> Awaitable<T> to the end of the type line. You'll notice that for lambdas, the async keyword appears after the argument types. If I specifying the lambda's return type, it would appears before that. This makes sense, since in practice, the keyword modifies the return type of the function.
As far as the specifics on how async/await interact with threading/blocking, the C# documentation section is excellent: http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_Threads