Scala (linguagem sobre a JVM)

newsflash_logo.png&w=630&h=250&zc=1

Linguagem que foi criada em 2001, por Martin Odersky professor da EPFL ( École Polytechnique Fédérale de Lausanne ) e foi desenvolvida a partir da combinação de dois princípios. O primeiro deles é que uma linguagem de programação precisa ser “escalável”, no sentido de que os conceitos da linguagem são adequados tanto para descrever componentes pequenos como para descrever componentes grandes. O segundo princípio é que essa escalabilidade pode ser alcançada através da unificação de dois conceitos: a programação orientada a objetos e a programação funcional.

Scala foi desenvolvida para rodar em uma Máquina Virtual, primeiramente em uma Java Virtual Machine. Os códigos em java, assim como todas as competências do programador, são totalmente reutilizáveis quando se está programando em Scala, já que se pode fazer pleno uso das bibliotecas java já existentes e utilizar ambientes de programação já conhecidos como o Netbeans e Eclipse.

Scala é Orientada a Objetos e é Funcional

Além de ser uma linguagem puramente orientada a objetos, ou seja, no sentido em que tudo é um objeto, incluindo números e funções, Scala também é funcional no sentido em que funções são valores de primeira classe. Em uma linguagem funcional, a função é um valor do mesmo tipo, como, por exemplo, um inteiro ou uma string. Essas funções podem ser passadas como parâmetros para outras funções, podem ser devolvidos como resultados de funções ou podem até mesmo ser armazenados em variáveis. É possível também definir uma função dentro de outra função ou valores dentro dessa mesma função. Na maioria das linguagens tradicionais, como por exemplo Java, as funções não são valores.

Hello World !!!

Utilizaremos como exemplo o clássico “Hello world”. Ele ficará como abaixo:

 object HelloWorld {
 def main(args: Array[String]) {
 println("Hello, world!")
 }
 }

A estrutura deste programa consiste num método chamado main que recebe os argumentos da linha de comando, um array de string, como parâmetro; o corpo deste método consiste de uma chamada única ao método pré-definido println que recebe nossa amigável saudação como argumento. O código de main não retorna um valor, dessa forma não é necessário declarar um valor de retorno. Uma parâmetro não familiar para programadores Java é a declaração object que contém o método main. Essa declaração introduz o que é comumente chamado de objeto singleton, que é uma classe que possuirá apenas uma única instância.

A declaração acima contrói tanto a classe chamada HelloWorld quanto sua intância, também chamada de HelloWorld. Esta instância é criada sob demanda, no momento do seu primeiro uso. Um detalhe que merece destaque é que no código, o método main não é declarado como static . Isso ocorre por que membros estáticos (métodos ou campos) não existem em Scala. Ao invés de usar métodos estáticos, o programador Scala declara esses membros como objetos singletons.

Compilando o exemplo

Para compilar nosso código você deve usar scalac, o compilador Scala. scalac funciona como a maioria dos compiladores: ele recebe um fonte como argumento e talvez algumas opções, e produz um ou mais arquivos objeto. Os arquivos objetos aqui produzidos são arquivos .class, padrão Java.

Se você salvar o código acima num arquivo chamado HelloWorld.scala, você pode compilá-lo usando o comando abaixo:

> scalac HelloWorld.scala

Obs: O“ >” representa o prompt de comando, portanto não precisa ser digitado.

Isso irá gerar uma série de classes no diretório corrente. Uma dessas classes será chamada de HelloWorld.class, e contém a classe que deve ser diretamente executada pelo comando scala, como será mostrado a seguir.

Assim como o javac, o compilador scalac gera bytecodes que são equivalentes os mnemônicos do assembly. Estes bytecodes são traduzidos para sistema operacional e Hardware especifico pela JVM.

Rodando o exemplo

Uma vez compilado, um programa Scala pode ser facilmente executado através do comando scala. Seu uso é bem parecido com o do comando java, que é usado para executar programas Java, e aceita as mesmas opções. O exemplo acima pode ser executado como comando a seguir, que produz a saída esperada:

>scala – classpath . HelloWorld

Saida:

Hello, world!

Classes

Como vimos anteriormente, Scala é uma linguagem orientada a objetos, e dessa forma possui o conceito de classes. Essas classes, em Scala, são declaradas usando uma sintaxe muito parecida com a do Java. Uma das diferenças mais marcantes é que classes em Scala podem ter parâmetros. Isso é ilustrado com a definição abaixo de uma classe de uma classe para números complexos:

class Complex(real: Double, imaginary: Double) {
 def re() = real
 def im() = imaginary}

Essa classe Complex recebe dois argumentos, que são a parte real e a parte imaginária de um número complexo. Estes argumentos devem ser passados no momento da criação de uma instância da classe Complex, da seguinte maneira:

new Complex(1.5, 2.3)

A classe contém dois métodos, chamados re e im, que dão acesso a ambas as partes do número. Repare que o tipo de retorno desses dois métodos não é especificado explicitamente. Ele será definido automaticamente pelo compilador, que olha os métodos e deduz que o valor de retorno de ambos é um Double.

O compilador, porém, pode não estar sempre apto a saber qual o tipo de retorno,e não há uma regra simples para saber qual o tipo que ele efetivamente usou. Na prática isso não é um problema visto que o compilador sabe que só pode mudar o tipo que não foi explicitamente passado. Como uma dica, o programador iniciante em Scala devem tentar omitir tipos quando esses forem fáceis de perceber no contexto, e ver como o compilador se comporta. Após algum tempo o programador terá um bom aprendizado sobre que tipo pode ou não omitir.}}

Métodos sem argumentos

Um pequeno problema dos métodos re e im é que, para chamar-los, deve-se usar um par de parênteses vazios ao lado de seu nome, como pode ser visto abaixo:

object ComplexNumbers {
 def main(args: Array[String]) {
 val c = new Complex(1.2, 3.4)
 println("imaginary part: " + c.im())
 }
 }

O ideial seria acessar a parte real e a parte imaginária como campos, sem a necessidade de colocar esse par de parenteses ao lado do nome. Isso pode ser feito em Scala através da definição de métodos sem argumentos. A classe Complex pode ser reescrita como abaixo:

class Complex(real: Double, imaginary: Double) {
 def re = real
 def im = imaginary
 }

Herança e polimorfismo

Todas as classes em Scala herdam de uma super-classe. Quando não é informada de qual super-classe deverá herdar, como no nosso exemplo complex, é usado por padrão scala.Object. Desta forma é possível sobrescrever métodos herdados da super-classe. Em Scala é obrigatório especificar que o método está sendo sobrescrito através do uso do modificador override, para evitar sobrescritas acidentais.

Por exemplo, nosso código da classe Complex pode ser ampliado com a redefinição do método toString, herdado da classe Object.

class Complex(real: Double, imaginary: Double) {
 def re = real
 def im = imaginary
 override def toString() =
 "" + re + (if (im < 0) "" else "+") + im + "i"
 }

Referencias:

http://programming-scala.labs.oreilly.com/

http://www.scala-lang.org/

http://ccsl.ime.usp.br/pt-br/uma-introducao-a-linguagem-scala

http://www.artima.com/scalazine/articles/scalable-language.html

http://leonardom.wordpress.com/tag/jvm/

http://www.arquiteturajava.com.br/livro/java-como-plataforma-nao-como-linguagem.pdf

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License