All Projects β†’ pointfreeco β†’ Swift Gen

pointfreeco / Swift Gen

Licence: mit
🎱 Composable, transformable, controllable randomness.

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Swift Gen

Not Awesome Es6 Classes
A curated list of resources on why ES6 (aka ES2015) classes are NOT awesome
Stars: ✭ 1,185 (+469.71%)
Mutual labels:  composition, functional-programming
Scriptum
A fool's scriptum on functional programming
Stars: ✭ 346 (+66.35%)
Mutual labels:  composition, functional-programming
Lambda Talk
A Flock of Functions: Combinators, Lambda Calculus, & Church Encodings in JS
Stars: ✭ 315 (+51.44%)
Mutual labels:  composition, functional-programming
Bow
🏹 Bow is a cross-platform library for Typed Functional Programming in Swift
Stars: ✭ 538 (+158.65%)
Mutual labels:  composition, functional-programming
Redash
Tiny functional programming suite for JavaScript.
Stars: ✭ 40 (-80.77%)
Mutual labels:  composition, functional-programming
Bugz
πŸ› Composable User Agent Detection using Ramda
Stars: ✭ 15 (-92.79%)
Mutual labels:  composition, functional-programming
Swift Web
πŸ•Έ A collection of Swift server-side frameworks for handling HTML, CSS, routing and middleware.
Stars: ✭ 415 (+99.52%)
Mutual labels:  composition, functional-programming
Json Decoder
Type safe JSON decoder for TypeScript
Stars: ✭ 67 (-67.79%)
Mutual labels:  composition, functional-programming
Functionalplus
Functional Programming Library for C++. Write concise and readable C++ code.
Stars: ✭ 1,286 (+518.27%)
Mutual labels:  composition, functional-programming
Zebras
Data analysis library for JavaScript built with Ramda
Stars: ✭ 192 (-7.69%)
Mutual labels:  functional-programming
Hybrids
Extraordinary JavaScript framework with unique declarative and functional architecture
Stars: ✭ 2,529 (+1115.87%)
Mutual labels:  functional-programming
Deep Waters
πŸ”₯Deep Waters is an easy-to-compose functional validation system for javascript developers πŸ”₯
Stars: ✭ 188 (-9.62%)
Mutual labels:  functional-programming
Bosatsu
A python-ish pure and total functional programming language
Stars: ✭ 193 (-7.21%)
Mutual labels:  functional-programming
Coalton
Coalton is (supposed to be) a dialect of ML embedded in Common Lisp.
Stars: ✭ 202 (-2.88%)
Mutual labels:  functional-programming
Apex Lambda
Functional programming for Salesforce Apex
Stars: ✭ 189 (-9.13%)
Mutual labels:  functional-programming
Scala Exercises
The easy way to learn Scala.
Stars: ✭ 2,431 (+1068.75%)
Mutual labels:  functional-programming
Remote Data Ts
RemoteData type
Stars: ✭ 185 (-11.06%)
Mutual labels:  functional-programming
Kickstarter Reactiveextensions
A collection of extensions to the ReactiveSwift framework.
Stars: ✭ 183 (-12.02%)
Mutual labels:  functional-programming
Isobar
A Python library for creating and manipulating musical patterns, designed for use in algorithmic composition, generative music and sonification. Can be used to generate MIDI events, MIDI files, OSC messages, or custom events.
Stars: ✭ 207 (-0.48%)
Mutual labels:  composition
Zio Actors
A high-performance, purely-functional library for building, composing, and supervising typed actors based on ZIO
Stars: ✭ 206 (-0.96%)
Mutual labels:  functional-programming

🎱 Gen

CI

Composable, transformable, controllable randomness.

Table of Contents

Motivation

Swift's randomness API is powerful and simple to use. It allows us to create random values from many basic types, such as booleans and numeric types, and it allows us to randomly shuffle arrays and pluck random elements from collections.

However, it does not make it easy for us to extend the randomness API, nor does it provide an API that is composable, which would allow us to create complex types of randomness from simpler pieces.

Gen is a lightweight wrapper over Swift's randomness APIs that makes it easy to build custom generators of any kind of value.

Examples

Gen's namesake type, Gen, is responsible for producing random values. Most often you will reach for one of the static variables inside Gen to get access to a Gen value:

