A blog exploring advanced programming topics in Swift.

Sharing state in the Composable Architecture

Monday Feb 26, 2024

⚠️ Warning

There are some episode spoilers contained in this announcement!

Today we are excited to announce a new beta for the Composable Architecture. Past betas have included the concurrency beta, the Reducer protocol beta, and most recently the observation beta. And we think this one may be more exciting than all of those!

This beta focuses on providing the tools necessary for sharing state throughout your app. We also went above and beyond by providing tools for persisting state to user defaults and the file system, as well as providing a way create your own persistence strategies.

Join us for a quick overview of the tools, and be sure to check out the beta today!

The @Shared property wrapper

The primary tool provided in this beta is the @Shared property wrapper. It represents a piece of state that will be shared with another part of the application, or potentially with the entire application. It can be used with any data type, and it cannot be set to a default value.

For example, suppose you have a feature that holds a count and you want to be able to hand a shared reference to that count to other features. You can do so by holding onto a @Shared property in the feature’s state:

@Reducer
struct ParentFeature {
  @ObservableState
  struct State {
    @Shared var count: Int
    // Other properties
  }
  // ...
}

Note

It is not possible to provide a default to a @Shared value. It must be passed to this feature’s state from a parent feature.

Then suppose that this feature can present a child feature that wants access to this shared count value. The child feature would also would hold onto an @Shared property to a count:

@Reducer
struct ChildFeature {
  @ObservableState
  struct State {
    @Shared var count: Int
    // Other properties
  }
  // ...
}

When the parent features creates the child feature’s state, it can pass a reference to the shared count rather than the actual count value by using the $count projected value:

case .presentButtonTapped:
  state.child = ChildFeature.State(count: state.$count)
  // ...

Now any mutation the ChildFeature makes to its count will be instantly made to the ParentFeature’s count too, and vice-versa.

The Shared type works by holding onto a reference type so that multiple parts of the application can see the same state and can each make mutations with it. Historically, reference types in state were problematic for two main reasons:

  • Reference types do not play nicely with SwiftUI view invalidation. It was possible for the data inside a reference to change without notifying the view that it changed, cause the view to show out-of-date information.
  • Reference types do not play nicely with testing. Classes do not easily conform to Equatable, and even when they do you cannot compare them before and after a mutation is made in order to exhaustively prove how it changes.

However, there are now solutions to both of these problems:

  • Thanks to Swift’s new observation tools (and our backport of those tools), reference types can now properly communicate to views when they change so that the view can invalidate and re-render.
  • And thanks to the @Shared property wrapper, we are able to make shared test 100% testable, even exhaustively! When using the TestStore to test your features you will be forced to assert on how all state changes in your feature, even state held in @Shared.

Persistence

The @Shared property wrapper can also be used in conjunction with a persistence strategy that makes the state available globally throughout the entire application, and persists the data to some external system so that it can be made available across application launches.

For example, to save the count described above in user defaults so that any changes are automatically persisted and made available next time the app launches, simply use the .appStorage persistence strategy with @Shared:

 @Reducer
 struct ParentFeature {
   @ObservableState
   struct State {
-    @Shared var count: Int
+    @Shared(.appStorage("count")) var count = 0
     // Other properties
   }
   // ...
 }

Note

You must provide a default value when using a persistence stategy. It is only used upon first access of the state and when there is no previously saved state (for example, the first launch of the app).

That’s all it takes. Now any part of the application can instantly access this state by using the same @Shared configuration, and it does not even need to be explicitly passed in from the parent feature. Any changes made to this state will be immediately persisted to user defaults, and further if something writes to the “count” key in user defaults directly without going through @Shared, the state in your feature will be immediately updated too.

The .appStorage persistence strategy is limited by the kinds of data you can store in it since user defaults has those limitations. It’s mostly appropriate for very simple data, such as strings, integers, booleans, etc.

There is also a .fileStorage strategy you can use to persist data. It requires that your state is Codable, and it’s more appropriate for complex data types rather than simpler values. We use this kind of persistence in our SyncUps demo application for persisting the list of sync up meetings to disk:

@ObservableState
struct State: Equatable {
  @Presents var destination: Destination.State?
  @Shared(.fileStorage(.syncUps)) var syncUps: IdentifiedArrayOf<SyncUp> = []
}

