A blog exploring functional programming and Swift.

Enterprise Subscriptions

Thursday May 9, 2019


Today we are excited to announce support for enterprise subscriptions on Point-Free. This makes it super easy for a large organization to obtain a subscription to our video series and share it with everyone in the company.

How team subscriptions work

Point-Free has supported team subscriptions from the day we launched. They allow a company to purchase multiple subscriptions at once for a discounted price. This works by specifying how many seats you want, and then you invite your colleagues to join your team. As owner of the subscription you get to add and remove teammates at anytime, and the billing rate will be adjusted accordingly.

This works great for smallish teams, but if your organization has a hundred engineers you probably don’t want to manually manage all of the seats on your team. It would be far better if everyone in your organization could simply get instant access to everything Point-Free has to offer. This is what inspired enterprise subscriptions!

How enterprise subscriptions work

If your organization is big enough where manually managing the seats of a team subscription is too cumbersome, then an enterprise subscription should help. After negotiating a yearly price with us, we will whitelist your company’s domain so that anyone with an email from your organization gets instant, full access to the site. You will get a white label landing page on our site, for example pointfree.co/enterprise/blob.biz, and anyone in your company can get access to Point-Free as long as they are in possession of an email from your company.

This greatly reduces the administrative overhead of managing a team subscription for large companies. We will even automatically remove teammates from your enterprise subscription once they leave your company and their email has been deactivated!

Interested?

If any of this sounds interesting to you then please get in touch with us to get more information. We can negotiate a yearly price with you based on your organization’s size. And if you already have a team subscription with us we can discount your enterprise subscription based on how much time you have left in your team subscription’s billing cycle.


Open Sourcing Enum Properties

Monday Apr 29, 2019


We wanted to make Swift enum data access as ergonomic as struct data access, so today we are open sourcing a code generation tool to do just that: generate-enum-properties.


We are excited to announce the 0.1.0 release of generate-enum-properties, a code generation tool for Swift that makes enum data access as ergonomic as struct data access!

Motivation

In Swift, struct data access is far more ergonomic than enum data access by default.

A struct field can be accessed in less than a single line using expressive dot-syntax:

user.name

An enum’s associated value requires as many as seven lines to bring it into the current scope:

let optionalValue: String?
if case let .success(value) = result {
  optionalValue = value
} else {
  optionalValue = nil
}
optionalValue

That’s a lot of boilerplate getting in the way of what we care about: getting at the value of a success.

This difference is also noticeable when working with higher-order functions like map and compactMap.

An array of struct values can be transformed succinctly in a single expression:

users.map { $0.name }

But an array of enum values requires a version of the following incantation:

results.compactMap { result -> String? in
  guard case let .success(value) = result else { return nil }
  return value
}

The imperative nature of unwrapping an associated value spills over multiple lines, which requires us to give Swift an explicit return type, name our closure argument, and provide two explicit returns.

Solution

We can recover all of the ergonomics of struct data access for enums by defining “enum properties”: computed properties that optionally return a value when the case matches:

extension Result {
  var success: Success? {
    guard case let .success(value) = self else { return nil }
    return value
  }

  var failure: Failure? {
    guard case let .failure(value) = self else { return nil }
    return value
  }
}

This is work we’re used to doing in an ad hoc way throughout our code bases, but by centralizing it in a computed property, we’re now free to access underlying data in a succinct fashion:

// Optionally-chain into a successful result.
result.success?.count

// Collect a bunch of successful values.
results.compactMap { $0.success }

By defining a computed property, we bridge another gap: our enums now have key paths!

\Result<String, Error>.success
// KeyPath<Result<String, Error>, String?>

Despite the benefits, defining these from scratch is a tall ask. Instead, enter generate-enum-properties.

generate-enum-properties

generate-enum-properties is a command line tool that will rewrite Swift source code to add ergonomic enum data access to any enum with associated data.

Given the following source file as input:

enum Validated<Valid, Invalid> {
  case valid(Valid)
  case invalid(Invalid)
}

It will be replaced with the following output:

enum Validated<Valid, Invalid> {
  case valid(Valid)
  case invalid(Invalid)

  var valid: Valid? {
    get {
      guard case let .valid(value) = self else { return nil }
      return value
    }
    set {
      guard case .valid = self, let newValue = newValue else { return }
      self = .valid(newValue)
    }
  }
}

