Dicas para jogar golfe em Dotty
Que dicas gerais você daria para jogar golfe no Dotty ? Estou procurando por ideias que possam ser aplicadas a problemas de golfe de código em geral que sejam pelo menos um pouco específicos para Dotty (por exemplo, "remover comentários" não é uma resposta). Por favor, poste uma dica por resposta.
Veja também dicas para jogar golfe no Scala
Respostas
Use parâmetro untupling
A untupling de parâmetro permite que você escreva funções aceitando uma única tupla como entrada, como se fossem funções que aceitam 2 parâmetros. Basicamente, você pode substituir esses
list.map{case(a,b)=>a+b}
//and
list.map{case(a,b)=>Seq(a,b)}
//or
list.map(t=>t._1+t._2)
//and
list.map(t=>Seq(t._1,t._2))
com isso, que é mais curto e mais bonito.
list.map(_+_)
//and
list.map(Seq(_,_))
Use as funções @main e toplevel
Se você precisar fazer um programa completo, use a @mainanotação em um método principal de nível superior.
@main def main={code}
É muito mais curto do que essas 2 abordagens:
object M extends App{code}
object M{def main(a:Array[String])={code}}
Literais Numéricos
Agora você pode escrever um literal de número para qualquer tipo definido pelo usuário com uma determinada instância / implícita da FromDigitscaracterística, como BigInte BigDecimal.
No Scala 2, para passar o número 9.999.999.999.999.999 para uma função que aceita BigInts, você teria que usar BigInt("9999999999999999"), mas agora você pode apenas dizer diretamente, 9999999999999999sem usar o método ou construtor apply explicitamente.
Você também pode usar sublinhados, notação científica, hexadecimal, etc., assim como qualquer literal de número normal, desde que a FromDigitsinstância desse tipo suporte essa notação, é claro. Ambos BigInte BigDecimalestão bem com sublinhados, mas BigIntpermitem apenas hexadecimais e apenas BigDecimalnotação científica (com decimais).
Chaves opcionais
Em expressões de correspondência, pelo menos, você pode salvar um byte usando a sintaxe baseada em indentação.
a match
case b=>c
case d=>e
tem 27 bytes, enquanto o código abaixo é 28.
a match{case b=>c case d=>e}
Como observação lateral, matchtambém recebe tratamento especial no que diz respeito ao encadeamento. O seguinte código Scala 2:
("foo"match{case x=>x})match{case x=>x}
agora pode ser escrito sem os parênteses:
"foo"match{case x=>x}match{case x=>x}
Deixe de fora newcom aplicativos de criadores
Você pode chamar construtores sem usar new(como Kotlin), tratando todas as classes como se elas tivessem applymétodos em seus companheiros. Isso economiza 4 bytes cada vez que você instancia algo, desde que new Foo()se torne justo Foo().
Isso também se aplica a dados (embora você raramente precise deles para o código de golfe):
given foo as Foo=new Foo() //bad
given foo as Foo=Foo() //better
given foo as Foo //great
Use tipos de correspondência para funções recursivas que correspondem a padrões
Fazer um typealias com um tipo de correspondência às vezes é mais curto do que usar uma função adequada. Por exemplo, tome esta implementação do cálculo KI (não é uma coisa real). O tipo não precisa :Any, então você economiza 7 bytes no total ( typeé 1 byte a mais def).
//A normal function
def r(t:Any):Any=t match{case(('K',x),y)=>r(x)case('I',x)=>r(x)case t=>t}
//With match types
type R[T]=T match{case(('K',x),y)=>R[x]case('I',x)=>R[x]case _=>T}
Reconhecidamente, neste exemplo particular, você poderia usar tuplagem automática,, ->literais de função de correspondência de padrões, etc. para tornar o def mais curto, mas este é apenas um caso. Quando você não está lidando com tuplas, ou o tipo de retorno é mais complexo do que apenas Any, ou você tem vários parâmetros, esta dica se torna mais útil.
Nova sintaxe de controle
Na maioria dos casos, a nova sintaxe de controle não encurta o código (e é, na verdade, mais detalhada), ela é útil para compreensão. Se sua expressão ou padrão termina ou começa com parênteses ou aspas duplas, você pode salvar um byte ou dois:
for((x,y,z)<-Seq((1,2,3),(3,4,5));y<-"foo")yield y+x //Old-style syntax
for(x,y,z)<-Seq((1,2,3),(3,4,5));y<-"foo"yield y+x //New control syntax
Não é tão útil quanto algumas outras coisas, como untupling de parâmetro, mas muitas vezes me encontro usando para compreensões para chamadas de função como f(foo)ou Seq(1,2), que terminam entre parênteses.
Veja-o rodar no Scastie .