You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sender/receiver channels is a common pattern for concurrency programming. Another common programming pattern is the actor model, where entities communicate by ids. Dyon combines these two approaches by treating functions as entities that can communicate with other processes. With other words, you do not have to change your algorithm to support concurrent programming. You can also use this technique for debugging your program, by printing out all input that is sent to a function.
Dyon uses the in keyword for creating receiver channels. The sender channel can be any loaded function.
Example:
fnmain(){
a := in log
log(1)
b := in log
log(2)
c := in log
log(3)report(a)// prints `123`report(b)// prints `23`
report(c)// prints `3`}// Dummy sink.fnlog(x){}fnreport(a: in[[f64]]){loop{
x := next(a)if x == none(){break}
x := unwrap(x)
print(x[0])}println("")}
When the log function is called, Dyon checks a flag whether any channels are subscribing. If there is at least one subscriber, Dyon pushes the arguments into an array and sends a copy to each recipient.
Here is another example, combining in and go:
/*This example shows how to process data chunkwise by readingat slower intervals.*/fnmain(){// Create a log receiver channel.
log := in log
// Create a channel for signaling when the task is done.
done := in done
// Create a new thread that works on the task.
th := go run()loop{// Read the done signal first to avoid data race.
done_val := next(done)// Print out received log.loop{
x := next(log)if x == none(){break}print(unwrap(x))}
println("")// Break the loop when done.if done_val != none(){break}sleep(0.5)}// Wait for the thread to finish.
_ := join(thread: th)}fnlog(x:f64){}fndone(){}// Runs task.fnrun() -> bool{for i 100{
log(i)
sleep(0.1)}
done()
return true}
Notice that the number of received messages varies, because the receiver thread sleeps at different intervals than the sender thread.
You can also receive current objects:
fnmain(){
log := in add
~ x := 0add(1)println(unwrap(next(log)))// prints `[1, 0]`add(4)println(unwrap(next(log)))// prints `[4, 1]`add(3)println(unwrap(next(log)))// prints `[3, 5]`}fnadd(a:f64) ~ mut x:f64{x += a}
The type of the receiver channel is in, with an optional inner type e.g.in[[str]]. The inner type created with the in <fn> syntax is an array. For example, if you subscribe to a function foo(a: f64, b: f64), then the type in[[f64]] can be used. If the arguments have different types, you can use in[[]], in[[any]] or just in.
When a receiver channel runs out of scope, sending new messages fails. Dyon cleans up unused channels by defragmenting the subscriber list and truncating it. This prevents memory leaks when creating and destroying lot of channels.
This also means that the order of receiving events can change:
abc // the subscriber list contains `a`, `b` and `c`
xbc // `a` runs out of scope and no longer receive messages
cbx // `c` and the broken `a` is swapped
cb // the subscriber list is truncated
Notice how c and b changed order in the example above.
When subscribing on a function, all input from all threads is received. To separate different tasks, one must pass in an identifier as an argument to the function.
Design:
Use Rust's receiver/sender channels passing Dyon variables for easy integratation
The in type has an optional inner type e.g. in[[f64]]
Extensible for other kinds of sender/receiver patterns
Rules:
All loaded functions can be turned into send-channels
An in-type channel is created by in foo where foo is a loaded function
External functions and intrinsic functions can not be turned into send-channels
The text was updated successfully, but these errors were encountered:
Sender/receiver channels is a common pattern for concurrency programming. Another common programming pattern is the actor model, where entities communicate by ids. Dyon combines these two approaches by treating functions as entities that can communicate with other processes. With other words, you do not have to change your algorithm to support concurrent programming. You can also use this technique for debugging your program, by printing out all input that is sent to a function.
Dyon uses the
in
keyword for creating receiver channels. The sender channel can be any loaded function.Example:
When the
log
function is called, Dyon checks a flag whether any channels are subscribing. If there is at least one subscriber, Dyon pushes the arguments into an array and sends a copy to each recipient.Here is another example, combining
in
andgo
:A typical output from the example above:
Notice that the number of received messages varies, because the receiver thread sleeps at different intervals than the sender thread.
You can also receive current objects:
The type of the receiver channel is
in
, with an optional inner type e.g.in[[str]]
. The inner type created with thein <fn>
syntax is an array. For example, if you subscribe to a functionfoo(a: f64, b: f64)
, then the typein[[f64]]
can be used. If the arguments have different types, you can usein[[]]
,in[[any]]
or justin
.When a receiver channel runs out of scope, sending new messages fails. Dyon cleans up unused channels by defragmenting the subscriber list and truncating it. This prevents memory leaks when creating and destroying lot of channels.
This also means that the order of receiving events can change:
Notice how
c
andb
changed order in the example above.When subscribing on a function, all input from all threads is received. To separate different tasks, one must pass in an identifier as an argument to the function.
Design:
in
type has an optional inner type e.g.in[[f64]]
Rules:
in foo
wherefoo
is a loaded functionThe text was updated successfully, but these errors were encountered: