A generic argument list refers to the bit in angle brackets that follow a method name and precede the parenthesized argument list. These clauses specify generic type arguments and the constraints that limit their application. Swift generic specification can grow very big very quickly. And they are a pain to wrap.
The Swift Standard Library group has come up with a creative way to handle this situation, which is about as aesthetically pleasing as Soviet Brutalist Architecture:
public init<
S : Sequence where S.Iterator.Element == Iterator.Element
>(_ elements: S) {
self.init()
append(contentsOf: elements)
}
The line that really kills it for me is the one with the closing angle bracket, the argument list, and the opening brace all on the same line.
As the generic argument and parameter lists grow longer, Apple’s folding style becomes less standardized. This example puts where
on its own line (not a bad thing) but breaks out the function parameter list into three lines
internal func _transcodeSomeUTF16AsUTF8<
Input : Collection
where
Input.Iterator.Element == UInt16>(
input: Input, _ startIndex: Input.Index
) -> (Input.Index, _StringCore._UTF8Chunk) {
typealias _UTF8Chunk = _StringCore._UTF8Chunk
...
}
The example that follows co-aligns where
but confuses me with its long parameter list, which is broken into lines of three apparently unrelated undefaulted parameters and a following line with a defaulted parameter.
static func fromCodeUnits<
Input : Collection, // Sequence?
Encoding : UnicodeCodec
where Input.Iterator.Element == Encoding.CodeUnit
>(
input: Input, encoding: Encoding.Type, repairIllFormedSequences: Bool,
minimumCapacity: Int = 0
) -> (_StringBuffer?, hadError: Bool) {
Swift allows the angle bracket to be spaced away from a function name even though that’s an atypical use and I am, frankly, not a fan. For example, the following example compiles and works as you’d expect
// This will compile
protocol MyProtocol {}
func myFunction
<T: MyProtocol>
(x: T)
{
...
}
And you can further break down the generic argument clause onto new lines. Xcode doesn’t really like this so you have to hand-indent the components:
func myFunction
<
T: MyProtocol
>
(x: T)
{
print(x)
}
So if you really wanted to, you could build something more like this:
internal func _transcodeSomeUTF16AsUTF8
< Input : Collection
where
Input.Iterator.Element == UInt16
>( input: Input, _ startIndex: Input.Index
) -> (Input.Index, _StringCore._UTF8Chunk) {
typealias _UTF8Chunk = _StringCore._UTF8Chunk
...
}
Whether you’d want to is another discussion. This refold certainly emphasizes the generics, parameters, and return type sections.
Moving back a little into reality world, here’s a deployed example from the Github Focus repo. In this example, extra indentation helps move the where clauses closer to the starting bracket of the argument list.
public func • <Left : LensType, Right : LensType where
Left.Target == Right.Source,
Left.AltTarget == Right.AltSource>
(l : Left, r : Right) -> Lens<Left.Source, Left.AltSource, Right.Target, Right.AltTarget> {
return l.compose(r)
}
Here’s one from TJ:

While I like the intent, I really don’t like the abnormal indentation. So I pulled up an old example from my massive “notes and tests” playground to share. This one uses multiple generic arguments and constraints but fairly standard indentation. Unlike all the preceding examples, my where
keyword and constraints are spaced in further than the type arguments.
func ====<
Seq1: SequenceType,
Seq2: SequenceType
where
Seq1.Generator.Element == Seq2.Generator.Element,
Seq1.Generator.Element: Equatable
>(seq1: Seq1, seq2: Seq2) -> Bool
{
var gen2 = seq2.generate()
return !seq1
.lazy
.contains({ $0 != gen2.next() })
&& gen2.next() == nil
}
In terms of readability I think it’s pretty clear where each part of the generic story is expressed. Using the same approach, here is the refolded fromCodeUnits
example:
static func fromCodeUnits<
Input : Collection, // Sequence?
Encoding : UnicodeCodec
where
Input.Iterator.Element == Encoding.CodeUnit
>(
input: Input,
encoding: Encoding.Type,
repairIllFormedSequences: Bool,
minimumCapacity: Int = 0
) -> (_StringBuffer?, hadError: Bool)
{
...
}

What do you think? Are there any specific rules you follow? And do you have any folding examples to share? Let me know.