What is the purpose of functions being first-class types in Swift 5+?
Just to reiterate, this is not new in Swift 5. Functions have been first-class types in all versions of Swift.
This is important for a whole bunch of reasons, running between two extremes:
Let’s look at each in turn.
For an example of the first extreme, consider the
DispatchQueue
API as it’s expressed in C. A traditional C approach to this API would take a function pointer an a ‘context’ value. And, indeed, this API is available to C:
typedef void (*dispatch_function_t)(void * context);
void dispatch_async_f(
dispatch_queue_t queue,
void * context,
dispatch_function_t work
);
The problem with this API is that the callback function only has one parameter available, the
context
parameter. If you need to pass two values to this callback, you have to pack them into a
struct
. Worse yet, as this is an async function, you have to allocate that struct on the heap. It’s a royal pain.
Fortunately the C API also has a block-based variant:
typedef void (^dispatch_block_t)(void);
void dispatch_sync(
dispatch_queue_t queue,
dispatch_block_t block
);
Note A dispatch block is like a Swift closure.
It lets you capture parameters from the enclosing scope. It makes it much easier to supply a callback that takes multiple arguments. No extra
struct
, no manual allocations, and so on.
The above is looking at this from the perspective of the client, but it’s important to realise that the implementation relies on having first-class function values. Without it, you just wouldn’t be able to implement this sort of API.
For an example of the second extreme, take a look at any of the folks doing functional programming in Swift. A recent example is Regexes vs Combinatorial Parsing, by the inestimable Soroush Khanlou.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"