Saltar para o conteúdo

Scala (linguagem de programação)

Origem: Wikipédia, a enciclopédia livre.
Scala
Logo do Scala
Paradigma
Surgido em 20 de janeiro de 2004 (20 anos)
Última versão 3.3.1 (9 de setembro de 2023; há 14 meses[1])
Criado por Martin Odersky
Estilo de tipagem
  • estática
  • forte
  • inferida
Principais implementações maven-scala-plugin
Influenciada por
Influenciou
Licença BSD
Extensão do arquivo
  • .scala
  • .sc
Página oficial www.scala-lang.org

Scala (Scalable language) é uma linguagem de programação de propósito geral, diga-se multiparadigma, projetada para expressar padrões de programação comuns de uma forma concisa, elegante e type-safe (é a medida em que uma linguagem de programação desestimula ou impede erros de tipo). Ela incorpora recursos de linguagens orientadas a objetos e funcionais. Também é plenamente interoperável com Java. Scala é a sucessora de Funnel, uma linguagem baseada em join calculus. Scala é software de código aberto. Requer JDK versão 1.4 ou superior.[5] Scala é uma linguagem de programação relativamente nova. Mesmo assim, nos últimos anos, conquistou empresas gigantes como o Twitter e o Foursquare. Uma das primeiras diferenças entre Scala e uma linguagem como Java, é que Scala também suporta o paradigma funcional.

Scala foi desenvolvida em 2001 por Martin Odersky e pelo grupo dele na École Polytechnique Fédérale de Lausanne (EPFL), Lausana na Suíça.

Anteriormente, (1986-1989) Martin trabalhou como um estudante Ph.D. com Niklaus Wirth em ETH Zuerich como um estudante Ph.D. em Modula-2 e Oberon. Depois disso, ele trabalhou nos fundamentos da linguagem de programação e programação funcional.

Em 1995 ele se juntou com Philip Wadler para escrever uma linguagem de programação funcional que compila Java bytecode. Este trabalho no Pizza levou, eventualmente , para GJ, o novo compilador javac, e Java generics.

Em 1999, depois de se unir a EPFL, este trabalho mudou um pouco. A meta ainda era combinar programação orientada a objetos e programação funcional, mas sem as restrições impostas pela linguagem Java. O primeiro passo para este caminho era o Funnel, uma linguagem minimalista de busca baseada em redes funcionais, uma variante orientada a objetos de join calculus. Funnel era pura do ponto de vista de design de linguagem, com poucas características de linguagem primitiva. Quase tudo, incluindo classes e padrões correspondentes, seria feito por bibliotecas e codificações.

No entanto, foi descoberto que linguagem não era agradável para o uso na prática. Minimalismo era ótimo para desenvolvedores, mas não para usuários. Usuários não experientes não sabiam como fazer a codificação necessária, e usuários experientes ficavam entediados por ter as codificações repetitivamente. Também, se tornou claro que qualquer nova linguagem tem melhor chance de ser aceita com um amplo conjunto de bibliotecas padrões.

O segundo, e atual, é o Scala, que trouxe algumas das ideias do Funnel e colocou dentro de uma linguagem mais pragmática com foco especial no funcionamento com plataformas padrões. Scala não é uma extensão de Java, mas é completamente interoperável com ele. Scala traduz para Java bytecodes, e a eficiência de ele compilara programas normalmente iguais aos do Java. Uma segunda implementação de Scala compila .NET. O design do Scala começou em 2001. Um primeiro lançamento ao público foi em 2003. Em 2006, uma segunda, versão remodelada foi lançada como Scala v 2.0. Desde então a linguagem tem ganhado popularidade.

Em Janeiro de 2011, uma bolsa de pesquisa de cinco anos foi concedida ao grupo Scala, pelo Conselho Europeu de Investigação (CEI) com o valor total de €2,3 milhões. Já em Maio do mesmo ano, Odersky e seus colaboradores lançaram uma empresa, a Typesafe Inc. (posteriormente viria a ser chamada de Lightbend Inc.), a qual tinha como intuito fornecer à Scala suporte comercial, treinamento e serviços diversos. Isso só foi possível em decorrência do investimento que a Typesafe recebeu da Greylock Partners, no valor de $3 milhões.

