Wednesday, February 20, 2019

The Curiously Recursive Inlinable Switch Pattern (CRISP)

Jordan Rose (via tweet):

When inlinable code switches over a non-frozen enum, it has to handle possible future cases (since it will be inlined into a module outside the standard library). You can see this in action with the implementation of round(_:) in FloatingPointTypes.swift.gyb, which takes a FloatingPointRoundingRule. It looks something like this:

[…]

Making round(_:) inlinable but still have a default case is an attempt to get the best of both worlds: if the rounding rule is known at compile time, the call will compile down to a single instruction in optimized builds; and if it dynamically turns out to be a new kind of rounding rule added in Swift 25 (e.g. .towardFortyTwo), there’s a fallback function, _roundSlowPath(_:), that can handle it.

It looks like the function is calling itself, but it’s actually calling a future version of itself that is guaranteed not to recurse.

Previously: Swift Proposal: Non-Exhaustive Enums.

Comments RSS · Twitter

Leave a Comment