Swift generators that can be copied while maintaining independent state




Spork defines Swift generators that can be copied while maintaining independent state. It does this by wrapping a normal generator in a BufferingGenerator, and maintaining a shared buffer among copies to provide value-semantics.

Normally, some generators work this way...

let indexingGenerator = [1,2,3].generate()
let copy = indexingGenerator
print( // -> 1
print(              // -> 1

But other generators work like this...

let sharedStateGenerator = anyGenerator(indexingGenerator)
let copy = sharedStateGenerator
print( // -> 1
print(                 // -> 2

That's to say, there's nothing that guarentees that your generator copy won't share its state with the original generator. Spork defines a protocol ForkableGeneratorType with a method fork that guarentees unique state among forked copies. Spork also defines a type BufferingGenerator that bridges any type of generator to be a ForkableGenerator by maintaining a list of forked listeners and holding onto any still-needed elements for these generators.

let bufferingGenerator = BufferingGenerator(bridgedFromGenerator: sharedStateGenerator)
let copy = bufferingGenerator.fork()
print( // -> 1
print(               // -> 1

Just like AnyGenerator is used for GeneratorType type-erasure, Spork defines a class AnyForkableGenerator that's used for ForkableGeneratorType type-erasure.

let typeErasedForkableGenerator = anyForkableGenerator(bufferingGenerator)

Spork also defines a ValueCopyGenerator that works like BufferingGenerator, but has value-semantics.

let valueCopyGenerator = ValueCopyGenerator(bufferingGenerator)
let copy = valueCopyGenerator
print( // -> 1
print(               // -> 1