Quem já usou Scala?

Scala parece que deixou o Groovy para trás como a grande vedete das linguagens criadas para a JVM. Tem até gente dizendo que a Sun deveria declarar que Java 8 vai ser Scala e ponto final. :slight_smile:

Mas alguém aqui já brincou pelo menos com Scala? O que é legal nela? O que não é tão legal? Eu pergunto do ponto de vista prático mesmo, não “a nível de pureza sintática.”

Sim, já fiz até um protótipo de quão mais limpa, legível e poderosa a JSR-310 se fosse implementada em Scala.

O que tem de bom em Scala?

[list]Não ter primitivos[/list]
[list]Operadores serem métodos[/list]
[list]Inferência de tipos[/list]
[list]Generics com covariância e contravariância na declaração e não no uso[/list]
[list]Implicit conversions[/list]
[list]Suporte a closures e functions[/list]
[list]Suporte a object[/list]
[list]Suporte a structural types[/list]
[list]Existential types[/list]
[list]Pattern matching[/list]
[list]Suporte a definição de visibilidade muito mais refinado[/list]
[list]Self-types[/list]
[list]A API[/list]
[list]Ter sido desenhada pra gerar bytecode (isso alguns discordariam)[/list]
[list]Interoperabilidade limpa com Java[/list]

E mais algumas coisas que eu esqueci. O que tem de ruim? Falta de doc, suporte inferior ao Java nas IDEs e não estar todo mundo usando :slight_smile:

Scala é bem legal, porém o sistema de tipos é incrivelmente complexo. Apesar de ser um ótimo exercício teórico, ter virtual types e generic types na mesma linguagem é muito perigoso do ponto de vista de uniformidade e simplicidade. Apesar de ter casos que um resolve que o outro não e vice-versa, deveriam ter escolhido apenas um dos dois.

Se generics já tem algumas sutilezas, virtual types com path dependant types são bem complicados de explicar. Sem falar que produzir um compilador que gere mensagens de erro úteis é incrivelmente dificil (basta ver que nhaca que o compilador do scala vomita nesse caso).

Porém, no entanto, acho que o maior problema de Scala é a plataforma no qual executa, não a linguagem em sí.

Por coincidência, saiu no developerworks um primeiro artigo de uma série sobre Scala:

The busy Java developer’s guide to Scala

Vocês podem dar uma palhinha de como ficam os generics em Scala? No Java eu já acho que tem umas coisas piradas, ainda mais quando mistura com autoboxing…

Scala tem suporte a existencial types, então vc pode escrever coisas como:


class C[T] { .. }

def foo (C[C[T for some {T}]] x) { ...}

medo++

Caramba, é o Existencialismo aplicado à programação!

Que tipo de problema você resolve com uma construção dessas, louds? Aquele “[T for some {T}]” está especialmente misterioso.

A sintaxe me pareceu incrivelmente enrolada e complexa. Java ganhou o mainstream porque a sintaxe era bem fácil. Basicamente fez com que OO fosse acessível para meros mortais.

E agora então com Ruby, fica ainda mais complicado ter que fazer um closure assim:

object Timer
{
  def oncePerSecond(callback: () => unit): unit =
  {
    while (true)
    {
      callback()
      Thread.sleep(1000)
    }
  }

  def timeFlies(): unit = 
  { Console.println("Time flies when you're having fun(ctionally)..."); }

  def main(args: Array[String]): unit =
  {
    oncePerSecond(timeFlies)
  }
}

Ao invés de assim:

def oncePerSecond
    while 1 do
        yield
        sleep 1
    end
end

def timeFlies
    puts "Time flies when you're having fun(ctionally)..."
end

oncePerSecond { timeFlies }

Acho que o pessoal deveria se inspirar no Ruby e fazer linguagens com uma sintaxe parecida… E que rodem sem problemas dentro da JVM como a Scala…

