Closed yorkie closed 10 years ago
nope, no callbacks in luna-land (internally of course), the plan is/was to go with coroutines to suspend functions
Hi mate, wondering on is/was
. Is the project dead? What's the plan?
I love every small thing, so I love this project, I'd like to do some contributes for this.
nah not dead but definitely low priority for me ATM :( unfortunately
Yep couroutines > callbacks . The & is amazing
Actually I'm so new guy to coroutinues, then why it bigger than callbacks? I just wanna get a notification when an async io event is completed, for example:
delete('/user/1') &
delete('/user/2') &
How could we knows the first user/1
has been deleted, also paralleled them. In Javascript:
delete('/user/1', function() {
// get notification for user/1
});
delete('/user/2', null);
a coroutine is basically a function which can be paused and resumed from that point.. in your case the function would be paused after the first delete
... after the async call is finished it would be resumed and would thus continue with the second delete
Then we need a join
like pthread to get result of those corresponding coroutines, am I right? Their definition has a little bit similar, but I see, thanks very much.
the idea is to have a scheduler which is basically responsible for running coroutines and is a loop
say you have this file main.rb
IO.read :file
the runtime would look something like
coro_ready = [:main] # main is the code block in main.rb
coro_stopped = []
class IO
def read
async_read { |result| # <- this function call doesn't block
coro_ready.push :main
}
end
end
while true
fn = coro_ready.pop
fn()
# when fn returns it means it's waiting for async io
coro_stopped.push :main
end
of course by adding coroutines to those two lists you can achieve concurrency (with async I/O and your code would still look synchronous)
am i right @visionmedia ?
im not 100% sold on the fork/join stuff I have in the readme ATM, there's a lot of different ways to approach it - at the lower level lua-style is probably the safest, but I'd like to have a scheduler in core, or pluggable like rust.
yea the idea is instead of a callback, within something like fs.read()
you have a coroutine.yield()
so that stack (and where it was called) is suspended so something else can do work, then when it's done it gets resumed. The easiest way to think of it is like a callback, it's basically the same thing, just easier to read and better exception handling haha
but with the fork/join example to run them in parallel and grab the results:
let a = get('/foo') &
let b = get('/bar') &
let a, b = join(a, b)
sugar for something like:
let a = task(def; return get('/foo'); end)
let b = task(def; return get('/bar'); end)
let a, b = join(a, b)
I have a fork with some syntax refinements though, I'm not 100% sold on the ruby-ish stuff, I love it at the root level, I think the symmetry of def <name>
looks really nice but once you get to closures etc I think it looks kinda bad
I'll try and get the fork up soon
The easiest way to think of it is like a callback, it's basically the same thing, just easier to read and better exception handling
+1 for this summary, just find a easy way to let programmers express its thoughts better :)
Plus, I think &
just defines a function in parallel, then program is to queue these functions by calling join
, but postposition of &
is more like linux shell, how about this syntax:
let a = &get('/foo')
let b = &get('/bar')
let a, b = join(a, b)
Further to say, we can define join
, parallel
, series
, etc, to decide that how the VM queues these functions defined by &
.
Just a suggestion :)
I just thought &
at the end was kinda cool since it's really familiar for shell users haha but yea kinda gimmicky, however the cool thing with it being a low-precedence operator is expressions:
let res = get('/foo') + get('/bar') &
let res = fork(def; return get('/foo') + get('/bar'); end)
is pretty clear that it wraps the whole expression, whereas with an unary it looks like it should just be the first (since unary operators are typically high precedence):
let res = &get('/foo') + get('/bar')
let res = fork(def; return get('/foo'); end) + get('/bar')
Yup, I see.
example of how it's working now: https://gist.github.com/visionmedia/8761361 that's just with coroutines but if/when we have a scheduler it'll look similar for regular IO in request/response cycles etc
hi, @visionmedia
Is @luna plan to implement
callback
like javascript for async IO? I think this feature would be very important for IO.