A proposta dos pacotes de parâmetros de evolução do Swift começa com uma seção de Motivação que cita o seguinte trecho de feiura familiar:
func < (lhs: (), rhs: ()) -> Bool
func < <A, B>(lhs: (A, B), rhs: (A, B)) -> Bool where A: Comparable, B: Comparable
func < <A, B, C>(lhs: (A, B, C), rhs: (A, B, C)) -> Bool where A: Comparable, B: Comparable, C: Comparable
O problema aqui é que para implementar a comparação de tuplas, temos que implementá-la para 2-tuplas, implementá-la novamente para 3-tuplas, e assim por diante. E além disso, essa repetição significa que temos que desistir após algum tamanho máximo arbitrário de tupla (6-tuplas).
Minha pergunta é: exatamente como os pacotes de parâmetros do Swift resolvem esse problema? Olhando nos cabeçalhos do Swift 6, não vejo que a declaração de tupla <
tenha mudado em relação às versões anteriores do Swift. (Na verdade, não vejo nenhum uso de pacotes de parâmetros nos cabeçalhos do Swift, ponto final.) E em qualquer caso (e mais direto ao ponto), os pacotes de parâmetros não são sobre tuplas; eles são sobre variadics .
Então posso ver instantaneamente como implementaríamos a comparação entre duas listas variáveis de valores comparáveis:
func isLessThan<each T: Comparable>(lhs: repeat each T, rhs: repeat each T) -> Bool {
for pair in repeat (each lhs, each rhs) {
if pair.0 >= pair.1 {
return false
}
}
return true
}
E podemos chamar assim:
let result = isLessThan(lhs: 1, "a", rhs: 2, "b")
Ótimo — mas essas não são tuplas . Elas são listas variádicas. A raiz do problema é que não há como fazer uma lista variádica dinamicamente: você não pode transformar uma tupla (ou uma sequência) em uma lista variádica.
Então, como os pacotes de parâmetros resolvem o problema motivacional?