# Implement two variants of a simulation which works with the same objects

**URL:** <https://discourse.julialang.org/t/implement-two-variants-of-a-simulation-which-works-with-the-same-objects/103321>\
**Category:** New to Julia\
**Tags:** best-practices\
**Created:** [August 29, 2023, 8:50am UTC](https://discourse.julialang.org/t/implement-two-variants-of-a-simulation-which-works-with-the-same-objects/103321 "2023-08-29T08:50:03Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![natema](https://avatars.discourse-cdn.com/v4/letter/n/ba9def/32.png) [@natema](https://discourse.julialang.org/u/natema)\
**Post date:** [August 29, 2023, 8:50am UTC](https://discourse.julialang.org/t/implement-two-variants-of-a-simulation-which-works-with-the-same-objects/103321/1 "2023-08-29T08:50:03Z")

</div>

I want to simulate two variants of a process that involves the same objects (e.g. a stochastic process on the unit interval [0,1) or on the circle \mathbb R/\mathbb Z).  
For the first variant, I’ve grouped the objects defining the process in a struct `System` and defined a function `simulate(s::System)` that performs the simulation.  
For the second variant, I only need to change few things in `simulate`. Some possibilities on how to implement the second variant are the following ones:

1. Modify `System` so that it contains an additional field, e.g. an `Enum Variant`, which is then used by `simulate` to determine which variant to run;
2. Define another function `simulate2`;
3. Define a different struct `System2` and use multiple dispatch on `simulate`.

**Q1.** Any advice on what would be the most _julionic_ way to do that?

I feel option 3 would be the most appropriate one. However, in that case I’d need two structs `System2` and `System1` which have the same fields, and differs only by the name of their type. Here some possibilities are the following ones:

- 3.1. Just repeat code.
- 3.2. Use code generation:

```plaintext
for type in (:System1, :System2)
   eval(quote
	   struct $type
		   field1
		   ...
	   end 
   end)
end

```

- 3.3. Create a parametric type `System{T}` and abstract types `Variant1` and `Variant2`, and then declare the system with `System{Variant1}(...)` etc.

**Q2.** Any advice on what would be the most _julionic_ way to do that?

I feel that option 3.3 could be a misuse of the concept of parametric type, since the parametric type is not used in any field; on the other hand, if one wants to have the possibility to multiple dispatch on structs holding the same objects, it looks like a nice way to make the situation transparent.

---

<div class="post-metadata">

**Author:** ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)\
**Post date:** [August 29, 2023, 9:15am UTC](https://discourse.julialang.org/t/implement-two-variants-of-a-simulation-which-works-with-the-same-objects/103321/2 "2023-08-29T09:15:21Z")

</div>

Conceptually, the information which simulation routine to run, is independent of the system itself. Therefore it feels clunky to attach that information to the `System` type in any way. This rules out options 1 and 3 for me.

Personally, I prefer a version of option 2. Define functions `_simulate_variant_i(::System)` and a higher-level function to dispatch on the correct one

```julia
function simulate(s::System; variant)
  if variant==1
    _simulate_variant_1(s)
  else
  [...]
  end
end 

```

Another option – if you insist on multiple dispatch – is to wrap a `System` in another structure, e.g.

```julia
struct SimVariant1
   s::System
end

```

and dispatch on the wrapper.

Of course this can be made parametric, and you are free to attach the simulation result to the wrapper if that is opportune, i.e.

```julia
struct Simulation{Variant}
    s::System
    solution
end

simulate!(s::Simulation{Variant1}) = ...
simulate!(s::Simulation{Variant2}) = ...

```

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [August 29, 2023, 9:17am UTC](https://discourse.julialang.org/t/implement-two-variants-of-a-simulation-which-works-with-the-same-objects/103321/3 "2023-08-29T09:17:03Z")

</div>

> [@natema](#):
>
> Define another function `simulate2`;

If the struct is the **exact** same thing, I would use 2 to make the intent clear.