This persistence strategy behaves like .appStorage in many ways. Using it makes the state globally available to all parts of the application, and any change to the state will be persisted to disk. Further, if the data on disk is changed outside of @Shared, that change will be immediately played back to any feature holding onto @Shared.

There is a third form of persistence that comes with the library called .inMemory. It has no restrictions on the kind of value you can hold in it, but that’s only because it doesn’t actually persist the data anywhere. It just makes the data globally available in your application, and it will be cleared out between app launches. It is similar to the “in-memory” persistence storage from SwiftData.

It is even possible for you to create your own persistence strategies! You can simply conform a new type to the PersistentKey protocol, implement a few requirements, and then it will be available to use with @Shared.

Testing

Shared state behaves quite a bit different from the regular state held in Composable Architecture features. It is capable of being changed by any part of the application, not just when an action is sent to the store, and it has reference semantics rather than value semantics. Typically references cause series problems with testing, especially exhaustive testing that the library prefers (see Testing), because references cannot be copied and so one cannot inspect the changes before and after an action is sent.

For this reason, the @Shared property wrapper does extra working during testing to preserve a previous snapshot of the state so that one can still exhaustive assert on shared state, even though it is a reference.

For the most part, shared state can be tested just like any regular state held in your features. For example, consider the following simple counter feature that uses in-memory shared state for the count:

@Reducer 
struct Feature {
  struct State: Equatable {
    @Shared var count: Int
  }
  enum Action {
    case incrementButtonTapped
  }
  var body: some ReducerOf<Self> {
    Reduce { state, action in
      switch action {
      case .incrementButtonTapped:
        state.count += 1
        return .none
      }
    }
  }
}

This feature can be tested in exactly the same way as when you are using non-shared state:

func testIncrement() async {
  let store = TestStore(initialState: Feature.State(count: Shared(0))) {
    Feature()
  }

  await store.send(.incrementButtonTapped) {
    $0.count = 1
  }
}

This test passes because we have described how the state changes. But even better, if we mutate the count incorrectly:

func testIncrement() async {
  let store = TestStore(initialState: Feature.State(count: Shared(0))) {
    Feature()
  }

  await store.send(.incrementButtonTapped) {
    $0.count = 2
  }
}

…we immediately get a test failure letting us know exactly what went wrong:

❌ State was not expected to change, but a change occurred: …

    − Feature.State(_count: 2)
    + Feature.State(_count: 1)

(Expected: −, Actual: +)

This works even though the @Shared count is a reference type. The TestStore and Shared type work in unison to snapshot the state before and after the action is sent, allowing us to still assert in an exhaustive manner.

However, exhaustively testing shared state is more complicated than testing non-shared state in features. Shared state can be captured in effects and mutated directly, without ever sending an action into system. This is in stark contrast to regular state, which can only ever be mutated when sending an action.

For example, it is possible to alter the incrementButtonTapped action so that it captures the shared state in an effect, and then increments from the effect:

case .incrementButtonTapped:
  return .run { [count = state.$count] _ in
    count.wrappedValue += 1
  }

The only reason this is possible is because @Shared state is reference-like, and hence can technically be mutated from anywhere.

However, how does this affect testing? Since the count is no longer incremented directly in the reducer we can drop the trailing closure from the test store assertion:

func testIncrement() async {
  let store = TestStore(initialState: SimpleFeature.State(count: Shared(0))) {
    SimpleFeature()
  }
  await store.send(.incrementButtonTapped)
}

This is technically correct, but we aren’t testing the behavior of the effect at all.

Luckily the TestStore has our back. If you run this test you will immediately get a failure letting you know that the shared count was mutated but we did not assert on the changes:

❌ Tracked changes to 'Shared<Int>@MyAppTests/FeatureTests.swift:10' but failed to assert: …

  − 0
  + 1

(Before: −, After: +)

Call 'Shared<Int>.assert' to exhaustively test these changes, or call 'skipChanges' to ignore them.

In order to get this test passing we have to explicitly assert on the shared counter state at the end of the test, which we can do using the Shared/assert(_:file:line:) method:

func testIncrement() async {
  let store = TestStore(initialState: SimpleFeature.State(count: Shared(0))) {
    SimpleFeature()
  }
  await store.send(.incrementButtonTapped)
  store.state.$count.assert {
    $0 = 1
  }
}

Now the test passes.

So, even though the @Shared type opens our application up to a little bit more uncertainty due to its reference semantics, it is still possible to get exhaustive test coverage on its changes.

Get started today!

We are very excited about these new shared state tools in the Composable Architecture, and we would love to get your feedback on it. Please consider pointing your project to the shared-state-beta branch and letting us know if anything goes wrong. Also be sure to read the Sharing State article and 1.9 migration guide for more information on the tools.



Subscribe to Point-Free

👋 Hey there! See anything you like? You may be interested in subscribing so that you get access to these episodes and all future ones.

Older blog posts

Monday Jan 29, 2024

Point-Free turns 6! 🥳

We launched Point-Free 6 years ago today! To celebrate we are announcing a live stream taking place next week, February 5th at 9am PST / 5pm GMT.

Monday Jan 29, 2024

Observation comes to the Composable Architecture

Swift 5.9's observation tools have officially been integrated into the Composable Architecture, simplifying nearly every facet of the library. Join us for an overview, as well as a special announcement!

Tuesday Jan 9, 2024

Perception: A back-port of @Observable

We have back-ported Swift 5.9's observation tools to work on Apple platforms going back almost 4 years ago! Start using it today even if you cannot target iOS 17.

Tuesday Dec 19, 2023

2023 Year-in-review

Point-Free year in review: 45 episodes, 200K unique visitors, 4 new open source projects, and a whole bunch more!

Monday Nov 27, 2023

Observable Architecture Beta!

Today the Composable Architecture crossed 10,000 stars on GitHub, _and_ we are announcing a beta preview for the biggest change we have made to the Composable Architecture in its history. We are integrating Swift's Observation framework into the library, and it revolutionizes nearly every aspect of the library.

Friday Nov 17, 2023

Macro Bonanza

This week was dedicated to the Macro Bonanza, where we showed how Swift's macro system allowed us to greatly simplify 4 of our popular libraries, as well as improve their ergonomics and increase their power. Join us for an overview!

Thursday Nov 16, 2023

Macro Bonanza: Dependencies

In part 4, and the final part, of our Macro Bonanza we demonstrate how macros allow us to better design dependencies when using our popular Dependencies library. Large amounts of boilerplate code can be automatically generated for us, and the ergonomics of our dependencies can be greatly improved.

Wednesday Nov 15, 2023

Macro Bonanza: SwiftUI Navigation

In part 3 of our Macro Bonanza we show how the improvements to case paths greatly simplify our SwiftUINavigation library. It allows us greatly simplify how one drives navigation from optionals and enums in SwiftUI.

Tuesday Nov 14, 2023

Macro Bonanza: Composable Architecture

In part 2 of our Macro Bonanza we show what macros bring to our popular library, the Composable Architecture. It can make our feature code simpler, more succint and safer!

Monday Nov 13, 2023

Macro Bonanza: Case Paths

Macros are finally available in Swift, and to celebrate we are releasing updates to 4 of our popular libraries to greatly simplify and enhance their abilities, starting with CasePaths!

Tuesday Oct 17, 2023

Being a good citizen in the land of SwiftSyntax

How can you be a good citizen in the new world of SwiftSyntax proliferation? Follow our advice to keep the greater Swift ecosystem healthy and thriving.

Tuesday Oct 3, 2023

MacroTesting 0.2.0: Test more with less

A couple weeks after its initial release, we have an update to MacroTesting that makes it even easier to fully assert on your macros, including holistic testing of diagnostics, fix-its, and expanded source code.

Monday Sep 18, 2023

A new tool for testing macros in Swift

With the release of Swift 5.9 and its new macros feature, we are excited to announce a brand new open source library: Macro Testing. It includes powerful tools for writing tests for your macros.

Wednesday Sep 13, 2023

Inline Snapshot Testing

We are releasing a major update to our popular SnapshotTesting library: inline snapshot testing! This allows your text-based snapshots to live right in the test source code, rather than in an external file.

Monday Jul 31, 2023

Composable Architecture 1.0

1.0 of the Composable Architecture is finally here! 🎉

Friday Jul 28, 2023

Streamlined team invites

We have streamlined team invites by making it as easy as sharing a link with your colleagues.

Wednesday Jul 19, 2023