Scala é similar a linguagem de programação Java, e roda na Java Virtual Machine, é compatível com programas java existentes. Uma implementação alternativa existe para a plataforma .NET, mas a plataforma base é mesmo para Java Scala é primariamente desenvolvida para a JVM e incorpora algumas de suas características. De qualquer forma, o suporte a .NET foi criado para deixá-la tão portátil entre duas plataformas o quanto possível. Scala ainda pode ser executada no Java Platform, Micro Edition Connected Limited Device Configuration.

A implementação em Scala é muito similar a usada em Java ou C. São utilizados os mesmos operadores e controles de estruturas bem similares.

Principais diferenças sintáticas:

  • Definições começam com uma palavra reservada.
  • Quando é preciso definir uma função começa-se com 'def', para definir uma variável é utilizado 'var' e para definir valores (variáveis apenas de leitura) começa-se com ‘val’.
  • O tipo do símbolo é declarado depois do símbolo e dois pontos. O tipo declarado pode ser omitido em alguns casos, porque o compilador pode identificá-lo pelo contexto.
  • O tipo Array é escrito como Array[T] em vez de T[], e o acesso aos elementos do array é feito, por exemplo, a(i) em vez de a[i].
  • Funções podem ser aninhadas dentro de outras funções. Funções aninhadas podem acessar parâmetros e variáveis locais anexando funções.

A linguagem Scala importa por padrão todas as classes do pacote java.lang, enquanto que todas as outras podem ser importadas explicitamente. A biblioteca de classes Java define um amplo conjunto de classes utilitárias, como Date e DateFormat. Como Scala interage diretamente com Java, não existem classes equivalentes na biblioteca de classes Scala, então os pacotes são importados do Java.

Exemplo:

import java.util.{Date, Locale}
import java.text.DateFormat
import java.text.DateFormat._

object FrenchDate {
   def main(args: Array[String]) {
      val now = new Date
      val df = getDateInstance(LONG, Locale.FRANCE)
      println(df format now)
  }
}

Orientação a objetos

[editar | editar código-fonte]

Scala é puramente orientada-a-objetos no sentido de todo o valor ser um Objeto. Tipos e comportamento dos objetos são descritos pelas classes e traços. Abstrações de classes são estendidas por "subclassing" e um flexível mecanismo de "mixin-based composition" como uma forma "limpa" de substituição a heranças múltiplas.

Classes em Scala são templates estáticos que podem ser instanciados como vários objetos em tempo de execução.

Um exemplo de definição de uma classe Ponto:

class Ponto(var x: Int, var y: Int) {
  def move(dx: Int, dy: Int): Unit = {
    x = x   dx
    y = y   dy
  }
}

Podemos criar um objeto do tipo Ponto utilizando a palavra reservada new:

object Main {
  def main(args: Array[String]) {
    val ponto = new Ponto(3, 5)
    println("("   ponto.x   ", "   ponto.y   ")")

    ponto.move(10, 10)
    println("("   ponto.x   ", "   ponto.y   ")")
  }
}

A saída gerada pelo programa é esta:

(3, 5)
(13, 15)


Programação funcional

[editar | editar código-fonte]

Scala é também uma linguagem funcional, no sentido de cada função ser um valor. Scala fornece uma sintaxe "leve" para definição de funções anônimas, ela suporta higher-order functions, ela permite que funções sejam aninhadas (funções são passadas como parâmetros dentro de outras funções, são tratadas como objetos), e suporta currying. Classes Scala e seu suporte interno para pattern matching modela tipos algébricos usados em muitas linguagens de programação funcionais. Além disso, sua noção de "pattern matching" natural é estendida para o processamento de arquivos XML com a ajuda de expressões regulares. Neste contexto, a linguagem se torna de grande valia para o processamento de sintaxes futuras. Estas características, fazem com que o Scala seja ideal para o desenvolvimento de aplicações como web services. Segue abaixo uma implementação do while loop que deve ser uma função que utiliza dois parâmetros: uma condição, de tipo booleano, e um comando , de tipo Unit. Ambas precisam ser passadas por nome, então elas são avaliadas repetidamente no loop de iteração:

def whileLoop(condition: => Boolean)(command: => Unit) {
  if (condition) {
    command; whileLoop(condition)(command)
  } else ()
}

