Skip to content

Hierarchical classes Splittable/Unsplittable Gen #7

@lehins

Description

@lehins

There is currently a totally useless CPP in random:

#ifdef ENABLE_SPLITTABLEGEN
class SplittableGen g where
#endif

which hints at what I am about to suggest.

There are some pure RNGs like mersenne-twister for example, that are not splittable. Question is do we want to bring this distinction to the type level or not? I personally would like to avoid seeing such code:

instance RandomGen PureMT where
   next  = randomInt
   split = error "System.Random.Mersenne.Pure: unable to split the mersenne twister"

There are four approaches I see that we can take:

  1. Follow the current path laid out in the code and simply remove the CPP pragmas:
class RandomGen g where
  ...
class RandomGen g => SplittableGen g where
  split    :: g -> (g, g)
  • Disadvantage: breaks bunch of code in the wild that depends on split.
  • Advantage: none
  1. Similar to the above, but use default signatures and deprecation
class RandomGen g where
  ...
  split    :: g -> (g, g)
  default split :: SplittableGen g => g -> (g, g)
  split = splitGen
  {-# DEPRECATED split "In favor of `splitGen`" #-}

class RandomGen g => SplittableGen g where
  splitGen    :: g -> (g, g)
  • Disadvantage: eventually it will affect the user code
  • Advantage: not a breaking change for RNG libraries
  1. Invert the dependency and create an UnsplittableGen (name is up for a debate)
class NoSplitGen g where
  ...
  genWord64 :: g -> (Word64, g)
class NoSplitGen g => RandomGen g where
  split  :: g -> (g, g)
  • Advantage: will not break the user code, unless they are using a non-splittable RNG.
  • Disadvantage: breaks current RNG libraries, which I think is OK, since they will need to be updated anyways.
  1. Not to worry about distinction between splittable/not-splittable and leave it as is:
  • Advantages: less changes for everyone
  • Disadvantages: partial code in the wild and hard to see the lack/presence of splitability property in th RNG

My favorite is the 3rd one. Any thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions