Last week, Joe Groff of the Swift Core Team published a post on the Swift forums discussing refining the Swift Generics model which was established by the Generics Manifesto, almost three years ago. The post introduced new changes to improve the UI of how generics work in the Swift language. The first part of this group of changes is the SE-0244 proposal. This proposal introduces some features around function return values.
The SE-0244 proposal addresses the problem of type-level abstraction for returns. At present Swift has three existing generics features in Swift 5.
The syntax of a type level abstraction is quite similar to generics in other languages, like Java or C#. In this users type out the function definitions, use angle brackets, and conventionally use T for a generic type, all of it happening at the function (or type) level. Each of the functions for Type-level abstraction has a placeholder type T. Each call site then gets to pick what concrete type is bound to T, making these functions very flexible and powerful in a variety of situations.
Value-level abstraction deals with individual variables. It is not concerned with making general statements about the types that can be passed into or out of a function; instead, developers need to worry only about the specific type of exactly one variable in one place.
Many swift libraries consist of composable generic components which provide primitive types along with composable transformations to combine and modify primitive shapes into more complex ones. These transformations may be composed by using the existential type instead of generic arguments. Existential types are like wrappers or boxes for other types. However, they bring more dynamism and runtime overhead than desired.
If a user wants to abstract the return type of a declaration from its signature, existentials or manual type erasure are the two choices. However, these come with their own tradeoffs.
Tradeoffs of existing generics features
The biggest problem of the original genetic manifesto is generalized existentials. Present existentials have a variety of use cases that could never be addressed.
Although existentials would allow functions to hide their concrete return types behind protocols as implementation details, they would not always be the most desirable tool for this job. This is because they don’t allow functions to abstract their concrete return types while still maintaining the underlying type’s identity in the client code.
Also, Swift follows in the tradition of similar languages like C++, Java, and C# in its generics notation, using explicit type variable declarations in angle brackets. However, this notation can be verbose and awkward. So new improvements need to be made for existing notations for generics and existentials.
Currently Swift has no way for an implementation to achieve type-level abstraction of its return values independent of the caller’s control. If an API wants to abstract its concrete return type from callers, it must accept the tradeoffs of value-level abstraction. If those trade-offs are unacceptable, the only alternative in Swift today is to fully expose the concrete return type.
These tradeoffs led to the introduction of a new type system feature to achieve type-level abstraction of a return type. Coined as reverse generics by Manolo van Ee, this system behaves similar to a generic parameter type, but whose underlying type is bound by the function’s implementation rather than by the caller.
This is analogous to the roles of argument and return values in functions; a function takes its arguments as inputs and uses them to compute the return values it gives back to the caller.
This process has already begun with a formal review in progress on SE-244: Opaque Result Types. This proposal covers the “reverse generics” idea and some keyword in return types.
“If adopted”, says Tim Ekl, a Seattle-area software developer, “it would give us the ability to return a concrete type hidden from the caller, indicating only that the returned value conforms to some protocol(s)”. He has also written an interesting blog post summarizing the discussion by Joe Groff on the swift forums page.
Note: The content of this article is taken from Joe Groff’s discussion. For extensive details, you may read the full discussion on the Swift forums page.