A new Swift video series exploring functional programming and more.
#30 • Monday Sep 17, 2018 • Subscriber-only

Composable Randomness

Randomness is a topic that may not seem so functional, but it gives us a wonderful opportunity to explore composition. After a survey of what randomness looks like in Swift today, we’ll build a complex set of random APIs from just a single unit.

#30 • Monday Sep 17, 2018 • Subscriber-only

Composable Randomness

Randomness is a topic that may not seem so functional, but it gives us a wonderful opportunity to explore composition. After a survey of what randomness looks like in Swift today, we’ll build a complex set of random APIs from just a single unit.


Subscribe to Point‑Free

This episode is for subscribers only. To access it, and all past and future episodes, become a subscriber today!

See subscription optionsorLog in

Sign up for our weekly newsletter to be notified of new episodes, and unlock access to any subscriber-only episode of your choosing!

Sign up for free episode


Exercises

  1. Create a function called frequency that takes an array of pairs, [(Int, Gen<A>)], to create a Gen<A> such that (2, gen) is twice as likely to be run than a (1, gen).

  2. Extend Gen with an optional computed property that returns a generator that returns nil a quarter of the time. What other generators can you compose this from?

  3. Extend Gen with a filter method that returns a generator that filters out random entries that don’t match the predicate. What kinds of problems may this function have?

  4. Create a string generator of type Gen<String> that randomly produces a randomly-sized string of any unicode character. What smaller generators do you composed it from?

  5. Redefine element(of:) to work with any Collection. Can it also be redefined in terms of Sequence?

  6. Create a subsequence generator to return a randomly-sized, randomly-offset subsequence of an array. Can it be redefined in terms of Collection?

  7. The Gen type has map defined it, which, as we’ve seen in the past, allows us to consider what zip might look like. Define zip2 on Gen:

    func zip2<A, B>(_ ga: Gen<A>, _ gb: Gen<B>) -> Gen<(A, B)>
    
  8. Define zip2(with:):

    func zip2<A, B, C>(with f: (A, B) -> C) -> (Gen<A>, Gen<B>) -> Gen<C>
    
  9. With zip2 and zip2(with:) defined, define higher-order zip3 and zip3(with:) and explore some uses. What functionality does zip provide our Gen type?


References

  • Random Zalgo Generator

    Brandon Williams • Tuesday Nov 20, 2018

    We apply the ideas of composable randomness to build a random Zalgo generator, which is a way to apply gitchy artifacts to a string by adding strange unicode characters to it. It shows that we can start with very simple, small pieces and then compose them together to create a really complicated machine.

Chapters
Introduction
00:06
Randomness in Swift: numbers
00:50
Randomness in Swift: elements
04:54
Randomness in Swift: more
10:40
Rethinking randomness
12:32
What’s the point?
27:15
Gen<[A]>
30:17
Gen<Password>
35:25
Conclusion
37:56
Credits

Hosted by Brandon Williams and Stephen Celis. Recorded in Brooklyn, NY.