Reliably testing async code in Swift

Swift makes it easy to write powerful, succinct async code, but how easy is it to test that code? We show how seemingly reasonable async code can be nearly impossible to test, and then how what can be done about it.

Tuesday Jul 18, 2023

Announcing Concurrency Extras: Useful, testable Swift concurrency.

Today we are excited to announce a brand new open source library: Concurrency Extras. It includes tools to help make your concurrent Swift code more versatile and more testable.

Tuesday May 30, 2023

Navigation tools come to the Composable Architecture

We are finally releasing first-class navigation tools for the Composable Architecture after 16 episodes and 3 months of beta testing.

Monday Apr 17, 2023

Composable navigation beta, part 2

As we begin to explore navigation stacks in the Composable Architecture we are releasing the second beta of our navigation tools.

Monday Feb 27, 2023

Composable navigation beta

Alongside our series on navigation in the Composable Architecture we are kicking off a beta so that you can start testing these tools today.

Monday Feb 13, 2023

Composable Architecture 1.0 Preview

We are very excited to officially share a preview of what 1.0 will bring to the Composable Architecture.

Monday Feb 6, 2023

Watch our first ever livestream

Last week we hosted our first ever livestream. In an hour and a half we discussed some of the tools that our Dependencies library comes with that we didn't have time to discuss in episodes, and we live refactored our open-source Standups app to use the new iOS 16 `NavigationStack`. We also answered 18 viewer questions, and just have 94 more left in the queue. 😅

Sunday Jan 29, 2023

Point-Free turns 5

We launched Point-Free 5 years ago today! There's still so much more we want to do, but we'll start with two things that many people have asked for: livestreams and a community Slack!

Friday Jan 27, 2023

Modern SwiftUI

A call to action: how would *you* rebuild Apple's "Scrumdinger" application? We've shown our take on modern SwiftUI, but we would love to see how you tackle the same problems. Don't like to use a observable objects for each screen? Prefer to use @StateObject instead of @ObservedObject? Want to use an architectural pattern such as VIPER? Have a different way of handling dependencies? Please show us!

Friday Jan 27, 2023

Modern SwiftUI: Testing

We show how the investments we made in the first 4 parts of this series of posts pays off when it comes to testing. Each decision helps make it possible to write incredibly nuanced tests that exercise many different user flows in the application.

Thursday Jan 26, 2023

Modern SwiftUI: Dependencies

Learn about what dependencies are and why they wreak so much havoc in a code base, and then see what can be done to take back control over dependencies rather than let them control you.

Wednesday Jan 25, 2023

Modern SwiftUI: State-driven navigation

Learn how to best leverage optionals and enums when modeling state-driven navigation in SwiftUI.

Tuesday Jan 24, 2023

Modern SwiftUI: Identified arrays

Learn how to make lists of data in your SwiftUI applications safer and more performant by scrapping plain arrays and embracing "identified arrays".

Monday Jan 23, 2023

Modern SwiftUI: Parent-child communication

We are celebrating the conclusion of our 7-part series on Modern SwiftUI by releasing a blog post every day this week, detailing an area of SwiftUI development that can be modernized. We begin by exploring ways to facilitate parent-child communication in SwiftUI in a safe and ergonomic manner.

Monday Jan 9, 2023

A new library to control dependencies and avoid letting them control you

We are open sourcing a new dependency management system for Swift. Take control of your dependencies, don't let them control you.

Monday Dec 19, 2022

2022 Year-in-review

Point-Free year in review: 45 episodes, 150K visitors, dozens of open source releases, and more!

Thursday Dec 8, 2022

swift-parsing: Swift 5.7 improvements

In time for Advent of Code, a new release of swift-parsing brings several quality-of-life improvements to Swift 5.7 users.

Monday Nov 21, 2022

Better SwiftUI navigation APIs

Navigation in SwiftUI can be complex, but it doesn't have to be that way. We are releasing a new version of our SwiftUI Navigation library that makes it easier to use NavigationStack, alerts, confirmation dialogs, and even fixes a few bugs in SwiftUI.

Monday Oct 31, 2022

Non-exhaustive testing in the Composable Architecture

Exhaustive testing is one of the most powerful features of the Composable Architecture, but it can also be cumbersome for large, highly composed features. Join us for an overview of the "why" and "how" of exhaustive testing, as well as when it breaks down, and how non-exhaustive testing can help.