Not only can you ergonomically access enum data, but you can update it as well!

Learn more

We’ve explored why “enum properties” are important on Point-Free, but we hope this library empowers folks to write source code generation tools to solve these kinds of problems more broadly.

To generate enum properties for your Swift source code projects, today, visit the repository and read through its installation and usage!


Open Sourcing Gen

Monday Mar 18, 2019


Today we are open sourcing Gen: a lightweight wrapper around Swift’s randomness API’s that makes randomess more composable, transformable and controllable!


We are excited to announce the 0.1.0 release of Gen, a new API for expressing randomness in Swift. Its focus is on composability (combining multiple forms of randomness into new forms of randomness), transformability (applying functions to randomness), and controllability (deterministic pseudo-randomness for times we need it). With these three features you can break down large, complex forms of randomness into smaller, simpler pieces, and you can write tests for it!

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. For example, while it may gives us ways of generating random booleans, numeric values, and even ways to shuffle arrays and pluck random elements from arrays, it says nothing about creating random strings, random collections of values, or random values from our own data types.

Further, the API is not very composable, which would allow us to create complex types of randomness from simpler pieces. One primarily uses the API by calling static random functions on types, such as Int.random(in: 0...9), but there is no guidance on how to generate new types of randomness from existing randomness.

Gen

Gen is a lightweight wrapper over Swift’s randomness APIs that makes it easy to build custom generators of any kind of value. 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
Int.random(in: 0...9) // 4

// Gen's API
Gen.int(in: 0...9).run() // 6

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, string, 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"

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 lcrng = LCRNG(seed: 0)
Gen.int(in: 0...9).run(using: &lcrng) // "8"
Gen.int(in: 0...9).run(using: &lcrng) // "1"
Gen.int(in: 0...9).run(using: &lcrng) // "7"

lcrng.seed = 0
Gen.int(in: 0...9).run(using: &lcrng) // "8"
Gen.int(in: 0...9).run(using: &lcrng) // "1"
Gen.int(in: 0...9).run(using: &lcrng) // "7"

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

Learn more

The Gen type has been explored on Point-Free numerous times. We began by showing that randomness can be made composable by expressiong it as a function. This allowed us to define map, flatMap and zip operations on randomness, which helped us create very complex forms of randomness for just a few small, simple pieces.

In order to show just how powerful composable randomness is, we wrote a blog post demonstrating how to create a Zalgo text generator. This consisted of defining small generators that do a specific thing, such as generating special unicode characters, and the piecing them together to finally give us the generator that allows us to create bizarre strings such as: P̵̙̬̬̝̹̰̜ͧ̿o̎ĩͪͪ͗n͓̪̝̓t̊̏̾̊̆-̦̲̥͉F̠͖͈̮̾́ͨ͐͝r̸͋̆̅̅ͪ̚ë̝͑ͣ̒̏̈́̉e̟̺̪͕̹͆ͩͯ̑ͣ͂̉.

Then we showed how randomness can be made controllable (part 1 and part 2) by slightly tweaking Gen definition so that it took a RandomNumberGenerator, which is the Swift protocol that powers all of Swift’s randomness API’s. This allowed us to keep all of Gen‘s nice compositional properties while also allowing us to plug in our own random number generators. In particular, we can use a deterministic, seedable, pseudo-random number generator in tests so that we can still test code that invokes randomness API’s.

Try it out today!

The official 0.1.0 release of Gen is on GitHub now, and we have more improvements and refinements coming soon. We hope that Gen will help you control the complexity in your applications that arises from randomness, both by making the randomness simpler to understand and easier to test.


Older blog posts

Tuesday Jan 8, 2019

Announcing swift-html 0.2.0

Announcing swift-html 0.2.0: support for CocoaPods, Carthage, SnapshotTesting, and more!

Wednesday Dec 19, 2018

2018 Year-in-Review

41 episodes, 19 hours of video, 25 blog posts, 8 open source libraries, 3.8K stars, 36K visitors, and we’re just getting started?

Wednesday Dec 19, 2018

Save 30% on Point-Free

To end 2018 on a high note we're offering a 30% discount to new subscribers for their first year. Just click through to read the full post below! We hope you'll join us for all of the great material we have planned for 2019.

Monday Dec 3, 2018

SnapshotTesting 1.0: Delightful Swift snapshot testing

Today we are open sourcing SnapshotTesting 1.0: a modern, composable snapshot testing library built entirely in Swift!