Tipagem estática

[editar | editar código-fonte]

O Scala é equipado com um sistema de tipos expressivo, que reforça estaticamente que abstrações sejam usadas de maneira segura e coerente. Em particular, o sistema de tipos suporta:

  • programação genérica,
  • anotações de variância,,
  • superior e inferior tipo acoplado
  • classes e enumeração (tipo de dado)
  • tipo composto
  • auto referencia
  • métodos polimórficos.

Extensibilidade

[editar | editar código-fonte]

O design do Scala, reconhece o fato de, na prática, o desenvolvimento de aplicações de domínio-específico requerem extensões a linguagens de domínio-específico. O Scala fornece uma combinação única de mecanismos de linguagem, que possibilitam a adição de construções na forma de bibliotecas, e com boa facilidade:

  • qualquer método pode ser usado como um operador prefixo ou sufixo
  • Clausuras são construídas automaticamente dependendo do tipo esperado (target typing).

A junção das duas características, facilita a definição de novos "statements" sem estender a sintaxe e sem usar a mágica da metaprogramação.

Independência de plataforma

[editar | editar código-fonte]

Scala foi projetado para interoperar bem com ambientes de programação populares, tais como Java 2 Runtime Environment (JRE) e .NET CLR. Em particular, a interação com linguagens orientadas-a-objeto, Java e C# por exemplo, é a mais robusta quanto possível. Em outras palavras, Scala pode fazer uso de todas as bibliotecas disponíveis para Java/C#, endereçando o comum inconveniente de usar avançadas linguagens funcionais, em sua maioria centrada academicamente, frequentemente não oferecendo bibliotecas de muita qualidade, para uso prático, acesso a bancos de dados relacionais, processamento XML, expressões regulares, por exemplo. Scala pode realizar estas tarefas de uma maneira muito similar a qual é feita em Java ou C#. Scala tem o mesmo modelo de compilação (compilação separada, carregamento dinâmico de classe) de Java e C#.

Exemplos de sintaxe

[editar | editar código-fonte]

Programa olá mundo

Ver artigo principal: Programa Olá Mundo

Aqui está o programa "Olá Mundo" escrito em Scala:

object OlaMundo {
  def main(args: Array[String]) {
    println("Olá, Mundo!")
  }
}

ou

object OlaMundo extends Application {
  println("Olá, Mundo!")
}

Note como ele é bem similar com a sintaxe Java. A diferença mais notável é que não declaramos nada como static ou void; a palavra-chave object nos dá o objeto Singleton, nos livrando da necessidade de invocar qualquer outro construtor.

A linha seguinte invoca o compilador, assumindo que foi salvo como OlaMundo.scala:

> scalac OlaMundo.scala

E executa desta maneira:

> scala -classpath . OlaMundo

A compilação e execução deste modelo é idêntica ao Java, fazendo com que as ferramentas de automação (build) sejam compatíveis, como o Ant.

Exemplo de IF

A condição IF sempre em ternários:

val x = 30
val y = 15
val maximo = if (x > y) x else y

maximo: Int = 30

Exemplo de FOR

O FOR pode retornar valor:

val lista = lista(1, 2, 3, 4)
val par = for {
  i <- lista
  if (i % 2 == 0)
} yield i

par: lista[Int] = lista(2, 4)

Para realizar testes

[editar | editar código-fonte]