Monday Oct 24, 2022

Open Sourcing swift-clocks

Today we are open sourcing swift-clocks, a collection of tools that make working with Swift concurrency more testable and more versatile.

Monday Oct 10, 2022

Announcing the Reducer Protocol

Today we are releasing the biggest update to the Composable Architecture ever, completely reimagining how features are built with the library.

Thursday Sep 8, 2022

Improving Composable Architecture performance

The latest release of the Composable Architecture brings a number of performance improvements to its tools, and best of all, most of the changes came from collaboration with people in the TCA community! 🤗

Monday Aug 8, 2022

Async Composable Architecture

Today we are releasing the biggest update to the Composable Architecture since it's first release over 2 years ago. The library has all new concurrency tools allowing you to construct complex effects using structured concurrency, tie effect lifetimes to view lifetimes, and we accomplish all of this while keeping your code 100% testable. We think it might even be the best way to test concurrent code in SwiftUI applications. 😇

Tuesday Jul 12, 2022

Reverse Engineering SwiftUI’s NavigationPath Codability

Learn how to use Swift 5.7's new existential type super powers to encode and decode type-erased values.

Wednesday Jun 29, 2022

Introducing XCTUnimplemented

We've added a new tool to our XCTest Dynamic Overlay library, which makes it easier to construct stronger dependencies for tests.

Monday May 2, 2022

Open Sourcing URLRouting and VaporRouting

Introducing new routing libraries that make client-side and server-side routing easy with more type safety and less fuss.

Monday Apr 11, 2022

Parser-printer unification

A new release of swift-parsing brings printing capabilities to your parsers for transforming structured data back into unstructured data.

Monday Feb 14, 2022

Parser Errors

A new release of swift-parsing that brings delightful and informative error messaging to parser failures.

Wednesday Feb 9, 2022

Backtracking Parsers

Today we are releasing 0.6.0 of our swift-parsing library that changes its backtracking behavior.

Monday Jan 24, 2022

Introducing Parser Builders

Today we are releasing 0.5.0 of our swift-parsing library, which leverages result builders for creating complex parsers with a minimal amount of syntactic noise. Learn how in this week's blog post, and give the library a spin today!

Monday Jan 3, 2022

Unobtrusive runtime warnings for libraries

Runtime warnings in libraries are a great way to notify your users that something unexpected has happened, or that an API is being used in an incorrect manner. In this post we give an overview of some techniques that can be employed easily today, as well as discuss a technique for surfacing runtime warnings that is both very visible and unobtrusive.

Wednesday Dec 22, 2021

2021 Year-in-review

Point-Free year in review: 42 episodes, 72k visitors, 5 new open source projects, and more!

Tuesday Nov 16, 2021

Open Sourcing SwiftUI Navigation

Today we are open sourcing SwiftUI Navigation, a collection of tools for making SwiftUI navigation simpler, more ergonomic and more precise.

Tuesday Oct 26, 2021

Give the Gift of Point-Free

Today we are excited to announce that you can now gift a Point-Free subscription to your friends, colleagues and loved ones.

Wednesday Sep 15, 2021

Point Freebies: Swift Concurrency and More

We're celebrating the release of Xcode 13 by making all of our WWDC 2021 videos free! Explore SwiftUI's new refreshable and FocusState APIs, both in the context of vanilla SwiftUI and the Composable Architecture, and learn how to build a map-powered application from scratch using the new searchable API.

Monday Sep 6, 2021

The Composable Architecture ❤️ SwiftUI Bindings

Today we are improving the Composable Architecture's first-party support for SwiftUI bindings with a safer, even conciser syntax.

Monday Aug 23, 2021

Open Sourcing: Custom Dump

Today we are open sourcing Custom Dump, a collection of tools for debugging, diffing, and testing your application's data structures.

Wednesday Jul 14, 2021

Better Performance Bonanza

The past 3 weeks we've shipped updates to 3 of our libraries, focused on improving the performance of your Composable Architecture applications, and more!

Monday Jul 12, 2021

Open Sourcing Identified Collections

Today we are open sourcing Identified Collections, a library of data structures for working with collections of identifiable elements in a performant way.

Monday Jun 14, 2021

Announcing SwitchStore for the Composable Architecture

