sexta-feira, 10 de julho de 2009

Scala parte I - sintaxe

Durante a escrita de um outro artigo (ainda a ser publicado), percebi que preferia escrever os exemplos em uma linguagem de programação chamada Scala ao invés de Java. Por isso, ao invés de explicar todas as linhas do código, resolvi escrever um pouco sobre esta linguagem que, na minha humilde opinião, tem potencial para ser a próxima grande linguagem de programação.

O que é Scala?
Scala é uma linguagem de programação orientada a objetos, com tipagem estática e compilada, que é executada na JVM e na máquina virtual do .Net[1]. Além disso, Scala tem muitas funcionalidades típicas de linguagens de programação funcional, como closures, otimização de chamadas recursivas, etc. Por último, por ser primariamente executada na JVM, apresenta ótima compatibilidade com Java, podendo se aproveitar das muitas bibliotecas existentes. Foi inventada por Martin Odersky e seu nome se refere à escalabilidade da linguagem, na medida em que pode ser usada para escrever pequenos scripts ou grandes sistemas completos, sem que haja uma alteração na maneira de escrever.

Como usar
Todos os exemplos abaixo podem ser testados no console de Scala, invocado por scala ou scala.bat dependendo do seu sistema operacional.

Um pouco sobre a sintaxe
Na sua estrutura geral, Scala se parece muito com Java, embora os detalhes da sintaxe sejam bastante diferentes. Para começar, a declaração de variável é precedida de val ou var e o tipo da variável é pós-escrito e separado do nome da variável por ':', desse modo:

var umaString: String = "aaa";
val umNumero: Int = 1;

uma variável declarada como var pode ser reassignada, enquanto que uma variável declarada com val é imutável, ou seja, para todos os efeitos, equivalente a declarar uma variável 'final' em Java. O compilador de Scala permite, porém, que se omita o tipo de uma variável (que deve ser sempre inicializada durante a declaração):

var outraString = "aaa"
val umDouble = 0.0

E o ';' pode ser omitido se for desnecessário (ou seja, na última expressão de uma linha).
Métodos em Scala são definidos pela palavra chave 'def':

def metodoSemParametros():String = { "a" }

O ':String' significa que o método devolve String. O retorno do método, se omitido, é o resultado da última expressão do método. Um método com parâmetros:

def metodoComUmParametroInteiro(parametro: Int) = parametro + 1

Este método declara um parâmetro do tipo Int (que é o mesmo que 'int'). Neste caso, o compilador também infere e insere o tipo de retorno do método e os delimitadores também são opcionais para métodos compostos por apenas uma expressão. Por falar em expressão, Scala é composto quase que exclusivamente por expressões, o que significa que você pode atribuir quase qualquer coisa a uma variável (embora haja expressões do tipo Unit, o equivalente a void em C/C++/Java).


val maior: String = { if (1 > 2) { "1 maior que 2"} else { "1 menor que 2"} }

Mesmo para expressões desse tipo, o compilador infere o tipo da expressão e o insere se este for omitido. As chaves também podem ser omitidas para expressões únicas:

val maior = if (1 > 2) "1 maior que 2" else "1 menor que 2"

Escrever classes em Scala é bem simples:

class MinhaClasse {
var propriedadeMutavel: String = "a"
val valorImutavel = 10
}


Var e Val dentro do corpo da classe criam propriedades mutáveis e imutáveis respectivamente (o bytecode gerado é o equivalente a um campo e getters e setters).
Isso faz com que classes cliente não saibam se determinado valor vindo de outra classe é um campo ou uma invocação de método, uma propriedade conhecida como princípio de acesso a dados uniforme.

Em Scala, há o conceito de construtor primário que deve ser chamado pelos outros construtores e sua assinatura está junto com a declaracao da classe:

class Ponto(x0: Int, y0: Int) {
val x = x0
val y = y0
}

Construtores auxiliares são declarados por métodos chamados 'this'

class Ponto(x0: Int, y0:Int) {
val x = x0
val y = y0

def this() = this(0, 0) //construtor vazio
}

Em especial, o construtor primário pode já ter a declaração de propriedades de classe:
class Ponto(val x:Int, val y:Int) {
def this() = this(0, 0)
}

Métodos em Scala podem ter praticamente qualquer nome:
class Ponto(val x:Int, val y:Int) {
def this() = this(0, 0)
def +(ponto: Ponto) = new Ponto(x + ponto.x, y + ponto.y)
}

Por último, generics em scala funcionam de maneira um pouco diferente e usam [ ] ao invés de < >, mas os detalhes serão dados em um post futuro. Além disso, posts posteriores vão mostrar construções avançadas, bem como algumas das propriedades que estão tornando scala uma linguagem tão popular

[1] - Embora o suporte ao .Net esteja bem defasado e incompleto.

Nenhum comentário:

Postar um comentário