Acho também que poderiam haver outros projetos competindo com o JRuby. Não precisa ser 100% compatível com o Ruby. Precisa ter uma sintaxe parecida, as sacadas mais importantes (closures, tudo é objeto, tudo é expressão, alias, operadores são métodos, etc) e rodar bonito dentro da JVM. Não sei se foi essa a intenção do Scala, mas a sintaxe ficou intimidadora… Talvez se removesse os tipos ou deixásse-os opcionais como ActionScript ficaria mais legível?

Em Scala, generics são especificados usando colchetes ao invés do par menor/maior:

class List[+T] {
   def elements : Iterator[T] {
      // logica para gerar o iterator
   }
}

O legal é a declaração da covariância/contravariância junto com o tipo genérico. Ao invés de fazer como em Java, onde em todo lugar que você usa uma Collection, você normalmente declara como: Collection<? extends String>, em Scala você tem a opção de fazer isso na definição do tipo genérico, uma vez só.

Não sou o louds, mas espero que minha resposta sirva :slight_smile:

Um dos usos de forSome é permitir o uso de tipos genéricos sem ter que declará-los explicitamente no uso, como por exemplo:

def someFuntion[X](arg:SomeClass[X]): Option[(Y => Z ,Y)] forSome {type Y; type Z} = //...

Esse exemplo pode ser simplificado para:

def oncePerSecond(callback : =&gt; unit) =
 while (true) {
   callback
   Thread.sleep(1000)
 }

def timeFlies() = println(&quot;Time flies when you're having fun(ctionally)...&quot;)

oncePerSecond(timeFlies)

Os tipos só são requeridos quando não podem ser inferidos, as chaves podem ser suprimidas quando o método tem apenas uma expressão e para rodar como script, não é necessário um object.

:shock: :shock: :shock:

http://recipes.mentaframework.org/posts/list/41.page

No seu exemplo, creio que o método hello não precise ter o retorno declarado.

Tem razão. É a prática! :slight_smile:

Já mudei la…

Existencial types existem porque Scala não possui wildcards e da necessidade de operar sobre membros com argumentos genéricos. Eles preferiram adotar que o tipo tenha variância em vez de usar wildcards, não que seja ruim, mas se perde um pouco de expressividade quando a variância fica no tipo genérico em sí.

A utilidade de tipos existenciais é quando vc quer criar algo como:

void copy_1(&lt;List&gt;&lt;?&gt; a, List&lt;?&gt; b) { a.set(0, g.get(0)); } // não compila
def copy_1[T](&lt;List&gt;&lt;T&gt; a, List&lt;T&gt; b)  for some {type T} { a.set(0, g.get(0)); } // agora compila

Para quem se interessa em aprender Scala, tem esse tutorial (uma série de 6 posts), no blog do Daniel Spiewak

Bom link, valeu!

Eu também sou um dos que gostaram do Scala. Algo que me atraiu muito nele é o fato do pessoal já estar brincando com Scala + frameworks Java. O post que o Sérgio colocou uns tópicos atrás usando Menta + Scala mostra como a interoperabilidade entre Scala e código java existente é boa.

Particularmente, não sou um dos que vestiram a camisa do Ruby ou Rails (sem um motivo especial), mas era fato que java tava dando no saco. Neste caso, juntar um bom framework web (em IMHO, Wicket, por exemplo) e Scala, é simplesmente ótimo!

Resumindo, gostei do Scala e principalmente pelo fato de eu poder considerar e optar por um framework java em uma decisão de arquitetura sem necessariamente me amarrar a linguagem java e seus efeitos colaterais… rsrs…

Abraços!

Começo a desconfiar que Ruby dá um pau no Scala. Se eu estiver enganado por favor se manifestem.

Scala não tem metaprogramação.

Scala não tem continue nem break.

Scala não tem suporte a regex no nível da linguagem. (parece tão ruim quanto Java)

Scala é distribuído em jars, assim como Java. (Se uma biblioteca está com algum bug, vc tem que baixar o source, modificar e gerar o jar novamente. Com Ruby vc faz isso em um segundo!)

Scala não possui nenhum livro e nenhum suporte. (ok, isso vai mudar em breve)

A sintaxe de Scala é mais complexa e enrolada que a sintaxe de Ruby.

Espero estar enganado…