Pitch: Introduce (static) callables

We've also had requests from performance-minded Swift programmers to be able to avoid the type-erasure inherent to closures and function types. One way we could realize that would be to allow function types to be used as generic constraints in addition to being used as types:

struct BoundClosure<T, F: (T) -> ()>: () -> () {
  var function: F
  var value: T

  call() { return function(value) }
}

let f = BoundClosure({ print($0), x }) // instantiates BoundClosure<(underlying type of closure), Int>
f() // invokes call on BoundClosure

where such a constraint implicitly requires that a conforming type have a call operator with the same signature. Whereas a function value always has a fixed, indirect layout, a type parameterized on a function constraint like this could capture the function object's layout inline, and allow for efficient "protocol-oriented" composition of function objects, similar to how function objects can compose in D or Rust. This might be an interesting future direction to consider as part of this design space.

19 Likes