Monday Oct 29, 2018

Some news about contramap

We've seen that contramap is a powerful operation, but the name isn't fantastic. We propose a much more intuitive name for this operation, and in doing so make our code much easier to read.

Tuesday Oct 9, 2018

How to Control the World

APIs that interact with the outside world are unpredictable and make it difficult to test and simulate code paths in our apps. Existing solutions to this problem are verbose and complicated, so let's explore a simpler solution by embracing singletons and global mutation, and rejecting protocol-oriented programming and dependency injection.

Monday Oct 8, 2018

Watch episodes in your favorite podcast app!

Follow along with the newest Point-Free episodes using your favorite podcast app. We now support podcast-friendly RSS feeds for viewing all of our videos.

Thursday Sep 20, 2018

Random Zalgo Generator

Let's create a random Zalgo text generator using the simple Gen type we defined in this week's episode!

Thursday Sep 13, 2018

Type-safe HTML with Kitura

Today we're releasing a Kitura plug-in for rendering type-safe HTML. It provides a Swift compile-time API to HTML that prevents many of the runtime errors and vulnerabilities of traditional templated HTML rendering.

Thursday Sep 13, 2018

Type-safe HTML with Vapor

Today we're releasing a Vapor plug-in for rendering type-safe HTML. It provides a Swift compile-time API to HTML that prevents many of the runtime errors and vulnerabilities of traditional templated HTML rendering.

Wednesday Sep 12, 2018

Open sourcing swift-html: A Type-Safe Alternative to Templating Languages in Swift

Today we are open sourcing a new library for building HTML documents in Swift. It's extensible, transformable, type-safe, and provides many benefits over templating languages.

Friday Aug 17, 2018

Overture 0.3.0: Now with Zip

Today we are releasing Overture 0.3.0 with a bunch of useful zip functions.

Friday Aug 17, 2018

Open Sourcing Validated

Today we are open sourcing Validated, a tiny functional Swift library for handling multiple errors: functionality that you don't get from throwing functions and the Result type.

Thursday Aug 16, 2018

Solutions to Exercises: Zip Part 3

Today we solve the exercises to the third and final part of our introductory series on zip.

Wednesday Aug 15, 2018

Solutions to Exercises: Zip Part 2

Today we solve the exercises to the second part of our introductory series on zip.

Tuesday Aug 14, 2018

Solutions to Exercises: Zip Part 1

Today we solve the exercises to the first part of our introductory series on zip.

Monday Aug 6, 2018

Announcing Student Discounts

Get 50% off your Point-Free subscription with proof of enrollment at a university or coding school.

Monday Jul 30, 2018

Celebrating 6 Months

This week marks 6 months since our launch, and we’re making one of our most popular episodes free to the public!

Monday Jul 2, 2018

Conditional Coding

What happens when we combine Swift's conditional conformance with codability?

Monday Jun 25, 2018

Open Sourcing NonEmpty

Today we are open sourcing NonEmpty, a Swift library for modeling non-empty collection types. This small library can help make your code safer and more expressive with very little work.

Monday Jun 18, 2018

Tagged Seconds and Milliseconds

Let's create a type-safe interface for dealing with seconds and milliseconds in our programs. We'll use the `Tagged` type, which allows us to construct all new types in a lightweight way.

Wednesday May 30, 2018

Styling with Functions: Free for Everyone!

We are making one of our early episodes, “UIKit Styling with Functions”, free to everyone today! It’s a seminal episode that sets the foundation for some later work in the Point-Free series.

Tuesday May 15, 2018

Overture: Now with Functional Setters

Announcing Overture 0.2.0! This release is all about setters: functions that allow us to build complex transformations out of smaller units.

Monday May 7, 2018

Solutions to Exercises: Contravariance

This week we solve the exercises from our episode on contravariance, because there were _a lot_ of them!

Monday Apr 23, 2018

Case Study: Algebraic Data Types

Let’s look at a real world use for algebraic data types. We will refactor a data type that is used in the code on this very site so that the invalid states are unrepresentable by the compiler.

Monday Apr 23, 2018

Announcing Point-Free Pointers!

Today we are excited to announcement launch of Point-Free Pointers, a blog to supplement our video series for all the content we couldn’t fit in. Expect to find regularly postings here that dive even deeper into functional programming, showing real world use cases and more!