We are adding new tools for handling enum state in the Composable Architecture, with a focus on safety and performance.

Wednesday May 12, 2021

A Tour of isowords

This past month we released four completely free videos dedicated to diving into the real-world Swift code base of an iOS game we recently launched and open sourced: isowords.

Monday Mar 22, 2021

Better Testing Bonanza

We're open sourcing a library that makes it easier to be more exhaustive in writing tests.

Wednesday Mar 17, 2021

Open Sourcing isowords

We're open sourcing the entire code base to our newly released iOS word game, isowords!

Wednesday Mar 17, 2021

Announcing: isowords

We are excited to release isowords to the App Store, a new word search game for your phone. Download today!

Monday Mar 8, 2021

Composable Architecture Test Store Improvements

Composable Architecture 0.16.0 comes with significant improvements to its testing capabilities for tracking down effect-related failures.

Monday Feb 1, 2021

Composable Forms: Say "Bye" to Boilerplate!

Today we are releasing first-party support for concisely handling form data in the Composable Architecture.

Wednesday Dec 23, 2020

2020 Year-in-review

The Composable Architecture, dependency management, parsers, Combine schedulers and more! Join us for a review of everything we accomplished in 2020!

Monday Dec 21, 2020

Open Sourcing Parsing

Today we are open sourcing Parsing, a library for turning nebulous data into well-structured data, with a focus on composition, performance, and generality.

Tuesday Jun 30, 2020

The Composable Architecture and SwiftUI Alerts

Today we are releasing a new version of the Composable Architecture with helpers that make working with SwiftUI alerts and action sheets a breeze.

Monday Jun 22, 2020

Core Motion support in the Composable Architecture

We are releasing our second mini-library for the Composable Architecture, which makes it easy to use Core Motion.

Monday Jun 15, 2020

Open Sourcing CombineSchedulers

Today we are open-sourcing CombineSchedulers, a library that introduces a few schedulers that makes working with Combine more testable and more versatile.

Wednesday May 27, 2020

Instrumenting features built in the Composable Architecture

Today we are releasing first-party support for instrumenting features built in the Composable Architecture.

Wednesday May 20, 2020

Core Location support in the Composable Architecture

We are releasing a mini-library that makes it easy to use Core Location inside the Composable Architecture.

Tuesday May 12, 2020

Regional Discounts

Regional discounts takes 50% off a monthly or yearly personal subscription to anyone whose credit card is issued from a particular list of countries.

Monday May 4, 2020

Composable Architecture, the library

Today we are releasing the Composable Architecture as an open-source library. It is a way to build applications in a consistent and understandable way, with composition, testing and ergonomics in mind.

Wednesday Mar 11, 2020

Announcing Episode Collections

After over two years and nearly 100 episodes we are finally launching episode collections on Point-Free!

Friday Feb 21, 2020

Share Point-Free with friends and save!

Today we're excited to announce support for referral bonuses! When friends and colleagues of yours subscribe to Point-Free with your referral link, both of you will get one month free.

Tuesday Feb 4, 2020

Open Sourcing Case Paths

Today we are open sourcing CasePaths, a library that introduces the power and ergonomics of key paths to enums!

Monday Dec 30, 2019

2019 Year-in-review

Random number generators, parsers, SwiftUI, composable architecture and more! Join us for a review of everything we accomplished in 2019!

Monday Dec 23, 2019

Snapshot Testing SwiftUI

Snapshot testing gives us broad test coverage on our SwiftUI views with very little up front work.

Wednesday Dec 18, 2019

Free Video: Testing SwiftUI

A free video exploring how to test SwiftUI.

Wednesday Nov 20, 2019

A Crash Course in Combine

Two free videos exploring Apple's new Combine framework, its core components, and how to integrate it in your code.

Thursday Nov 7, 2019

Higher-Order Snapshot Testing

How to enrich snapshot testing strategies with additional behavior using higher-order constructions.

Tuesday Jul 30, 2019

SwiftUI and State Management Corrections

Xcode 11 beta 5 has brought lots of changes to SwiftUI, and we'd like to take a moment to provide corrections to our episodes based on these changes.

Monday Apr 29, 2019

Open Sourcing Enum Properties

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!

Monday Mar 18, 2019

Open Sourcing Gen

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

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?

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!