We need to share the insight that if packets are treated as immutable, and no global state is used, then a graph's outputs given a set of inputs will always be the same (assuming of course no random number is used insight a calculator).
For example, this example might give different results on different runs because global state is used.
using Tissue;
x = 0
struct Source
count
Source() = new(0)
end
function Tissue.process(c::Source)
c.count += 1
return c.count > 50 ? nothing : 1
end
struct Adder end
function Tissue.process(c::Adder, num)
global x += 1
return num
end
struct Multer end
function Tissue.process(c::Multer, num)
global x *= 2
return num
end
struct Barrier end
function Tissue.process(c::Barrier, num1, num2)
global x
x
end
@graph NonReproducibleGraph begin
@calculator source = Source()
@calculator adder = Adder()
@calculator multer = Multer()
@calculator barrier = Barrier()
@bindstreams adder (num = source)
@bindstreams multer (num = source)
@bindstreams barrier (num1 = adder) (num2 = multer)
end
The example for using mutable is very similar: Source sends a mutable struct object with an Atomic{Int} field, and adder and multer modify that field similar to how they modify global x in this example.
We need to share the insight that if packets are treated as immutable, and no global state is used, then a graph's outputs given a set of inputs will always be the same (assuming of course no random number is used insight a calculator).
For example, this example might give different results on different runs because global state is used.
The example for using mutable is very similar:
Source
sends amutable struct
object with anAtomic{Int}
field, andadder
andmulter
modify that field similar to how they modifyglobal x
in this example.