Gen.bool
// Gen<Bool>

Rather than immediately producing a random value, Gen describes a random value that can be produced by calling its run method:

let myGen = Gen.bool
// Gen<Bool>

myGen.run() // true
myGen.run() // true
myGen.run() // false

Every random function that comes with Swift is also available as a static function on Gen:

Swift's API Gen's API
Int.random(in: 0...9) Gen.int(in: 0...9)
Double.random(in: 0...9) Gen.double(in: 0...9)
Bool.random() Gen.bool
[1, 2, 3].randomElement() Gen.element(of: [1, 2, 3])
[1, 2, 3].shuffled() Gen.shuffle([1, 2, 3])

The reason it is powerful to wrap randomness in the Gen type is that we can make the Gen type composable. For example, a generator of integers can be turned into a generator of numeric strings with a simple application of the map function:

let digit = Gen.int(in: 0...9)           // Gen<Int>
let stringDigit = digit.map(String.init) // Gen<String>

stringDigit.run() // "7"
stringDigit.run() // "1"
stringDigit.run() // "3"

Already this is a form of randomness that Swift's API's do not provide out of the box.

Gen provides many operators for generating new types of randomness, such as map, flatMap and zip, as well as helper functions for generating random arrays, sets, dictionaries, strings, distributions and more! A random password generator, for example, is just a few operators away.

// Take a generator of random letters and numbers.
let password = Gen.letterOrNumber
  // Generate 6-character strings of them.
  .string(of: .always(6))
  // Generate 3 segments of these strings.
  .array(of: .always(3))
  // And join them.
  .map { $0.joined(separator: "-") }

password.run() // "9BiGYA-fmvsOf-VYDtDv"
password.run() // "dS2MGr-FQSuC4-ZLEicl"
password.run() // "YusZGF-HILrCo-rNGfCA"

This kind of composition makes it simple to generate random values of anything.

// Use `zip` to combine generators together and build structures.

let randomPoint = zip(.int(in: -10...10), .int(in: -10...10))
  .map(CGPoint.init(x:y:))
// Gen<CGPoint>

But composability isn't the only reason the Gen type shines. By delaying the creation of random values until the run method is invoked, we allow ourselves to control randomness in circumstances where we need determinism, such as tests. The run method has an overload that takes a RandomNumberGenerator value, which is Swift's protocol that powers their randomness API. By default it uses the SystemRandomNumberGenerator, which is a good source of randomness, but we can also provide a seedable "pseudo" random number generator, so that we can get predictable results in tests:

var xoshiro = Xoshiro(seed: 0)
Gen.int(in: 0...9).run(using: &xoshiro) // "1"
Gen.int(in: 0...9).run(using: &xoshiro) // "0"
Gen.int(in: 0...9).run(using: &xoshiro) // "4"

xoshiro = Xoshiro(seed: 0)
Gen.int(in: 0...9).run(using: &xoshiro) // "1"
Gen.int(in: 0...9).run(using: &xoshiro) // "0"
Gen.int(in: 0...9).run(using: &xoshiro) // "4"

This means you don't have to sacrifice testability when leveraging randomness in your application.

For more examples of using Gen to build complex randomness, see our blog post on creating a Zalgo generator and our two-part video series (part 1 and part 2) on creating generative art.

Installation

Carthage

If you use Carthage, you can add the following dependency to your Cartfile:

github "pointfreeco/swift-gen" ~> 0.3

CocoaPods

If your project uses CocoaPods, just add the following to your Podfile:

pod 'PointFree-Gen', '~> 0.3'

SwiftPM

If you want to use Gen in a project that uses SwiftPM, it's as simple as adding a dependencies clause to your Package.swift:

dependencies: [
  .package(url: "https://github.com/pointfreeco/swift-gen.git", from: "0.3.0")
]

Xcode Sub-project

Submodule, clone, or download Gen, and drag Gen.xcodeproj into your project.

Interested in learning more?

These concepts (and more) are explored thoroughly in Point-Free, a video series exploring functional programming and Swift hosted by Brandon Williams and Stephen Celis.

The design of this library was explored in the following Point-Free episodes:

video poster image

License

All modules are released under the MIT license. See LICENSE for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].