Formas para teste de códigos Scala:

  • A própria scala-library fornece SUnit, um xUnit como framework usando Assertions.
  • No site Rehersal encontra-se o projeto que fornece um framework mais extensivo usando Expectations e linguagem natural para testar nomes. Ele também é integrado com o Apache Ant.
  • No eclipse.org [1] encontra-se o compilador Eclipse onde pode ser feito um download, no menu ferramentas "HELP" do eclipse instale novos softwares digitando o endereço [Scala Update Site - http://www.scala-lang.org/scala-eclipse-plugin], e assim fazer os testes de programas em Scala.
  • Outra forma de teste é o site ideone[2] que permite que sejam compilados códigos em Scala e outras linguagens online.

Outro exemplo para estudo, números perfeitos:

object Numeros_Perfeitos {
  def main(args: Array[String]) = {
    println("------NÚMEROS PERFEITOS------")
    println("\nUm número se diz perfeito se eh igual a soma de seus divisores próprios." )
    println("Divisores próprios de um número positivo N são todos os divisores inteiros")
    println("positivos de N exceto o próprio N. ")
    println("Por exemplo, o número 6, seus divisores próprios são 1, 2 e 3, cuja soma = 6. ")
    println("--> 1   2   3 = 6 ")
    println("Outro exemplo é o numero 28, cujos divisores próprios são 1, 2, 4, 7 e 14,")
    println("e a soma dos seus divisores próprios é 28. ")
    println("--> 1   2   4   7   14 = 28  ")

    var cont, x, soma, t: Int=0
    var n = 4 // n = ao número de números perfeitos que irão ser achados

    println("\n\nPrograma mostra os 4 primeiros números perfeitos\n")
    while (cont != n) {
      x  = 1
      soma = 0
      for (i <- 1 to x - 1) {
        t = x % i
        if(t == 0) {
          soma  = i
        }
      }
      if (soma == x) {
        println(x)
        cont  = 1
      }
    }
  }
}

Akka

Akka é uma estrutura moderna middleware orientado a eventos, para a construção de alto desempenho e confiabilidade de aplicações distribuídas em Java e Scala. A lógica de negócios do Akka desacopla de baixo nível de mecanismos como threads e locks. A lógica de seu programa Scala ou Java vive em objetos ator leves que enviam e recebem mensagens. Com Akka, você pode facilmente configurar como os atores são criados, destruídos, programados e reiniciados após a falha.

Play framework!

Surgiu como um framework Java, que fornecia suporte a linguagem Scala. Mas reconhecendo o poder e produtividade da linguagem Scala, a versão 2.0 do framework foi totalmente re-escrita em Scala. Atualmente, o Play Framework! 2.0 é um framework Scala, com suporte a Java.

Uma das principais características desse framework é que ele foca no desenvolvimento de um "server-side stateless". Isso facilita a escalabilidade das aplicações desenvolvidas neste framework.

Assim como Interface em Java, existe em Scala um equivalente conhecido como mixin. Mixin é um mecanismo que incentiva o reuso de código e evita problemas causados pela herança múltipla.

Quando uma classe inclui um mixin, a classe implementa a interface e inclui, em vez de heranças, todos os atributos e métodos. Eles se tornam parte de uma classe durante a compilação . Mixins não precisam de uma interface implementada. A vantagem de implementar uma interface é que em linguagens estaticamente tipadas, instancias da classe podem ser passadas como parâmetros para métodos que necessitam daquela interface.

Outras linguagens que utilizam mixin:

  • ActionScript com bibliotecas Adobe Flex
  • Ada
  • C#
  • Ceylon
  • Cobra
  • ColdFusion
  • Curl
  • D
  • Dart
  • Factor
  • Fantom
  • Groovy
  • Ioke
  • JavaFX Script
  • JavaScript
  • Magik
  • Newspeak
  • Object REXX
  • OpenLaszlo
  • Perl
  • Perl 6
  • PHP's "traits"
  • Python
  • Racket
  • Ruby
  • Smalltalk
  • Symbian C
  • Strongtalk
  • Vala
  • Visual Dataflex
  • XOTcl/TclOO
  • Self
  • Groovy é uma linguagem orientada a objetos, alternativa dentro da plataforma Java.
  • Jython - Implementação em Java da linguagem Python.

Referências

  1. «Scala 3.3.1 LTS» (em inglês). 9 de setembro de 2023. Consultado em 9 de setembro de 2023 
  2. Fogus, Michael (6 de agosto de 2010). «MartinOdersky take(5) toList». Send More Paramedics. Consultado em 9 de fevereiro de 2012 
  3. «Scala Macros» 
  4. Martin Odersky et al., An Overview of the Scala Programming Language, 2nd Edition
  5. Martin Odersky et al, An Overview of the Scala Programming Language, 2nd Edition
  • ODERSKY, Martin; SPOON, Lex; VENNERS, Bill (2008). Programming in Scala. Mountain View: Artima. 736 páginas. ISBN 0-9815316-0-1 

Ligações externas

[editar | editar código-fonte]