Make it easier to share state

Sometimes I wish that there were a magical language construct that makes it easier to share some state under a common roof.

Even the module construct in latest C++ does not seem to provide this feature.

Although enum, struct and class types in Swift allow the declaration of nested types, they don't make it easier to have some state shared among instances of those nested types. Consequently, one has to resort to using singletons or passing references around to make state sharing possible.

To make this possible, we could introduce a new type (more like a class) and name it domain, module or world, which can be used to create a compound type that provides a scope for declaring both shared state and nested types which use that state.

For example, using world as the new type, we can declare a Simulation world that has both properties for shared state and nested types using that state.

world Simulation {
   // Type for shared state, doesn't have to be here - can be declared anywhere

   struct Parameters {
      ...
   }

   // All properties constitute shared state
   let parameters : Parameters
   static var instanceCounter : Int = 0

   // Initialisation
   init (parameters : Parameters) {
      self.parameters = parameters
      instanceCounter += 1
   }

  // Instance creation function for state-sharing types
  func create <T> (...) -> T where T == BarEngine or T == FooEngine {
     return T (...)
  }

  // State-sharing types must opt in
 @StateSharing class BarEngine {
     // All instances of this have access to shared state
     ...
  }

  @StateSharing class FooEngine {
     // All instances of this have access to shared state
     ...
  }

  // These don't share state
  class BarHelper {
     ...
  }

  struct FooHelper {
     ...
  }

  // Etc
}

Then, we can run multiple simulation engines in parallel in different instances of the Simulation world:

// Create a simulation world
// Create shared state - not shown
let s1 = Simulation (...)

// Engines in this world
let engine11 = s1.create <.BarEngine> ()
let engine12 = s1.create <.FooEngine> ()

// Run the engines
Task {
   engine11.run ()
}

Task {
   engine12.run ()
}

// Create a second world
// Create shared state - not shown
let s2 = Simulation (...)

// Engines in second world
let engine21 = s2.create <.BarEngine> ()
let engine22 = s2.create <.FooEngine> ()

// Run the engines
Task {
   engine21.run ()
}

Task {
   engine22.run ()
}

// Wait for results
...

Everyone is invited to brainstorm this magical new construct :slight_smile:

1 Like

This is kind of swimming against the flow. Reducing shared mutable state has been a huge movement in programming language design in the past 20 years.

How would this "world-owned" shared state be tested?

6 Likes

Is it dependency injection you find tedious? There are tools for that, such as Swinject.

2 Likes

An approach similar to SwiftUI's Environment looks far superior to me than Swinject. In fact, I was so impressed by it, that I reverse-engineered it. The storage part of it I implemented as a standalone library AttributeKit.

1 Like