From 6e095d2479d7df94a9d02852f2ecd2245ffe2100 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Thu, 5 Jan 2017 20:52:06 -0200 Subject: [PATCH 01/34] Tutorials - Translation PT-BR - Tour Of Scala --- pt-br/tutorials/tour/tour-of-scala.md | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 pt-br/tutorials/tour/tour-of-scala.md diff --git a/pt-br/tutorials/tour/tour-of-scala.md b/pt-br/tutorials/tour/tour-of-scala.md new file mode 100644 index 0000000000..a3323ea079 --- /dev/null +++ b/pt-br/tutorials/tour/tour-of-scala.md @@ -0,0 +1,48 @@ +--- +layout: tutorial +title: Introdução + +disqus: true + +tutorial: scala-tour +num: 1 +outof: 33 +tutorial-next: unified-types +--- + +Scala é uma linguagem de programação moderna e multi-paradigma desenvolvida para expressar padrões de programação comuns em uma forma concisa, elegante e com tipagem segura. Integra fácilmente características de linguagens orientadas a objetos e funcional. + +## Scala é orienta a objetos ## +Scala é uma linguagem puramente orientada a objetos no sentido que [todo valor é um objeto](unified-types.html). Tipos e comportamentos de objetos são descritos por [classes](classes.html) e [traits](traits.html). Classes são estendidas por subclasses e por um flexível mecanismo [de composição mesclada](mixin-class-composition.html) como uma alternativa para herança múltipla. + +## Scala is functional ## +Scala é também uma linguagem funcional no sentido que [toda função é um valor](unified-types.html). Scala fornece uma [sintaxe leve](anonymous-function-syntax.html) para definir funções anônimas, suporta [funções de primeira ordem](higher-order-functions.html), permite funções [aninhadas](nested-functions.html), e suporta [currying](currying.html). As [case classes](case-classes.html) da linguagem Scala e o suporte embutido para [reconhecimento de padrões ou pattern matching](pattern-matching.html) modelam tipos algébricos utilizados em muitas linguagens de programação funcional. [Objetos únicos ou Singleton objects](singleton-objects.html) fornecem uma alternativa conveniente para agrupar funções que não são membros de uma classe. + +Além disso, a noção de reconhecimento de padrões em scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [extrator de objetos](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. + +## Scala é estaticamente tipada ## +Scala é equipada com um expressivo sistema de tipos que reforça estaticamente que abstrações são utilizadas de uma forma segura e coerente. Particularmente, o sistema de tipos suporta: + +* [Classes genéricas](generic-classes.html) +* [Anotações variáveis](variances.html) +* [Limites de tipos superiores](upper-type-bounds.html) e [limites de tipos inferiores](lower-type-bounds.html), +* [Classes internas](inner-classes.html) e [tipos abstratos](abstract-types.html) como membros de um objeto +* [Tipos compostos](compound-types.html) +* [Auto referências explicitamente tipadas](explicitly-typed-self-references.html) +* [parâmetros implícitos](implicit-parameters.html) e [conversões implícitas](implicit-conversions.html) +* [métodos polimórficos](polymorphic-methods.html) + +Um [mecanismo de inferência de tipo local](local-type-inference.html) se encarrega para que o usuário não seja obrigado a anotar o programa com informações reduntante de tipos. Combinados, esses recursos fornecem uma base poderosa para a reutilização segura de abstrações de programação e para a extensão de tipos seguro do software. + +## Scala é estensível ## + +Na prática, o desenvolvimento de uma aplicaçãoes de um determinado domínio geralmente requer uma linguagem de domínio específico. Scala fornece uma combinação única de mecanismos de linguagem que facilitam a adição suave de novas construções de linguagem na forma de bibliotecas: + +* qualquer método pode ser utilizado como um [operador infix ou postfix](operators.html) +* [closures são construídas automaticamente dependendo do tipo esperado](automatic-closures.html) (tipo alvo). + +Uma utilização conjunta de ambos os recursos facilita a definição de novas instruções sem estender a sintaxe e sem usar meta-programação como macros. + +Scala é projetada para interoperar bem com o popular Java 2 Runtime Environment (JRE). Em particular, a interação com a linguagem de programação orientada a objetos Java é o mais suave possível. Funcionalidades novas do Java como [annotations](annotations.html) e Java generics têm correspondentes diretos em Scala. Esses recursos Scala sem correspondentes Java, como [valor default de parâmetros](default-parameter-values.html) e [parâmetros nomeados](named-parameters.html), compilam de forma semelhante ao Java. Scala tem o mesmo modelo de compilação que Java (compilação separada, carregamento de classe dinâmica) e permite o acesso a milhares de bibliotecas de alta qualidade existentes. + +Continue na próxima página para ler mais. From f276868f77dd221a75c831ee21bb79925960be6e Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Thu, 5 Jan 2017 20:52:38 -0200 Subject: [PATCH 02/34] Tutorials - Translation PT-BR - Unified Types --- pt-br/tutorials/tour/unified-types.md | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 pt-br/tutorials/tour/unified-types.md diff --git a/pt-br/tutorials/tour/unified-types.md b/pt-br/tutorials/tour/unified-types.md new file mode 100644 index 0000000000..f4de23b09d --- /dev/null +++ b/pt-br/tutorials/tour/unified-types.md @@ -0,0 +1,48 @@ +--- +layout: tutorial +title: Tipos Unificados + +disqus: true + +tutorial: scala-tour +num: 2 +tutorial-next: classes +tutorial-previous: tour-of-scala +--- + +Diferente de Java, todos os valores em Scala são objetos (incluindo valores numéricos e funções). Dado que Scala é baseada em classes, todos os valores são instâncias de uma classe. O diagrama a seguir ilustra a hierarquia de classes. + +![Hierarquia de Tipos Scala]({{ site.baseurl }}/resources/images/classhierarchy.img_assist_custom.png) + +## Hierarquia de Tipos Scala ## + +A superclass de todas as classes `scala.Any` tem duas subclasses diretas `scala.AnyVal` e `scala.AnyRef` representando dois mundos de classes distintos: classes de valor e classes de referência. Todas as classes de valor são predefinidas; elas correspondem aos tipos primitivos em linguagens semelhante a Java. Todas as outras classes definem tipos de referência. Classes definidas pelo usuário definem tipos de referência por padrão; por exemplo, tais classes sempre (indiretamente) são subclasses de `scala.AnyRef`. Toda classes definida pelo usuário em Scala implicitamente estende a trait `scala.ScalaObject`. Classes de infraestrutura nas quais Scala está sendo executado (ex. ambiente de execução do Java) não estendem `scala.ScalaObject`. Se utilizar Scala no contexto do ambiente de execução do Java, então `scala.AnyRef` corresponde à `java.lang.Object`. +Observe que o diagrama acima mostra implicitamente as conversões entre as classes de valores. +Este exemplo demonstra que números numbers, caracteres, valores booleanos, e funções são objetos como qualquer outro objeto: + +```tut +object TiposUnificados extends App { + val set = new scala.collection.mutable.LinkedHashSet[Any] + set += "Sou uma string" // adiciona uma string ao set + set += 732 // adiciona um número + set += 'c' // adiciona um caractere + set += true // adiciona um valor booleano + set += main _ // adiciona a função main + val iter: Iterator[Any] = set.iterator + while (iter.hasNext) { + println(iter.next.toString()) + } +} +``` + +O programa declare uma aplicação chamada `TiposUnificados` em forma de um [objeto singular/único](singleton-objects.html) que estende `App`. A aplicação define uma variável local `set` que se refere à uma instância da classe `LinkedHashSet[Any]`. As demais linhas adicionam vários elementos à variável set. Tais elementos devem estar em conformidade com o tipo `Any` que foi declarado para o set. Por fim, são escritas as representações em string de todos os elementos adicionados ao set. + + +Escrita de saída do programa: +``` +Sou uma string +732 +c +true + +``` From 6cc8be715f12e724bd0a34a1e3fcb9d21b39c436 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Thu, 5 Jan 2017 20:53:23 -0200 Subject: [PATCH 03/34] Tutorials - Translation PT-BR - Classes --- pt-br/tutorials/tour/classes.md | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 pt-br/tutorials/tour/classes.md diff --git a/pt-br/tutorials/tour/classes.md b/pt-br/tutorials/tour/classes.md new file mode 100644 index 0000000000..cb108b4527 --- /dev/null +++ b/pt-br/tutorials/tour/classes.md @@ -0,0 +1,53 @@ +--- +layout: tutorial +title: Classes + +disqus: true + +tutorial: scala-tour +num: 3 +tutorial-next: traits +tutorial-previous: unified-types +--- + +Classes em Scala são templates estáticos que podem ser instânciados como vários objetos em tempo de execução. +Aqui uma definição de classe que define a classe `Ponto`: + +```tut +class Ponto(var x: Int, var y: Int) { + def move(dx: Int, dy: Int): Unit = { + x = x + dx + y = y + dy + } + override def toString: String = + "(" + x + ", " + y + ")" +} +``` + +Classes em Scala são parametrizadas com argumentos de construtor. O código acima define dois argumentos de construtor, `x` e `y`; ambos são acessíveis por todo o corpo da classe. + +A classe também inclui dois métodos, `move` and `toString`. `move` recebe dois parâmetros inteiros mas não retorna um valor (o tipo de retorno `Unit` equivale ao `void` em linguagens como Java). `toString`, por outro lado, não recebe parâmetro algum mas retorna um valor `String`. Dado que `toString` sobrescreve o método pré-definido `toString`, é marcado com a palavra-chave `override`. + +Perceba que em Scala, não é necessário declarar `return` para então retornar um valor. O valor retornado em um método é simplesmente o último valor no corpo do método. No caso do método `toString` acima, a expressão após o sinal de igual é avaliada e retornada para quem chamou a função. + +Classes são instânciadas com a primitiva `new`, por exemplo: + +```tut +object Classes { + def main(args: Array[String]) { + val pt = new Ponto(1, 2) + println(pt) + pt.move(10, 10) + println(pt) + } +} +``` + +O programa define uma aplicação executável chamada Classes como um [objeto singular/único](singleton-objects) dentro do método `main`. O método `main` cria um novo `Ponto` e armazena o valor em `pt`. Perceba que valores definidos com o construtor `val` são diferentes das variáveis definidas com o construtor `var` (veja acima a classe `Ponto`), `val` não permite atualização do valor, ou seja, o valor é uma constante. + +Aqui a saída do programa: + +``` +(1, 2) +(11, 12) +``` From 6747bd77be14072bc84ffa0d9bf7ddda1ff6802b Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Thu, 5 Jan 2017 20:53:38 -0200 Subject: [PATCH 04/34] Tutorials - Translation PT-BR - Traits --- pt-br/tutorials/tour/traits.md | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 pt-br/tutorials/tour/traits.md diff --git a/pt-br/tutorials/tour/traits.md b/pt-br/tutorials/tour/traits.md new file mode 100644 index 0000000000..4184c19a66 --- /dev/null +++ b/pt-br/tutorials/tour/traits.md @@ -0,0 +1,53 @@ +--- +layout: tutorial +title: Traits + +disqus: true + +tutorial: scala-tour +num: 4 +tutorial-next: mixin-class-composition +tutorial-previous: classes +--- + +Similar a interfaces em Java, traits são utilizadas para definir tipos de objetos apenas especificando as assinaturas dos métodos suportados. Como em Java 8, Scala permite que traits sejam parcialmente implementadas; ex. é possível definir uma implementação padrão para alguns métodos. Diferentemente de classes, traits não precisam ter construtores com parâmetros. +Veja o exemplo a seguir: + +```tut +trait Similaridade { + def eSemelhante(x: Any): Boolean + def naoESemelhante(x: Any): Boolean = !eSemelhante(x) +} +``` + +Tal trait consiste em dois métodos `eSemelhante` e `naoESemelhante`. Equanto `eSemelhante` não fornece um método com implementação concreta (que é semelhante ao abstract na linguagem Java), o método `naoESemelhante` define um implementação concreta. Consequentemente, classes que integram essa trait só precisam fornecer uma implementação concreta para o método `eSemelhante`. O comportamento para `naoESemelhante` é herdado diretamente da trait. Traits são tipicamente integradas a uma [classe](classes.html) (ou outras traits) utilizando a [composição mesclada de classes](mixin-class-composition.html): + +```tut +class Ponto(xc: Int, yc: Int) extends Similaridade { + var x: Int = xc + var y: Int = yc + def eSemelhante(obj: Any) = + obj.isInstanceOf[Point] && + obj.asInstanceOf[Point].x == x +} +object TraitsTest extends App { + val p1 = new Ponto(2, 3) + val p2 = new Ponto(2, 4) + val p3 = new Ponto(3, 3) + val p4 = new Ponto(2, 3) + println(p1.eSemelhante(p2)) + println(p1.eSemelhante(p3)) + // Ponto.naoESemelhante foi definido na classe Similaridade + println(p1.naoESemelhante(2)) + println(p1.naoESemelhante(p4)) +} +``` + +Aqui a saída do programa: + +``` +true +false +true +false +``` From a85e7f8611901f682fe9ba7953e934f89546bb05 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Thu, 5 Jan 2017 21:35:02 -0200 Subject: [PATCH 05/34] Tutorials - Translation PT-BR - Mixin Class Composition --- .../tutorials/tour/mixin-class-composition.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 pt-br/tutorials/tour/mixin-class-composition.md diff --git a/pt-br/tutorials/tour/mixin-class-composition.md b/pt-br/tutorials/tour/mixin-class-composition.md new file mode 100644 index 0000000000..68265da40f --- /dev/null +++ b/pt-br/tutorials/tour/mixin-class-composition.md @@ -0,0 +1,56 @@ +--- +layout: tutorial +title: Composição de Classes Mixin + +disqus: true + +tutorial: scala-tour +num: 5 +tutorial-next: anonymous-function-syntax +tutorial-previous: traits +language: pt-br +--- +_Nota de tradução: A palavra `mixin` pode ser traduzida como mescla, porém é preferível utilizar a notação original_ + +Ao contrário de linguagens que suportam somente _herança simples_, Scala tem uma noção mais abrangente sobre a reutilização de classes. Scala torna possível reutilizar a _nova definição de membros de uma classe_ (por exemplo: o relacionamento delta para com a superclasse) na definição de uma nova classe. Isso é expressado como uma _composição de classe mixin ou mixin-class composition_. Considere a seguinte abstração para iterators. + +```tut +abstract class AbsIterator { + type T + def hasNext: Boolean + def next: T +} +``` + +A seguir, considere a classe mixin que estende `AbsIterator` com um método `foreach` que aplica uma dada função para cada elemento retornado pelo iterator. Para definir tal classe que será utilizada como um mixin a palavra-chave `trait` deve ser declarada. + +```tut +trait RichIterator extends AbsIterator { + def foreach(f: T => Unit) { while (hasNext) f(next) } +} +``` + +Aqui uma classes iterator concreta a qual retorna sucessivos caracteres de uma dada string: + +```tut +class StringIterator(s: String) extends AbsIterator { + type T = Char + private var i = 0 + def hasNext = i < s.length() + def next = { val ch = s charAt i; i += 1; ch } +} +``` + +Poderíamos combinar a funcionalidade de `StringIterator` e `RichIterator` em uma só classe. Com herança simples e interfaces isso é impossível, pois ambas as classes contém implementações para seus membros. Scala nos ajuda com a sua _composição de classes mixin_. Isso permite que programadores reutilizem o delta de uma definição de uma classe, por exemplo: todas as novas definições não são herdadas. Esse mecanismo torna possível combinar `StringIterator` com `RichIterator`, como pode ser visto no programa teste a seguir, que imprime uma coluna de todos os caracteres de uma dada string. + +```tut +object StringIteratorTest { + def main(args: Array[String]) { + class Iter extends StringIterator(args(0)) with RichIterator + val iter = new Iter + iter foreach println + } +} +``` + +A classe `Iter` na função `main` é construída a partir de uma composição dos pais `StringIterator` e `RichIterator` com a palavra-chave `with`. O primeiro pai é chamado de _superclass_ de `Iter`, já o segundo pai (e qualquer outro que venha após) é chamado de _mixin_ ou mescla. \ No newline at end of file From e94a7dd39ce641fdc2a23d7ee27a96c238e91226 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Thu, 5 Jan 2017 21:44:00 -0200 Subject: [PATCH 06/34] Tutorials - Translation PT-BR - Anon Func Syntax --- .../tour/anonymous-function-syntax.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 pt-br/tutorials/tour/anonymous-function-syntax.md diff --git a/pt-br/tutorials/tour/anonymous-function-syntax.md b/pt-br/tutorials/tour/anonymous-function-syntax.md new file mode 100644 index 0000000000..d141ab44e3 --- /dev/null +++ b/pt-br/tutorials/tour/anonymous-function-syntax.md @@ -0,0 +1,54 @@ +--- +layout: tutorial +title: Sintaxe de Função Anônima + +disqus: true + +tutorial: scala-tour +num: 6 +tutorial-next: higher-order-functions +tutorial-previous: mixin-class-composition +language: pt-br +--- + +Scala fornece uma sintaxe relativamente leve para definir funções anônimas. A expressão a seguir cria uma função sucessor para inteiros: + +```tut +(x: Int) => x + 1 +``` + +Isso é uma abreviação para a definição de classe anônima a seguir: + +```tut +new Function1[Int, Int] { + def apply(x: Int): Int = x + 1 +} +``` + +Também é possível definir funções com mútiplos parâmetros: + +```tut +(x: Int, y: Int) => "(" + x + ", " + y + ")" +``` + +or sem parâmetros: + +```tut +() => { System.getProperty("user.dir") } +``` + +Há também uma forma muito simples de escrever tipos de funções. Aqui estão os tipos da três funções acima definidas: + +``` +Int => Int +(Int, Int) => String +() => String +``` + +Essa sintaxe é uma abreviação para os seguintes tipos: + +``` +Function1[Int, Int] +Function2[Int, Int, String] +Function0[String] +``` From 38e8ce78edc5ffed5acb35932319d6ecd4c27181 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Fri, 6 Jan 2017 09:26:51 -0200 Subject: [PATCH 07/34] Tutorials - Translation PT-BR - High Order Func --- .../tutorials/tour/higher-order-functions.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 pt-br/tutorials/tour/higher-order-functions.md diff --git a/pt-br/tutorials/tour/higher-order-functions.md b/pt-br/tutorials/tour/higher-order-functions.md new file mode 100644 index 0000000000..c0d8913b07 --- /dev/null +++ b/pt-br/tutorials/tour/higher-order-functions.md @@ -0,0 +1,42 @@ +--- +layout: tutorial +title: Funções de ordem superior + +disqus: true + +tutorial: scala-tour +num: 7 +tutorial-next: nested-functions +tutorial-previous: anonymous-function-syntax +language: pt-br +--- + +Scala permite definir funções de ordem superior. Tais funções _recebem outras como parâmetros_, as quais _o resultado é outra função_. Por exemplo, a função `apply` recebe outra função `f` e um valor `v` então aplica a função `f` em`v`: + +```tut +def apply(f: Int => String, v: Int) = f(v) +``` + +_Nota: métodos são automaticamente convertidos em funções se o contexto demandar.**_ + +Outro exemplo: + +```tut +class Decorator(left: String, right: String) { + def layout[A](x: A) = left + x.toString() + right +} + +object FunTest extends App { + def apply(f: Int => String, v: Int) = f(v) + val decorator = new Decorator("[", "]") + println(apply(decorator.layout, 7)) +} +``` + +A execução produz a saída: + +``` +[7] +``` + +Nesse exemplo, o método `decorator.layout` é automaticamente convertido em um valor do tipo `Int => String` conforme o método `apply` demanda. Note que o método `decorator.layout` é um _método polimórfico_ (por exemplo: ele abstrai alguns tipos de sua assinatura) e o compilador Scala precisa primeiro instanciar corretamento o tipo do método. From 6316f7f27818a860ee8fb53c2f91494abd879f87 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Fri, 6 Jan 2017 09:34:01 -0200 Subject: [PATCH 08/34] Tutorials - Translation PT-BR - Nested Functions --- pt-br/tutorials/tour/nested-functions.md | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 pt-br/tutorials/tour/nested-functions.md diff --git a/pt-br/tutorials/tour/nested-functions.md b/pt-br/tutorials/tour/nested-functions.md new file mode 100644 index 0000000000..23545e2f4b --- /dev/null +++ b/pt-br/tutorials/tour/nested-functions.md @@ -0,0 +1,35 @@ +--- +layout: tutorial +title: Funções Aninhadas + +disqus: true + +tutorial: scala-tour +num: 8 +tutorial-next: currying +tutorial-previous: higher-order-functions +language: pt-br +--- + +Em scala é possível aninhar definições de funções. O objeto a seguir fornece uma função `filter` para extrair valores de uma lista de inteiros que são abaixo de um determinado valor: + +```tut +object FilterTest extends App { + def filter(xs: List[Int], threshold: Int) = { + def process(ys: List[Int]): List[Int] = + if (ys.isEmpty) ys + else if (ys.head < threshold) ys.head :: process(ys.tail) + else process(ys.tail) + process(xs) + } + println(filter(List(1, 9, 2, 8, 3, 7, 4), 5)) +} +``` + +_Nota: a função aninhada `process` refere-se a variável `threshold` definida em um escopo externo como um parâmetro da função `filter`._ + +A saída gerada pelo programa é: + +``` +List(1,2,3,4) +``` From 582abf5f830a92e1e7affe226304f755f1643a98 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Fri, 6 Jan 2017 09:46:39 -0200 Subject: [PATCH 09/34] Tutorials - Translation PT-BR - Currying --- pt-br/tutorials/tour/currying.md | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 pt-br/tutorials/tour/currying.md diff --git a/pt-br/tutorials/tour/currying.md b/pt-br/tutorials/tour/currying.md new file mode 100644 index 0000000000..4cd370ea36 --- /dev/null +++ b/pt-br/tutorials/tour/currying.md @@ -0,0 +1,43 @@ +--- +layout: tutorial +title: Currying + +disqus: true + +tutorial: scala-tour +num: 9 +tutorial-next: case-classes +tutorial-previous: nested-functions +language: pt-br +--- + +_Nota de tradução: Currying é uma técnica de programação funcional nomeada em honra ao matemático e lógico Haskell Curry. Por essa razão a palavra Currying não será traduzida. Entende-se que é uma ação, uma técnica básica de Programação Funcional._ + +Métodos podem definir múltiplas listas de parâmetros. Quando um método é chamado com uma lista menor de parâmetros, então será retornada uma função que recebe a lista que parâmetros que falta como argumentos. + +Aqui um exemplo: + +```tut +object CurryTest extends App { + + def filter(xs: List[Int], p: Int => Boolean): List[Int] = + if (xs.isEmpty) xs + else if (p(xs.head)) xs.head :: filter(xs.tail, p) + else filter(xs.tail, p) + + def modN(n: Int)(x: Int) = ((x % n) == 0) + + val nums = List(1, 2, 3, 4, 5, 6, 7, 8) + println(filter(nums, modN(2))) + println(filter(nums, modN(3))) +} +``` + +_Nota: o método `modN` é parcialmente aplicado em duas chamadas de `filter`; por exemplo: somente o primeiro argumento é realmente aplicado. O termo `modN(2)` retorna uma função do tipo `Int => Boolean` e esta se torna uma possível candidata a segundo argumento da função `filter`._ + +A saída do programa acima produz: + +``` +List(2,4,6,8) +List(3,6) +``` From 8716410d8b8aba21c113efa0adcc50d0ec097fe2 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sat, 7 Jan 2017 11:12:25 -0200 Subject: [PATCH 10/34] Tutorials - Translation PT-BR - Case Classes --- pt-br/tutorials/tour/case-classes.md | 141 ++++++++++++++++++++++++++ pt-br/tutorials/tour/tour-of-scala.md | 4 +- 2 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 pt-br/tutorials/tour/case-classes.md diff --git a/pt-br/tutorials/tour/case-classes.md b/pt-br/tutorials/tour/case-classes.md new file mode 100644 index 0000000000..f7d371b6fd --- /dev/null +++ b/pt-br/tutorials/tour/case-classes.md @@ -0,0 +1,141 @@ +--- +layout: tutorial +title: Classes Case + +disqus: true + +tutorial: scala-tour +num: 10 +tutorial-next: pattern-matching +tutorial-previous: currying +language: pt-br +--- + +Scala suporta o conceito de _classes case_. Classes case são classes regulares que são: + +* Imutáveis por padrão +* Decompostas por meio de [correspondência de padrões](pattern-matching.html) +* Comparadas por igualdade estrututal ao invés de referência +* Sucintas para instanciar e operar + +Aqui um exemplo para hierarquia de tipos de notificação que consiste em uma super classe abstrata `Notification` e três tipos concretos de notificação implementados com classes case `Email`, `SMS`, e `VoiceRecording`. + +```tut +abstract class Notification +case class Email(sourceEmail: String, title: String, body: String) extends Notification +case class SMS(sourceNumber: String, message: String) extends Notification +case class VoiceRecording(contactName: String, link: String) extends Notification +``` + +Instânciar uma classe case é fácil: (Perceba que nós não precisamos da palavra-chave `new`) + +```tut +val emailDeJohn = Email("john.doe@mail.com", "Saudações do John!", "Olá Mundo") +``` + +Os parâmetros do construtor de uma classe case são tratados como valores públicos e podem ser acessados diretamente. + +```tut +val titulo = emailDeJohn.title +println(titulo) // prints "Saudações do John!" +``` + +Com classes case, você não pode alterar seus campos diretamente. (ao menos que você declare `var` antes de um campo, mas fazê-lo geralmente é desencorajado). + +```tut:fail +emailDeJohn.title = "Adeus do John!" // Erro the compilação. Não podemos atribuir outro valor para um campo que foi declarado como val, lembrando que todos os campos de classes case são val por padrão. +``` + +Ao invés disso, faça uma cópia utilizando o método `copy`. Como descrito abaixo, então você poderá substituir alguns dos campos: + +```tut +val emailEditado = emailDeJohn.copy(title = "Estou aprendendo Scala!", body = "É muito legal!") + +println(emailDeJohn) // prints "Email(john.doe@mail.com,Saudações do John!,Hello World!)" +println(emailEditado) // prints "Email(john.doe@mail.com,Estou aprendendo Scala,É muito legal!)" +``` + +Para cada classe case em Scala o compilador gera um método `equals` que implementa a igualdade estrutural e um método `toString`. Por exemplo: + +```tut +val primeiroSMS = SMS("12345", "Hello!") +val segundoSMS = SMS("12345", "Hello!") + +if (primeiroSMS == segundoSMS) { + println("Somos iguais!") +} + +println("SMS é: " + primeiroSMS) +``` + +Irá gerar como saída: + +``` +Somos iguais! +SMS é: SMS(12345, Hello!) +``` + +Com classes case, você pode utilizar **correspondência de padrões** para manipular seus dados. Aqui um exemplo de uma função que escreve como saída diferente mensagens dependendo do tipo de notificação recebida: + +```tut +def mostrarNotificacao(notificacao: Notification): String = { + notificacao match { + case Email(email, title, _) => + "Você recebeu um email de " + email + " com o título: " + title + case SMS(number, message) => + "Você recebeu um SMS de" + number + "! Mensagem: " + message + case VoiceRecording(name, link) => + "Você recebeu uma Mensagem de Voz de " + name + "! Clique no link para ouvir: " + link + } +} + +val algumSMS = SMS("12345", "Você está aí?") +val algumaMsgVoz = VoiceRecording("Tom", "voicerecording.org/id/123") + +println(mostrarNotificacao(algumSMS)) +println(mostrarNotificacao(algumaMsgVoz)) + +// Saída: +// Você recebeu um SMS de 12345! Mensagem: Você está aí? +// Você recebeu uma Mensagem de Voz de Tom! Clique no link para ouvir: voicerecording.org/id/123 +``` + +Aqui um exemplo mais elaborado utilizando a proteção `if`. Com a proteção `if`, o correspondência de padrão irá falhar se a condição de proteção retorna falso. + +```tut +def mostrarNotificacaoEspecial(notificacao: Notification, emailEspecial: String, numeroEspecial: String): String = { + notificacao match { + case Email(email, _, _) if email == emailEspecial => + "Você recebeu um email de alguém especial!" + case SMS(numero, _) if numero == numeroEspecial => + "Você recebeu um SMS de alguém especial!" + case outro => + mostrarNotificacao(outro) // Nada especial para mostrar, então delega para nossa função original mostrarNotificacao + } +} + +val NUMERO_ESPECIAL = "55555" +val EMAIL_ESPECIAL = "jane@mail.com" +val algumSMS = SMS("12345", "Você está aí?") +val algumaMsgVoz = VoiceRecording("Tom", "voicerecording.org/id/123") +val emailEspecial = Email("jane@mail.com", "Beber hoje a noite?", "Estou livre depois das 5!") +val smsEspecial = SMS("55555", "Estou aqui! Onde está você?") + +println(mostrarNotificacaoEspecial(algumSMS, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) +println(mostrarNotificacaoEspecial(algumaMsgVoz, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) +println(mostrarNotificacaoEspecial(smsEspecial, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) +println(mostrarNotificacaoEspecial(smsEspecial, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) + +// Saída: +// Você recebeu um SMS de 12345! Mensagem: Você está aí? +// Você recebeu uma Mensagem de Voz de Tom! Clique no link para ouvir: voicerecording.org/id/123 +// Você recebeu um email de alguém especial! +// Você recebeu um SMS de alguém especial! + +``` + +Ao programar em Scala, recomenda-se que você use classes case de forma pervasiva para modelar / agrupar dados, pois elas ajudam você a escrever código mais expressivo e passível de manutenção: + +* Imutabilidade libera você de precisar acompanhar onde e quando as coisas são mutadas +* Comparação por valor permite comparar instâncias como se fossem valores primitivos - não há mais incerteza sobre se as instâncias de uma classe é comparada por valor ou referência +* Correspondência de padrões simplifica a lógica de ramificação, o que leva a menos bugs e códigos mais legíveis. \ No newline at end of file diff --git a/pt-br/tutorials/tour/tour-of-scala.md b/pt-br/tutorials/tour/tour-of-scala.md index a3323ea079..4c07f1d11f 100644 --- a/pt-br/tutorials/tour/tour-of-scala.md +++ b/pt-br/tutorials/tour/tour-of-scala.md @@ -16,9 +16,9 @@ Scala é uma linguagem de programação moderna e multi-paradigma desenvolvida p Scala é uma linguagem puramente orientada a objetos no sentido que [todo valor é um objeto](unified-types.html). Tipos e comportamentos de objetos são descritos por [classes](classes.html) e [traits](traits.html). Classes são estendidas por subclasses e por um flexível mecanismo [de composição mesclada](mixin-class-composition.html) como uma alternativa para herança múltipla. ## Scala is functional ## -Scala é também uma linguagem funcional no sentido que [toda função é um valor](unified-types.html). Scala fornece uma [sintaxe leve](anonymous-function-syntax.html) para definir funções anônimas, suporta [funções de primeira ordem](higher-order-functions.html), permite funções [aninhadas](nested-functions.html), e suporta [currying](currying.html). As [case classes](case-classes.html) da linguagem Scala e o suporte embutido para [reconhecimento de padrões ou pattern matching](pattern-matching.html) modelam tipos algébricos utilizados em muitas linguagens de programação funcional. [Objetos únicos ou Singleton objects](singleton-objects.html) fornecem uma alternativa conveniente para agrupar funções que não são membros de uma classe. +Scala é também uma linguagem funcional no sentido que [toda função é um valor](unified-types.html). Scala fornece uma [sintaxe leve](anonymous-function-syntax.html) para definir funções anônimas, suporta [funções de primeira ordem](higher-order-functions.html), permite funções [aninhadas](nested-functions.html), e suporta [currying](currying.html). As [case classes](case-classes.html) da linguagem Scala e o suporte embutido para [correspondência de padrões](pattern-matching.html) modelam tipos algébricos utilizados em muitas linguagens de programação funcional. [Objetos únicos ou Singleton objects](singleton-objects.html) fornecem uma alternativa conveniente para agrupar funções que não são membros de uma classe. -Além disso, a noção de reconhecimento de padrões em scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [extrator de objetos](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. +Além disso, a noção de correspondência de padrões em scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [extrator de objetos](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. ## Scala é estaticamente tipada ## Scala é equipada com um expressivo sistema de tipos que reforça estaticamente que abstrações são utilizadas de uma forma segura e coerente. Particularmente, o sistema de tipos suporta: From ea910f6ba8950999be4dfff6849dd6e3c2828353 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sat, 7 Jan 2017 11:49:43 -0200 Subject: [PATCH 11/34] Tutorials - Translation PT-BR - Pattern Matching --- pt-br/tutorials/tour/pattern-matching.md | 49 ++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 pt-br/tutorials/tour/pattern-matching.md diff --git a/pt-br/tutorials/tour/pattern-matching.md b/pt-br/tutorials/tour/pattern-matching.md new file mode 100644 index 0000000000..680d86ff36 --- /dev/null +++ b/pt-br/tutorials/tour/pattern-matching.md @@ -0,0 +1,49 @@ +--- +layout: tutorial +title: Correspondência de Padrões + +disqus: true + +tutorial: scala-tour +num: 11 + +tutorial-next: singleton-objects +tutorial-previous: case-classes +language: pt-br +--- + +_Nota de tradução: A palavra cujo o significado melhor corresponde a palavra `match` em inglês seria `correspondência`. Também podemos entender que `match` é como "coincidir" ou "concordar" com algo._ + +Scala possui mecanismo de correspondência de padrão embutido. Isso permite realizar o match de qualquer tipo de dados any sort of data com a política de primeiro match. +Aqui um pequeno exemplo que mostrar como realizar o match de um número inteiro: + +```tut +object MatchTest1 extends App { + def matchTest(x: Int): String = x match { + case 1 => "um" + case 2 => "dois" + case _ => "muitos" + } + println(matchTest(3)) +} +``` + +O bloco com a declaração `case` define a função que mapeia inteiros para strings. A palavra-chave `match` fornece uma maneira conveniente de aplicar uma função (como a função de correspondência de padrões acima) em um objeto. + +Aqui um segundo exemplo no qual o match é realizado em valores de diferentes tipos: + +```tut +object MatchTest2 extends App { + def matchTest(x: Any): Any = x match { + case 1 => "um" + case "dois" => 2 + case y: Int => "scala.Int" + } + println(matchTest("dois")) +} +``` + +O primeiro `case` realiza o match se `x` refere-se a um valor inteiro `1`. O segundo `case` realiza o match se `x` é igual a string `"dois"`. O terceiro `case` é padrão tipado; realiza o match de qualquer valor que seja um inteiro e associa o valor do match de `x` a uma variável `y` do tipo `Int`. + +A correspondência de padrões de Scala é mais útil para realizar os matches de tipos algébricos expressados com [classes case](case-classes.html). +Scala também permite a definição de padrões independentemente de classes case, basta utilizar o método `unapply` em um [extrator de objetos](extractor-objects.html). From 11b3c8bececef5977e5cd3b85becad19931f3703 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sat, 7 Jan 2017 17:33:44 -0200 Subject: [PATCH 12/34] Tutorials - Translation PT-BR - Singleton Objects --- pt-br/tutorials/tour/classes.md | 2 +- pt-br/tutorials/tour/singleton-objects.md | 73 +++++++++++++++++++++++ pt-br/tutorials/tour/tour-of-scala.md | 2 +- pt-br/tutorials/tour/unified-types.md | 2 +- 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 pt-br/tutorials/tour/singleton-objects.md diff --git a/pt-br/tutorials/tour/classes.md b/pt-br/tutorials/tour/classes.md index cb108b4527..09c64e14cf 100644 --- a/pt-br/tutorials/tour/classes.md +++ b/pt-br/tutorials/tour/classes.md @@ -43,7 +43,7 @@ object Classes { } ``` -O programa define uma aplicação executável chamada Classes como um [objeto singular/único](singleton-objects) dentro do método `main`. O método `main` cria um novo `Ponto` e armazena o valor em `pt`. Perceba que valores definidos com o construtor `val` são diferentes das variáveis definidas com o construtor `var` (veja acima a classe `Ponto`), `val` não permite atualização do valor, ou seja, o valor é uma constante. +O programa define uma aplicação executável chamada Classes como um [Objeto Singleton](singleton-objects) dentro do método `main`. O método `main` cria um novo `Ponto` e armazena o valor em `pt`. Perceba que valores definidos com o construtor `val` são diferentes das variáveis definidas com o construtor `var` (veja acima a classe `Ponto`), `val` não permite atualização do valor, ou seja, o valor é uma constante. Aqui a saída do programa: diff --git a/pt-br/tutorials/tour/singleton-objects.md b/pt-br/tutorials/tour/singleton-objects.md new file mode 100644 index 0000000000..a83c2754c0 --- /dev/null +++ b/pt-br/tutorials/tour/singleton-objects.md @@ -0,0 +1,73 @@ +--- +layout: tutorial +title: Objetos Singleton + +disqus: true + +tutorial: scala-tour +num: 12 + +tutorial-next: xml-processing +tutorial-previous: pattern-matching +language: pt-br +--- + +Métodos e valores que não são associados com instâncias individuais de uma [classe](classes.html) são considerados *objetos singleton*, denotados através da palavra-chave `object` ao invés de `class`. + +``` +package test + +object Blah { + def sum(l: List[Int]): Int = l.sum +} +``` + +O método `sum` é disponível globalmente, e pode ser referenciado ou importado como `test.Blah.sum`. + +Objetos Singleton são um tipo de mescla e abreviação para definir uma classe de uso único, a qual não pode ser diretamente instanciada, e um membro `val` durante a definição do `object`. De fato, como `val`, objetos singleton podem ser definidos como membros de uma [trait](traits.html) ou [classe](classes.html), porém isso não é comum. + +Um objeto singleton pode estender classes e traits. Já uma [classe clase](case-classes.html) sem [parâmetros com tipo](generic-classes.html) por padrão irá criar um objeto singleton como o mesmo nome e com uma [`Função*`](http://www.scala-lang.org/api/current/scala/Function1.html) trait implementada. + +## Acompanhantes ## + +A maioria dos objetos singleton não estão sozinhos, mas sim associados com uma classe de mesmo nome. O “objeto singleton de mesmo nome” que uma classe case, acima mencionado, é um exemplo disso. Quando isso acontece, o objeto singleton é chamado de *objeto acompanhante* de uma classe e, a classe é chamada de *classe acompanhante* de um objeto. + +[Scaladoc](https://wiki.scala-lang.org/display/SW/Introduction) possui um um recurso espacial para navegar entre classes e seus acompanhantes: se o grande círculo contendo “C” ou “O” possui sua extremidade superior dobrada para baixo, você pode clicar no círculo para acessar o acompanhante. + +Se houver um objeto acompanhante para uma classe, ambos devem ser definidos no mesmo aquivo fonte. Por exemplo: + +```tut +class IntPair(val x: Int, val y: Int) + +object IntPair { + import math.Ordering + + implicit def ipord: Ordering[IntPair] = + Ordering.by(ip => (ip.x, ip.y)) +} +``` + +É comum ver instâncias de classes de tipo como [valores implicit](implicit-parameters.html), como `ipord` acima, definido no objeto acompanhante quando se segue o padrão da classe de tipo. Isso ocorre porque os membros do objeto acompanhante são incluídos por padrão na busca de valores implicitos. + +## Nota para programadores Java ## + +`static` não é uma palavra-chava em Scala. Ao invés disso, todos os membros que devem ser estáticos, incluindo classes, devem ser declarados no objeto singleton. Eles podem ser referenciados com a mesma sintaxe, They can be referred to with the same syntax, importados gradativamente ou como um grupo, e assim por diante. + +Frequentemente, os programadores Java definem membros estáticos, talvez `private`, como auxiliares de implementação para seus membros de instância. Estes são movidos para o acompanhante também; Um padrão comum é importar os membros do objeto acompanhante na classe, da seguinte forma: +``` +class X { + import X._ + + def blah = foo +} + +object X { + private def foo = 42 +} +``` + +Isso demonstra outra característica: no contexto `private`, as classes e seus acompanhantes são amigos. `object X` pode acessar membro privados da `class X`, e vice versa. Para fazer com que um membro seja *realmente* para um ou outro, utilize `private[this]`. + +Para conveniência Java, métodos, incluindo `var`s e `val`s, definidos diretamente em um objeto singleton também têm um método estático definido na classe acompanhante, chamado *encaminhadores estáticos*. Outros membros são acessíveis por meio de campos estáticos `X$.MODULE$` para o `object X`. + +Se você mover tudo para um objeto acompanhante e descobrir que tudo o que resta é uma classe que você não deseja que seja instanciada, exclua simplesmente a classe. Encaminhadores estáticos ainda serão criados. \ No newline at end of file diff --git a/pt-br/tutorials/tour/tour-of-scala.md b/pt-br/tutorials/tour/tour-of-scala.md index 4c07f1d11f..6ce00bc8c3 100644 --- a/pt-br/tutorials/tour/tour-of-scala.md +++ b/pt-br/tutorials/tour/tour-of-scala.md @@ -16,7 +16,7 @@ Scala é uma linguagem de programação moderna e multi-paradigma desenvolvida p Scala é uma linguagem puramente orientada a objetos no sentido que [todo valor é um objeto](unified-types.html). Tipos e comportamentos de objetos são descritos por [classes](classes.html) e [traits](traits.html). Classes são estendidas por subclasses e por um flexível mecanismo [de composição mesclada](mixin-class-composition.html) como uma alternativa para herança múltipla. ## Scala is functional ## -Scala é também uma linguagem funcional no sentido que [toda função é um valor](unified-types.html). Scala fornece uma [sintaxe leve](anonymous-function-syntax.html) para definir funções anônimas, suporta [funções de primeira ordem](higher-order-functions.html), permite funções [aninhadas](nested-functions.html), e suporta [currying](currying.html). As [case classes](case-classes.html) da linguagem Scala e o suporte embutido para [correspondência de padrões](pattern-matching.html) modelam tipos algébricos utilizados em muitas linguagens de programação funcional. [Objetos únicos ou Singleton objects](singleton-objects.html) fornecem uma alternativa conveniente para agrupar funções que não são membros de uma classe. +Scala é também uma linguagem funcional no sentido que [toda função é um valor](unified-types.html). Scala fornece uma [sintaxe leve](anonymous-function-syntax.html) para definir funções anônimas, suporta [funções de primeira ordem](higher-order-functions.html), permite funções [aninhadas](nested-functions.html), e suporta [currying](currying.html). As [case classes](case-classes.html) da linguagem Scala e o suporte embutido para [correspondência de padrões](pattern-matching.html) modelam tipos algébricos utilizados em muitas linguagens de programação funcional. [Objetos Singleton](singleton-objects.html) fornecem uma alternativa conveniente para agrupar funções que não são membros de uma classe. Além disso, a noção de correspondência de padrões em scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [extrator de objetos](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. diff --git a/pt-br/tutorials/tour/unified-types.md b/pt-br/tutorials/tour/unified-types.md index f4de23b09d..93af193e39 100644 --- a/pt-br/tutorials/tour/unified-types.md +++ b/pt-br/tutorials/tour/unified-types.md @@ -35,7 +35,7 @@ object TiposUnificados extends App { } ``` -O programa declare uma aplicação chamada `TiposUnificados` em forma de um [objeto singular/único](singleton-objects.html) que estende `App`. A aplicação define uma variável local `set` que se refere à uma instância da classe `LinkedHashSet[Any]`. As demais linhas adicionam vários elementos à variável set. Tais elementos devem estar em conformidade com o tipo `Any` que foi declarado para o set. Por fim, são escritas as representações em string de todos os elementos adicionados ao set. +O programa declare uma aplicação chamada `TiposUnificados` em forma de um [objeto Singleton](singleton-objects.html) que estende `App`. A aplicação define uma variável local `set` que se refere à uma instância da classe `LinkedHashSet[Any]`. As demais linhas adicionam vários elementos à variável set. Tais elementos devem estar em conformidade com o tipo `Any` que foi declarado para o set. Por fim, são escritas as representações em string de todos os elementos adicionados ao set. Escrita de saída do programa: From 3eda83df9dc7f735b04879afeef7cf184695f1a6 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sat, 7 Jan 2017 18:20:51 -0200 Subject: [PATCH 13/34] Tutorials - Translation PT-BR - XML Processing --- pt-br/tutorials/tour/xml-processing.md | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 pt-br/tutorials/tour/xml-processing.md diff --git a/pt-br/tutorials/tour/xml-processing.md b/pt-br/tutorials/tour/xml-processing.md new file mode 100644 index 0000000000..1a88553bcb --- /dev/null +++ b/pt-br/tutorials/tour/xml-processing.md @@ -0,0 +1,69 @@ +--- +layout: tutorial +title: Processando arquivos XML + +disqus: true + +tutorial: scala-tour +num: 13 +tutorial-next: regular-expression-patterns +tutorial-previous: singleton-objects +language: pt-br +--- + +Scala pode ser utilizado para facilmente criar, parsear e processar documentos XML. Os dados de um XML podem ser representados em Scala utilizando uma representação de dados genérica ou específica. A última abordagem é suportada através da ferramenta de *data-binding* `schema2src`. + +### Representação em Tempo de Execução ### +Um XML é representado como uma árvore de rótulos. A partir de Scala 1.2 (versões anteriores é necessário utilizar a opção -Xmarkupoption), você pode convenientemente criar esses nós rotulados usando a sintaxe XML padrão. + +Considere o seguinte documento XML: + +```html + + + Olá mundo XHTML + + +

Olá mundo

+

Scala fala XHTML

+ + +``` + +Tal documento pode ser criado através do seguinte código: + +```tut +object XMLTest1 extends App { + val pagina = + + + Olá mundo XHTML + + +

Olá mundo

+

Scala fala XHTML

+ + ; + println(pagina.toString()) +} +``` + +É também possível combinar expressões Scala e sintaxe XML: + +```tut +object XMLTest2 extends App { + import scala.xml._ + val df = java.text.DateFormat.getDateInstance() + val stringData = df.format(new java.util.Date()) + def data(nome: String) = + + Olá, { nome }! Hoje é { stringData } + ; + println(data("John Doe").toString()) +} +``` + +### Data Binding ### +Em muitos casos você tem um DTD para os documentos XMLs que você quer processar. Você poderá precisar criar classes especiais em Scala com código para parsear e salvar tais documentos. Para isso, Scala fornece uma ferramenta elegante que converte seus DTDs em coleções de definições de classes Scala, que fazem todo o trabalho para você. +A documentação e exemplos sobre a ferramenta `schema2src` podem ser encontrados no livro de Burak's [draft scala xml book](http://burak.emir.googlepages.com/scalaxbook.docbk.html). + From 3e5dc7c0535bce2216620edc6437ab77c23d8cdc Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sat, 7 Jan 2017 18:38:01 -0200 Subject: [PATCH 14/34] Tutorials - Translation PT-BR - Reg Exp Patterns --- .../tour/regular-expression-patterns.md | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 pt-br/tutorials/tour/regular-expression-patterns.md diff --git a/pt-br/tutorials/tour/regular-expression-patterns.md b/pt-br/tutorials/tour/regular-expression-patterns.md new file mode 100644 index 0000000000..6ad9e02700 --- /dev/null +++ b/pt-br/tutorials/tour/regular-expression-patterns.md @@ -0,0 +1,47 @@ +--- +layout: tutorial +title: Padrões de Expressões Regulares + +disqus: true + +tutorial: scala-tour +num: 14 + +tutorial-next: extractor-objects +tutorial-previous: xml-processing +language: pt-br +--- + +## Padrões de sequência que ignoram a direita ## + +Padrões de sequência que ignoram a direita são uma funcionalidade útil para decompor qualquer dado sendo ele um subtipo de `Seq[A]` ou uma classe case com um parâmetro iterador formal, como por exemplo: + +``` +Elem(prefix:String, label:String, attrs:MetaData, scp:NamespaceBinding, children:Node*) +``` +Em tais casos, Scala permite que padrões tenham o curinga `_*` na posição mais à direita para ter lugar para sequências arbitrariamente longas. +O exemplo a seguir demonstra um padrão que faz o match de um prefixo de uma sequência e vincula o resto à variável `rest`. + +```tut +object RegExpTest1 extends App { + def containsScala(x: String): Boolean = { + val z: Seq[Char] = x + z match { + case Seq('s','c','a','l','a', rest @ _*) => + println("rest is "+rest) + true + case Seq(_*) => + false + } + } +} +``` + +Em contraste com versões anteriores Scala, não é mais permitido ter expressões regulares arbitrárias, pelas razões descritas abaixo. + +###Padrões genéricos de expressões regulares `RegExp` temporariamente retirados de Scala### + +Desde que descobrimos um problema de precisão, esse recurso está temporariamente removido da linguagem Scala. Se houver solicitação da comunidade de usuários, poderemos reativá-la de forma aprimorada. + +De acordo com nossa opinião, os padrões de expressões regulares não eram tão úteis para o processamento XML como estimamos. Em aplicações de processamento de XML de vida real, XPath parece uma opção muito melhor. Quando descobrimos que nossos padrões de expressões regulares ou de tradução tinham alguns bugs para padrões raros que são incomuns e difíceis de excluir, escolhemos que seria hora de simplificar a linguagem. + From 9d293d3f149a0f82bb4ebab1dffe9f0817734089 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 13:09:10 -0200 Subject: [PATCH 15/34] Tutorials - Translation PT-BR - Extractor Objects --- pt-br/tutorials/tour/extractor-objects.md | 42 +++++++++++++++++++++++ pt-br/tutorials/tour/pattern-matching.md | 2 +- pt-br/tutorials/tour/tour-of-scala.md | 2 +- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 pt-br/tutorials/tour/extractor-objects.md diff --git a/pt-br/tutorials/tour/extractor-objects.md b/pt-br/tutorials/tour/extractor-objects.md new file mode 100644 index 0000000000..1690d96d79 --- /dev/null +++ b/pt-br/tutorials/tour/extractor-objects.md @@ -0,0 +1,42 @@ +--- +layout: tutorial +title: Objetos Extratores + +disqus: true + +tutorial: scala-tour +num: 15 +tutorial-next: sequence-comprehensions +tutorial-previous: regular-expression-patterns +language: pt-br +--- + +Em Scala, padrões podem ser definidos independentemente de classes case. Para este fim, um método chamado `unapply` é definido para retorna o extrator. Um extrator pode ser pensado como um método especial que inverte o efeito da aplicação de um determinado objeto em algumas entradas. Seu objetivo é "extrair" as entradas que estavam presentes antes da operação `apply`. Por exemplo, o código a seguir define um [objeto] (singleton-objects.html) extrator chamado Twice. + +```tut +object Twice { + def apply(x: Int): Int = x * 2 + def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None +} + +object TwiceTest extends App { + val x = Twice(21) + x match { case Twice(n) => Console.println(n) } // prints 21 +} +``` + +Existem duas convenções sintáticas em ação aqui: + +O padrão `case Twice (n)` causa a invocação do método `Twice.unapply`, que é usado para fazer o match de qualquer número par; O valor de retorno de `unapply` indica se houve match ou não, e quaisquer sub-valores que possam ser utilizados para um seguinte match. Aqui, o sub-valor é `z/2`. + +O método `apply` não é necessário na correspondência de padrões. É utilizado somente para simular um construtor. `val x = Twice(21)` é expandido para `val x = Twice.apply(21)`. + +O tipo de retorno de uma chamada `unapply` deveria ser escolhido da seguinta forma: + +* Se é somente um teste, retorne `Boolean`. Por exemplo `case even()` +* Se retorna um único sub valor to tipo `T`, retorne `Option[T]` +* Se você quer retornar vários sub valores `T1,...,Tn`, agrupe todos em uma tupla opcional como `Option[(T1,...,Tn)]`. + +Algumas vezes, o número de sub valores é fixo e você precisa retornar uma sequência. Para isso, você pode definir padrões através da chamada `unapplySeq`. O último sub valor do tipo `Tn` precisa ser `Seq[S]`. Tal mecanismo é utilizado como exemplo no padrão `case List(x1, ..., xn)`. + +Extratores podem tornar o código mais fácil de manter. Para mais detalhes, leia o artigo ["Matching Objects with Patterns"](https://infoscience.epfl.ch/record/98468/files/MatchingObjectsWithPatterns-TR.pdf) (veja a seção 4) by Emir, Odersky and Williams (January 2007). diff --git a/pt-br/tutorials/tour/pattern-matching.md b/pt-br/tutorials/tour/pattern-matching.md index 680d86ff36..e0898bd23f 100644 --- a/pt-br/tutorials/tour/pattern-matching.md +++ b/pt-br/tutorials/tour/pattern-matching.md @@ -46,4 +46,4 @@ object MatchTest2 extends App { O primeiro `case` realiza o match se `x` refere-se a um valor inteiro `1`. O segundo `case` realiza o match se `x` é igual a string `"dois"`. O terceiro `case` é padrão tipado; realiza o match de qualquer valor que seja um inteiro e associa o valor do match de `x` a uma variável `y` do tipo `Int`. A correspondência de padrões de Scala é mais útil para realizar os matches de tipos algébricos expressados com [classes case](case-classes.html). -Scala também permite a definição de padrões independentemente de classes case, basta utilizar o método `unapply` em um [extrator de objetos](extractor-objects.html). +Scala também permite a definição de padrões independentemente de classes case, basta utilizar o método `unapply` em um [objeto extrator](extractor-objects.html). diff --git a/pt-br/tutorials/tour/tour-of-scala.md b/pt-br/tutorials/tour/tour-of-scala.md index 6ce00bc8c3..125628c459 100644 --- a/pt-br/tutorials/tour/tour-of-scala.md +++ b/pt-br/tutorials/tour/tour-of-scala.md @@ -18,7 +18,7 @@ Scala é uma linguagem puramente orientada a objetos no sentido que [todo valor ## Scala is functional ## Scala é também uma linguagem funcional no sentido que [toda função é um valor](unified-types.html). Scala fornece uma [sintaxe leve](anonymous-function-syntax.html) para definir funções anônimas, suporta [funções de primeira ordem](higher-order-functions.html), permite funções [aninhadas](nested-functions.html), e suporta [currying](currying.html). As [case classes](case-classes.html) da linguagem Scala e o suporte embutido para [correspondência de padrões](pattern-matching.html) modelam tipos algébricos utilizados em muitas linguagens de programação funcional. [Objetos Singleton](singleton-objects.html) fornecem uma alternativa conveniente para agrupar funções que não são membros de uma classe. -Além disso, a noção de correspondência de padrões em scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [extrator de objetos](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. +Além disso, a noção de correspondência de padrões em scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [objetos extratores](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. ## Scala é estaticamente tipada ## Scala é equipada com um expressivo sistema de tipos que reforça estaticamente que abstrações são utilizadas de uma forma segura e coerente. Particularmente, o sistema de tipos suporta: From e65353af2f7587873b59e8d3cac3b0c2d42ed3b2 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 13:37:08 -0200 Subject: [PATCH 16/34] Tutorials - Translation PT-BR - Sequence Comprehensions --- .../tutorials/tour/sequence-comprehensions.md | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 pt-br/tutorials/tour/sequence-comprehensions.md diff --git a/pt-br/tutorials/tour/sequence-comprehensions.md b/pt-br/tutorials/tour/sequence-comprehensions.md new file mode 100644 index 0000000000..77250e01ad --- /dev/null +++ b/pt-br/tutorials/tour/sequence-comprehensions.md @@ -0,0 +1,69 @@ +--- +layout: tutorial +title: Sequence Comprehensions + +disqus: true + +tutorial: scala-tour +num: 16 +tutorial-next: generic-classes +tutorial-previous: extractor-objects +language: pt-br +--- + +Scala oferece uma notação simples para expressar *compreensões de sequência*. As compreensões têm a forma `for (enumerators) yield e`, onde` enumerators` se refere a uma lista de enumeradores separados por ponto-e-vírgula. Um *enumerator* é um gerador que introduz novas variáveis ou é um filtro. A compreensão avalia o corpo `e` para cada associação gerada pelos enumeradores e retorna uma sequência desses valores. + +Por exemplo: + +```tut +object ComprehensionTest1 extends App { + def par(de: Int, ate: Int): List[Int] = + for (i <- List.range(de, ate) if i % 2 == 0) yield i + Console.println(par(0, 20)) +} +``` + +A função for-expression in introduz uma nova variável `i` do tipo `Int`, que é subsequentemente associada a todos os valores da lista `List (de, de + 1, ..., ate - 1)`. A restrição `if i% 2 == 0` ignora todos os números ímpares para que o corpo (que só consiste na expressão i) seja avaliado somente para números pares. Consequentemente, toda a expressão `for` retorna uma lista de números pares. + +O programa produz a seguinte saída: + +``` +List(0, 2, 4, 6, 8, 10, 12, 14, 16, 18) +``` + +Agora um exemplo mais complicado que calcula todos os pares de números entre `0` e` n-1` cuja soma é igual a um dado valor `v`: + +```tut +object ComprehensionTest2 extends App { + def foo(n: Int, v: Int) = + for (i <- 0 until n; + j <- i until n if i + j == v) yield + (i, j); + foo(20, 32) foreach { + case (i, j) => + println(s"($i, $j)") + } +} +``` + +Este exemplo mostra que as compreensões não estão restritas às listas. Pois o programa anterior usa iteradores. Todo tipo de dados que suporta as operações `filterWith`, `map`, e `flatMap` (com os tipos apropriados) pode ser usado em compreensões de sequência. + +Aqui está a saída do programa: + +``` +(13, 19) +(14, 18) +(15, 17) +(16, 16) +``` + +Há também uma forma especial de compreensão de sequência que retorna `Unit`. Aqui as associações que são criadas a partir da lista de geradores e filtros são utilizadas para gerar efeitos colaterais. O programador precisa omitir a palavra-chave `yield` para fazer uso de tal compreensão de sequência. +Aqui está um programa que é equivalente ao anterior, mas usa uma forma especial de for-expression que retorna `Unit`: + +``` +object ComprehensionTest3 extends App { + for (i <- Iterator.range(0, 20); + j <- Iterator.range(i, 20) if i + j == 32) + println(s"($i, $j)") +} +``` From fc3ab24e6e90fb0f0db94216334d38bfedfa877c Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 15:51:24 -0200 Subject: [PATCH 17/34] Tutorials - Translation PT-BR - Generic Classes --- pt-br/tutorials/tour/generic-classes.md | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 pt-br/tutorials/tour/generic-classes.md diff --git a/pt-br/tutorials/tour/generic-classes.md b/pt-br/tutorials/tour/generic-classes.md new file mode 100644 index 0000000000..d75bd75071 --- /dev/null +++ b/pt-br/tutorials/tour/generic-classes.md @@ -0,0 +1,47 @@ +--- +layout: tutorial +title: Classes Genéricas + +disqus: true + +tutorial: scala-tour +num: 17 +tutorial-next: variances +tutorial-previous: sequence-comprehensions +language: pt-br +--- + +Semelhante ao Java 5 (aka. [JDK 1.5](http://java.sun.com/j2se/1.5/)), Scala tem suporte nativo para classes parametrizadas com tipos. Essas classes genéricas são particularmente úteis para o desenvolvimento de classes collection. +Aqui um exemplo que demonstra isso: + +```tut +class Stack[T] { + var elems: List[T] = Nil + def push(x: T) { elems = x :: elems } + def top: T = elems.head + def pop() { elems = elems.tail } +} +``` + +A classe `Stack` modela uma pila mutável que contém elementos de um tipo arbitrário `T`. Os parâmetros de tipo garantem que somente os elementos legais (que são do tipo `T`) são inseridos na pilha. Da mesma forma, com os parâmetros de tipo podemos expressar que o método `top` retorna somente elementos de um único tipo de dado, no caso, `T`. + +Aqui mais alguns exemplo de uso: + +```tut +object GenericsTest extends App { + val stack = new Stack[Int] + stack.push(1) + stack.push('a') + println(stack.top) + stack.pop() + println(stack.top) +} +``` + +O saída do programa é: + +``` +97 +1 +``` +_Nota: subtipos de tipos genéricos são *invariantes*. Isto significa que se tivermos uma pilha de caracteres do tipo `Stack [Char]` então não pode ser usado como uma pilha de inteiros do tipo `Stack [Int]`. Isso seria incorreto porque ele nos permitiria inserir inteiros verdadeiros na pilha de caracteres. Para concluir, `Stack [T]` é um subtipo de de `Stack [S]` se e somente se `S = T`. Como isso pode ser bastante restritivo, Scala oferece um [mecanismo de anotação de parâmetro de tipo](variances.html) para controlar o comportamento de subtipo de tipos genéricos._ \ No newline at end of file From 3ecc555b30b5b8cbf2319b69b5c143ff8ad97875 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 16:43:05 -0200 Subject: [PATCH 18/34] Tutorials - Translation PT-BR - Variances --- pt-br/tutorials/tour/variances.md | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 pt-br/tutorials/tour/variances.md diff --git a/pt-br/tutorials/tour/variances.md b/pt-br/tutorials/tour/variances.md new file mode 100644 index 0000000000..c8cd8c7c45 --- /dev/null +++ b/pt-br/tutorials/tour/variances.md @@ -0,0 +1,41 @@ +--- +layout: tutorial +title: Variâncias + +disqus: true + +tutorial: scala-tour +num: 18 +tutorial-next: upper-type-bounds +tutorial-previous: generic-classes +language: pt-br +--- + +Scala suporta anotações de variância de parâmetros de tipo de [classes genéricas](generic-classes.html). Em contraste com o Java 5, as anotações de variância podem ser adicionadas quando uma abstração de classe é definida, enquanto que em Java 5, as anotações de variância são fornecidas por clientes quando uma abstração de classe é usada. + +Na página sobre [classes genéricas](generic-classes.html) foi dado um exemplo de uma pilha de estado mutável. Explicamos que o tipo definido pela classe `Stack [T]` está sujeito a subtipos invariantes em relação ao parâmetro de tipo. Isso pode restringir a reutilização da abstração de classe. Derivamos agora uma implementação funcional (isto é, imutável) para pilhas que não tem esta restrição. Por favor, note que este é um exemplo avançado que combina o uso de [métodos polimórficos](polymorphic-methods.html), [limites de tipo inferiores](lower-type-bounds.html) e anotações de parâmetros de tipos covariantes em um estilo não trivial. Além disso, fazemos uso de [classes internas](inner-classes.html) para encadear os elementos da pilha sem links explícitos. + +```tut +class Stack[+A] { + def push[B >: A](elem: B): Stack[B] = new Stack[B] { + override def top: B = elem + override def pop: Stack[B] = Stack.this + override def toString() = elem.toString() + " " + + Stack.this.toString() + } + def top: A = sys.error("no element on stack") + def pop: Stack[A] = sys.error("no element on stack") + override def toString() = "" +} + +object VariancesTest extends App { + var s: Stack[Any] = new Stack().push("hello"); + s = s.push(new Object()) + s = s.push(7) + println(s) +} +``` + +A anotação `+T` declara o tipo `T` para ser usado somente em posições covariantes. Da mesma forma, `-T` declararia que `T` pode ser usado somente em posições contravariantes. Para os parâmetros de tipo covariante obtemos uma relação de sub-tipo covariante em relação ao parâmetro de tipo. Em nosso exemplo, isso significa que `Stack [T]` é um subtipo de `Stack [S]` se `T` for um subtipo de `S`. O oposto é válido para parâmetros de tipo que são marcados com um `-`. + +No exemplo da pilha teríamos que usar o parâmetro de tipo covariante `T` em uma posição contravariante para podermos definir o método `push`. Uma vez que queremos sub-tipagem covariante para pilhas, usamos um truque e abstraímos o tipo de parâmetro do método `push`. Então temos um método polimórfico no qual usamos o tipo de elemento `T` como um limite inferior da variável de tipo da função `push`. Isso faz com que a variância de `T` fique em acordo com sua declaração, como um parâmetro de tipo covariante. Agora as pilhas são covariantes, mas a nossa solução permite que, por exemplo, seja possível inserir uma string em uma pilha de inteiros. O resultado será uma pilha do tipo `Stack [Any]`; Assim detectamos o error somente se o resultado for usado em um contexto onde esperamos uma pilha de números inteiros. Caso contrário, nós apenas criamos uma pilha com um tipo de elemento mais abrangente. \ No newline at end of file From edbdc9b5728c380111491206e8b330210fbb492d Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 16:56:13 -0200 Subject: [PATCH 19/34] Tutorials - Translation PT-BR - Upper Types Bounds --- pt-br/tutorials/tour/upper-type-bounds.md | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 pt-br/tutorials/tour/upper-type-bounds.md diff --git a/pt-br/tutorials/tour/upper-type-bounds.md b/pt-br/tutorials/tour/upper-type-bounds.md new file mode 100644 index 0000000000..f8b5deda11 --- /dev/null +++ b/pt-br/tutorials/tour/upper-type-bounds.md @@ -0,0 +1,50 @@ +--- +layout: tutorial +title: Limitante Superior de Tipos + +disqus: true + +tutorial: scala-tour +num: 19 +tutorial-next: lower-type-bounds +tutorial-previous: variances +language: pt-br +--- + +Em scala, [parâmetros de tipos](generic-classes.html) e [tipos abstratos](abstract-types.html) podem ser restringidos por um limitante de tipo. Tal limitante de tipo limita os valores concretos de uma variável de tipo e possivelmente revela mais informações sobre os membros de determinados tipos. Um _limitante superiror de tipos_ `T <: A` declare que a variável tipo `T` refere-se a um subtipo do tipo `A`. +Aqui um exemplo que demonstra um limitante superior de tipo para um parâmetro de tipo da classe `Cage`: + +```tut +abstract class Animal { + def name: String +} + +abstract class Pet extends Animal {} + +class Gato extends Pet { + override def name: String = "Gato" +} + +class Cachorro extends Pet { + override def name: String = "Cachorro" +} + +class Leao extends Animal { + override def name: String = "Leao" +} + +class Jaula[P <: Pet](p: P) { + def pet: P = p +} + +object Main extends App { + var jaulaCachorro = new Jaula[Cachorro](new Cachorro) + var jaulaGato = new Jaula[Gato](new Gato) + /* Não é possível colocar Leao em Jaula pois Leao não estende Pet. */ +// var jaulaLeao = new Jaula[Leao](new Leao) +} +``` + +Um instância da classe `Jaula` pode conter um animal, porém com um limite superior do tipo `Pet`. Um animal to tipo `Leao` não é um pet, pois não estende `Pet`, então não pode ser colocado em uma Jaula. + +O uso de limitantes inferiores de tipo é discutido [aqui](lower-type-bounds.html). From c5fd8fe0a6d9dad5dcc770a463d8d469e88c8141 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 17:30:50 -0200 Subject: [PATCH 20/34] Tutorials - Translation PT-BR - Lower Type Bounds --- pt-br/tutorials/tour/lower-type-bounds.md | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 pt-br/tutorials/tour/lower-type-bounds.md diff --git a/pt-br/tutorials/tour/lower-type-bounds.md b/pt-br/tutorials/tour/lower-type-bounds.md new file mode 100644 index 0000000000..4ac7a9bbb2 --- /dev/null +++ b/pt-br/tutorials/tour/lower-type-bounds.md @@ -0,0 +1,58 @@ +--- +layout: tutorial +title: Limitante Inferior de Tipos + +disqus: true + +tutorial: scala-tour +num: 20 +tutorial-next: inner-classes +tutorial-previous: upper-type-bounds +language: pt-br +--- + +Enquanto o [limitante superior de tipos](upper-type-bounds.html) limita um tipo a um subtipo de outro tipo, O *limitante inferior de tipos* declara um tipo para ser supertipo de outro tipo. O termo `T>: A` expressa que o parâmetro de tipo `T` ou tipo abstracto `T` refere-se a um supertipo do tipo `A`. + +Aqui está um exemplo onde isso é útil: + +```tut +case class ListNode[T](h: T, t: ListNode[T]) { + def head: T = h + def tail: ListNode[T] = t + def prepend(elem: T): ListNode[T] = + ListNode(elem, this) +} +``` + +O programa acima implementa uma linked list com uma operação de pré-inserção. Infelizmente, esse tipo é invariante no parâmetro de tipo da classe `ListNode`; Ou seja, `ListNode [String]` não é um subtipo de `ListNode [Any]`. Com a ajuda de [anotações de variância](variances.html) podemos expressar tal semântica de subtipo: + +``` +case class ListNode[+T](h: T, t: ListNode[T]) { ... } +``` + +Infelizmente, este programa não compila, porque uma anotação de covariância só é possível se a variável de tipo é usada somente em posições covariantes. Como a variável de tipo `T` aparece como um parâmetro de tipo do método `prepend`, tal regra é violada. Porém com a ajuda de um *limitante inferior de tipo*, podemos implementar um método de pré-inserção onde `T` só aparece em posições covariantes. + +Aqui está o código correspondente: + +```tut +case class ListNode[+T](h: T, t: ListNode[T]) { + def head: T = h + def tail: ListNode[T] = t + def prepend[U >: T](elem: U): ListNode[U] = + ListNode(elem, this) +} +``` + +_Nota:_ o novo método `prepend` tem um tipo ligeiramente menos restritivo. Permite, por exemplo, inserir um objeto de um supertipo a uma lista existente. A lista resultante será uma lista deste supertipo. + +Aqui está o código que ilustra isso: + +```tut +object LowerBoundTest extends App { + val empty: ListNode[Null] = ListNode(null, null) + val strList: ListNode[String] = empty.prepend("hello") + .prepend("world") + val anyList: ListNode[Any] = strList.prepend(12345) +} +``` + From 107761ce9aac8b78c5a9a43f8f10d1b73dcb02c9 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 17:55:52 -0200 Subject: [PATCH 21/34] Tutorials - Translation PT-BR - Inner Classes --- pt-br/tutorials/tour/inner-classes.md | 97 +++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 pt-br/tutorials/tour/inner-classes.md diff --git a/pt-br/tutorials/tour/inner-classes.md b/pt-br/tutorials/tour/inner-classes.md new file mode 100644 index 0000000000..b29c7c41e7 --- /dev/null +++ b/pt-br/tutorials/tour/inner-classes.md @@ -0,0 +1,97 @@ +--- +layout: tutorial +title: Classes Internas + +disqus: true + +tutorial: scala-tour +num: 21 +tutorial-next: abstract-types +tutorial-previous: lower-type-bounds +language: pt-br +--- + +Em Scala é possível declarar classes que tenham outras classes como membros. Em constrate com a linguagenm Java, onde classes internas são membros da classe em que foram declaradas, em Scala as classes internas são ligadas ao objeto exterior. Para ilustrar essa diferença, rapidamente esboçamos a implementação de grafo como um tipo de dados: + +```tut +class Graph { + class Node { + var connectedNodes: List[Node] = Nil + def connectTo(node: Node) { + if (connectedNodes.find(node.equals).isEmpty) { + connectedNodes = node :: connectedNodes + } + } + } + var nodes: List[Node] = Nil + def newNode: Node = { + val res = new Node + nodes = res :: nodes + res + } +} +``` + +Em nosso programa, os grafos são representados por uma lista de nós. Os nós são objetos da classe interna `Node`. Cada nó tem uma lista de vizinhos, que são armazenados na lista `connectedNodes`. Agora podemos configurar um grafo com alguns nós e conectar os nós de forma incremental: + +```tut +object GraphTest extends App { + val g = new Graph + val n1 = g.newNode + val n2 = g.newNode + val n3 = g.newNode + n1.connectTo(n2) + n3.connectTo(n1) +} +``` + +Agora melhoramos o exemplo acima com tipos, para assim declarar explicitamente qual o tipo das várias entidades definidas: + +```tut +object GraphTest extends App { + val g: Graph = new Graph + val n1: g.Node = g.newNode + val n2: g.Node = g.newNode + val n3: g.Node = g.newNode + n1.connectTo(n2) + n3.connectTo(n1) +} +``` + +Este código mostra claramente que o tipo nó é prefixado com sua instância externa (em nosso exemplo é o objeto `g`). Se agora temos dois grafos, o sistema de tipos de Scala não nos permite misturar nós definidos dentro de um grafo com os nós de outro, já que os nós do outro grafo têm um tipo diferente. +Aqui está um programa inválido: + +```tut:fail +object IllegalGraphTest extends App { + val g: Graph = new Graph + val n1: g.Node = g.newNode + val n2: g.Node = g.newNode + n1.connectTo(n2) // legal + val h: Graph = new Graph + val n3: h.Node = h.newNode + n1.connectTo(n3) // illegal! +} +``` + +Observe que em Java a última linha no programa do exemplo anterior é válida. Para nós de ambos os grafos, o Java atribuiria o mesmo tipo `Graph.Node`; isto é, `Node` é prefixado com a classe `Graph`. Em Scala, esse tipo também pode ser expresso, e é escrito `Graph#Node`. Se quisermos ser capazes de conectar nós de diferentes grafos, temos que mudar a definição inicial da nossa implementação do grafo da seguinte maneira: + +```tut +class Graph { + class Node { + var connectedNodes: List[Graph#Node] = Nil + def connectTo(node: Graph#Node) { + if (connectedNodes.find(node.equals).isEmpty) { + connectedNodes = node :: connectedNodes + } + } + } + var nodes: List[Node] = Nil + def newNode: Node = { + val res = new Node + nodes = res :: nodes + res + } +} +``` + +> Note que este programa não nos permite anexar um nó a dois grafos diferentes. Se quisermos também remover esta restrição, temos de mudar o tipo da variável `nodes` para `Graph#Node`. From 498ce3b9f5c01901944e96c534584c58792f39c8 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 18:40:41 -0200 Subject: [PATCH 22/34] Tutorials - Translation PT-BR - Abstract Types --- pt-br/tutorials/tour/abstract-types.md | 79 ++++++++++++++++++++++++++ pt-br/tutorials/tour/variances.md | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 pt-br/tutorials/tour/abstract-types.md diff --git a/pt-br/tutorials/tour/abstract-types.md b/pt-br/tutorials/tour/abstract-types.md new file mode 100644 index 0000000000..c2adfab8fe --- /dev/null +++ b/pt-br/tutorials/tour/abstract-types.md @@ -0,0 +1,79 @@ +--- +layout: tutorial +title: Tipos Abstratos + +disqus: true + +tutorial: scala-tour +num: 22 +tutorial-next: compound-types +tutorial-previous: inner-classes +language: pt-br +--- + +Em Scala, as classes são parametrizadas com valores (parâmetros de construtor) e com tipos (se [classes genéricas](generic-classes.html)). Por razões de regularidade, só não é possível ter valores como membros de um objeto; tipos juntamente com valores são membros de objetos. Além disso, ambas as formas de membros podem ser concretas e abstratas. + +Aqui está um exemplo que define uma definição de valor diferido e uma definição de tipo abstrato como membros de uma [trait](traits.html) chamada `Buffer`. + +```tut +trait Buffer { + type T + val element: T +} +``` + +*Tipos Abstratos* são tipos cuja identidade não é precisamente conhecida. No exemplo acima, só sabemos que cada objeto da classe `Buffer` tem um membro de tipo `T`, mas a definição de classe `Buffer` não revela para qual tipo concreto o membro do tipo `T` corresponde. Como definições de valores, podemos sobrescrever definições de tipos em subclasses. Isso nos permite revelar mais informações sobre um tipo abstrato ao limitar o tipo associado (o qual descreve as possíveis instâncias concretas do tipo abstrato). + +No seguinte programa temos uma classe `SeqBuffer` que nos permite armazenar apenas as sequências no buffer ao definir que o tipo `-T` precisa ser um subtipo de `Seq[U]` para um novo tipo abstrato `U`: + +```tut +abstract class SeqBuffer extends Buffer { + type U + type T <: Seq[U] + def length = element.length +} +``` + +[Traits](traits.html) ou [classes](classes.html) com membros de tipo abstratos são frequentemente utilizadas em combinação com instâncias de classe anônimas. Para ilustrar isso, agora analisamos um programa que lida com um buffer de sequência que se refere a uma lista de inteiros: + +```tut +abstract class IntSeqBuffer extends SeqBuffer { + type U = Int +} + +object AbstractTypeTest1 extends App { + def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer = + new IntSeqBuffer { + type T = List[U] + val element = List(elem1, elem2) + } + val buf = newIntSeqBuf(7, 8) + println("length = " + buf.length) + println("content = " + buf.element) +} +``` + +O tipo de retorno do método `newIntSeqBuf` refere-se a uma especialização da trait `Buffer` no qual o tipo `U` é agora equivalente a `Int`. Declaramos um tipo alias semelhante ao que temos na instanciação da classe anônima dentro do corpo do método `newIntSeqBuf`. Criamos uma nova instância de `IntSeqBuffer` na qual o tipo `T` refere-se a `List [Int]`. + +Observe que muitas vezes é possível transformar os membros de tipo abstrato em parâmetros de tipo de classes e vice-versa. Aqui está uma versão do código acima que usa apenas parâmetros de tipo: + +```tut +abstract class Buffer[+T] { + val element: T +} +abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] { + def length = element.length +} +object AbstractTypeTest2 extends App { + def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] = + new SeqBuffer[Int, List[Int]] { + val element = List(e1, e2) + } + val buf = newIntSeqBuf(7, 8) + println("length = " + buf.length) + println("content = " + buf.element) +} +``` + +Note que temos que usar [anotação de variância](variances.html) aqui; Caso contrário, não seríamos capazes de ocultar o tipo implementado pela sequência concreta do objeto retornado por `newIntSeqBuf`. Além disso, há casos em que não é possível substituir tipos abstratos com parâmetros de tipo. + diff --git a/pt-br/tutorials/tour/variances.md b/pt-br/tutorials/tour/variances.md index c8cd8c7c45..d311ddb3f5 100644 --- a/pt-br/tutorials/tour/variances.md +++ b/pt-br/tutorials/tour/variances.md @@ -36,6 +36,6 @@ object VariancesTest extends App { } ``` -A anotação `+T` declara o tipo `T` para ser usado somente em posições covariantes. Da mesma forma, `-T` declararia que `T` pode ser usado somente em posições contravariantes. Para os parâmetros de tipo covariante obtemos uma relação de sub-tipo covariante em relação ao parâmetro de tipo. Em nosso exemplo, isso significa que `Stack [T]` é um subtipo de `Stack [S]` se `T` for um subtipo de `S`. O oposto é válido para parâmetros de tipo que são marcados com um `-`. +A anotação `+T` declara o tipo `T` para ser usado somente em posições covariantes. Da mesma forma, `-T` declara que `T` pode ser usado somente em posições contravariantes. Para os parâmetros de tipo covariante obtemos uma relação de sub-tipo covariante em relação ao parâmetro de tipo. Em nosso exemplo, isso significa que `Stack [T]` é um subtipo de `Stack [S]` se `T` for um subtipo de `S`. O oposto é válido para parâmetros de tipo que são marcados com um `-`. No exemplo da pilha teríamos que usar o parâmetro de tipo covariante `T` em uma posição contravariante para podermos definir o método `push`. Uma vez que queremos sub-tipagem covariante para pilhas, usamos um truque e abstraímos o tipo de parâmetro do método `push`. Então temos um método polimórfico no qual usamos o tipo de elemento `T` como um limite inferior da variável de tipo da função `push`. Isso faz com que a variância de `T` fique em acordo com sua declaração, como um parâmetro de tipo covariante. Agora as pilhas são covariantes, mas a nossa solução permite que, por exemplo, seja possível inserir uma string em uma pilha de inteiros. O resultado será uma pilha do tipo `Stack [Any]`; Assim detectamos o error somente se o resultado for usado em um contexto onde esperamos uma pilha de números inteiros. Caso contrário, nós apenas criamos uma pilha com um tipo de elemento mais abrangente. \ No newline at end of file From 8b647a8e5752d8cb428c06472b146f553c3a3063 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 18:51:54 -0200 Subject: [PATCH 23/34] Tutorials - Translation PT-BR - Compound Types --- pt-br/tutorials/tour/compound-types.md | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 pt-br/tutorials/tour/compound-types.md diff --git a/pt-br/tutorials/tour/compound-types.md b/pt-br/tutorials/tour/compound-types.md new file mode 100644 index 0000000000..03e7d5baf4 --- /dev/null +++ b/pt-br/tutorials/tour/compound-types.md @@ -0,0 +1,53 @@ +--- +layout: tutorial +title: Tipos Compostos + +disqus: true + +tutorial: scala-tour +num: 23 +tutorial-next: explicitly-typed-self-references +tutorial-previous: abstract-types +language: pt-br +--- + +Às vezes é necessário expressar que o tipo de um objeto é um subtipo de vários outros tipos. Em Scala isso pode ser expresso com a ajuda de *tipos compostos*, que são interseções de tipos de objetos. + +Suponha que temos duas traits `Cloneable` and `Resetable`: + +```tut +trait Cloneable extends java.lang.Cloneable { + override def clone(): Cloneable = { + super.clone().asInstanceOf[Cloneable] + } +} +trait Resetable { + def reset: Unit +} +``` + +Agora supondo que queremos escrever uma função `cloneAndReset` que recebe um objeto, clona e reseta o objeto original: + +``` +def cloneAndReset(obj: ?): Cloneable = { + val cloned = obj.clone() + obj.reset + cloned +} +``` + +A questão é: qual é o tipo do parâmetro `obj`? Se for `Cloneable` então o objeto pode ser clonado, mas não resetado; Se for `Resetable` nós podemos resetar, mas não há nenhuma operação para clonar. Para evitar conversão de tipos em tal situação, podemos especificar o tipo de `obj` para ser tanto `Cloneable` como `Resetable`. Este tipo composto pode ser escrito da seguinte forma em Scala: `Cloneable with Resetable`. + +Aqui está a função atualizada: + +``` +def cloneAndReset(obj: Cloneable with Resetable): Cloneable = { + //... +} +``` + +Os tipos de compostos podem consistir em vários tipos de objeto e eles podem ter um único refinamento que pode ser usado para restrigird a assinatura de membros de objetos existentes. + +A forma geral é: `A com B com C ... { refinamento }` + +Um exemplo para o uso de refinamentos é dado na página sobre [tipos abstratos](abstract-types.html). From 092873552cd80b0bbaf2f1376227bc1a78acab4e Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 20:36:44 -0200 Subject: [PATCH 24/34] Tutorials - Translation PT-BR - Explicitly Typed Self Refs --- .../tour/explicitly-typed-self-references.md | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 pt-br/tutorials/tour/explicitly-typed-self-references.md diff --git a/pt-br/tutorials/tour/explicitly-typed-self-references.md b/pt-br/tutorials/tour/explicitly-typed-self-references.md new file mode 100644 index 0000000000..dd3623ca73 --- /dev/null +++ b/pt-br/tutorials/tour/explicitly-typed-self-references.md @@ -0,0 +1,122 @@ +--- +layout: tutorial +title: Auto Referências Explicitamente Tipadas + +disqus: true + +tutorial: scala-tour +num: 24 +tutorial-next: implicit-parameters +tutorial-previous: compound-types +language: pt-br +--- + +Ao desenvolver um software extensível, às vezes é útil declarar explicitamente o tipo do valor `this`. Para ilustrar isso, criaremos uma pequena representação extensível de uma estrutura de dados de grafo em Scala. + +Aqui está uma definição que descreve um grafo: + +```tut +abstract class Graph { + type Edge + type Node <: NodeIntf + abstract class NodeIntf { + def connectWith(node: Node): Edge + } + def nodes: List[Node] + def edges: List[Edge] + def addNode: Node +} +``` + +Um grafo consiste em uma lista de nós e arestas onde o nó e o tipo de aresta são declarados como abstratos. O uso de [tipos abstratos](abstract-types.html) permite que a implementação da trait `Graph` forneça suas próprias classes concretas para nós e arestas. Além disso, existe um método `addNode` para adicionar novos nós a um grafo. Os nós são conectados usando o método `connectWith`. + +Uma possível implementação de `Graph` é ilustrada na classe a seguir: + +```tut:fail +abstract class DirectedGraph extends Graph { + type Edge <: EdgeImpl + class EdgeImpl(origin: Node, dest: Node) { + def from = origin + def to = dest + } + class NodeImpl extends NodeIntf { + def connectWith(node: Node): Edge = { + val edge = newEdge(this, node) + edges = edge :: edges + edge + } + } + protected def newNode: Node + protected def newEdge(from: Node, to: Node): Edge + var nodes: List[Node] = Nil + var edges: List[Edge] = Nil + def addNode: Node = { + val node = newNode + nodes = node :: nodes + node + } +} +``` + +A classe `DirectedGraph` estende a classe `Graph` fornecendo uma implementação parcial. A implementação é apenas parcial porque gostaríamos de poder ampliar o `DirectedGraph`. Portanto, esta classe deixa todos os detalhes de implementação abertos e assim, tanto as arestas e os nós são definidos como abstrato. No entanto, a classe `DirectedGraph` revela alguns detalhes adicionais sobre a implementação do tipo das arestas ao restringir o limite de tipo para a classe `EdgeImpl`. Além disso, temos algumas implementações preliminares de arestas e nós representados pelas classes `EdgeImpl` e `NodeImpl`. Uma vez que é necessário criar novos objetos nó e aresta dentro da nossa implementação de grafo, também temos que adicionar os métodos de construção `newNode` e `newEdge`. Os métodos `addNode` e `connectWith` são ambos definidos em termos destes métodos de construção. Uma análise mais detalhada da implementação do método `connectWith` revela que, para criar uma aresta, temos que passar a auto-referência `this` para o método de construção `newEdge`. Mas a `this` é atribuído o tipo `NodeImpl`, por isso não é compatível com o tipo `Node` que é exigido pelo método de construção correspondente. Como consequência, o programa acima não é bem-formado e o compilador Scala irá emitir uma mensagem de erro. + +Em Scala é possível vincular uma classe a outro tipo (que será implementado no futuro) ao fornecer a auto referência `this` ao outro tipo explicitamente. Podemos usar esse mecanismo para corrigir nosso código acima. O tipo explícito de `this` é especificado dentro do corpo da classe `DirectedGraph`. + +Aqui está o programa já corrigido: + +```tut +abstract class DirectedGraph extends Graph { + type Edge <: EdgeImpl + class EdgeImpl(origin: Node, dest: Node) { + def from = origin + def to = dest + } + class NodeImpl extends NodeIntf { + self: Node => // nova linha adicionada + def connectWith(node: Node): Edge = { + val edge = newEdge(this, node) // agora válido + edges = edge :: edges + edge + } + } + protected def newNode: Node + protected def newEdge(from: Node, to: Node): Edge + var nodes: List[Node] = Nil + var edges: List[Edge] = Nil + def addNode: Node = { + val node = newNode + nodes = node :: nodes + node + } +} +``` + +Nesta nova definição de classe `NodeImpl`, `this` tem o tipo `Node`. Como o tipo `Node` é abstrato e, portanto, ainda não sabemos se `NodeImpl` é realmente um subtipo de `Node`, o sistema de tipo Scala não nos permitirá instanciar esta classe. Mas, no entanto, declaramos com a anotação de tipo explícito que, em algum ponto, (uma subclasse de) `NodeImpl` precisa denotar um subtipo de tipo `Node` para ser instantiável. + +Aqui está uma especialização concreta de `DirectedGraph` onde todos os membros da classe abstrata são definidos: + +```tut +class ConcreteDirectedGraph extends DirectedGraph { + type Edge = EdgeImpl + type Node = NodeImpl + protected def newNode: Node = new NodeImpl + protected def newEdge(f: Node, t: Node): Edge = + new EdgeImpl(f, t) +} +``` + +Observe que nesta classe, podemos instanciar `NodeImpl` porque agora sabemos que `NodeImpl` representa um subtipo de tipo `Node` (que é simplesmente um alias para `NodeImpl`). + +Aqui está um exemplo de uso da classe `ConcreteDirectedGraph`: + +```tut +object GraphTest extends App { + val g: Graph = new ConcreteDirectedGraph + val n1 = g.addNode + val n2 = g.addNode + val n3 = g.addNode + n1.connectWith(n2) + n2.connectWith(n3) + n1.connectWith(n3) +} +``` \ No newline at end of file From 0ce3cb83bf6d1d780fcf8015b667cb5b5ac176b1 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 21:35:31 -0200 Subject: [PATCH 25/34] Tutorials - Translation PT-BR - Implicit Parameters --- pt-br/tutorials/tour/implicit-parameters.md | 59 +++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 pt-br/tutorials/tour/implicit-parameters.md diff --git a/pt-br/tutorials/tour/implicit-parameters.md b/pt-br/tutorials/tour/implicit-parameters.md new file mode 100644 index 0000000000..45112f616b --- /dev/null +++ b/pt-br/tutorials/tour/implicit-parameters.md @@ -0,0 +1,59 @@ +--- +layout: tutorial +title: Parâmetros Implícitos + +disqus: true + +tutorial: scala-tour +num: 25 +tutorial-next: implicit-conversions +tutorial-previous: explicitly-typed-self-references +language: pt-br +--- + +Um método com _parâmetros implícitos_ pode ser aplicado a argumentos como um método normal. Neste caso, o rótulo implícito não tem efeito. No entanto, se esse método faltar argumentos para os parâmetros implícitos declarados, tais argumentos serão automaticamente fornecidos. + +Os argumentos reais que são elegíveis para serem passados para um parâmetro implícito se dividem em duas categorias: + +* Primeira, são elegíveis todos os identificadores x que podem ser acessados no ponto da chamada do método sem um prefixo e que denotam uma definição implícita ou um parâmetro implícito. + +* Segunda, são elegíveis também todos os membros dos módulos acompanhates do tipo do parâmetro implícito que são rotulados marcados como `implicit`. + +No exemplo a seguir, definimos um método `sum` que calcula a soma de uma lista de elementos usando as operações `add` e `unit` do monóide. Observe que valores implícitos não podem ser de nível superior, eles precisam ser membros de um modelo. + +```tut +/** Este exemplo usa uma estrutura da álgebra abstrata para mostrar como funcionam os parâmetros implícitos. Um semigrupo é uma estrutura algébrica em um conjunto A com uma operação (associativa), chamada add, que combina um par de A's e retorna um outro A. */ +abstract class SemiGroup[A] { + def add(x: A, y: A): A +} +/** Um monóide é um semigrupo com um elemento distinto de A, chamado unit, que quando combinado com qualquer outro elemento de A retorna esse outro elemento novamente. */ +abstract class Monoid[A] extends SemiGroup[A] { + def unit: A +} +object ImplicitTest extends App { + /** Para mostrar como os parâmetros implícitos funcionam, primeiro definimos os monóides para strings e inteiros. A palavra-chave implicit indica que o objeto correspondente pode ser usado implicitamente, dentro deste escopo, como um parâmetro de uma função definia como implícita. */ + implicit object StringMonoid extends Monoid[String] { + def add(x: String, y: String): String = x concat y + def unit: String = "" + } + implicit object IntMonoid extends Monoid[Int] { + def add(x: Int, y: Int): Int = x + y + def unit: Int = 0 + } + /** Este método recebe uma List[A] retorna um A que representa o valor da combinação resultante ao aplicar a operação monóide sucessivamente em toda a lista. Tornar o parâmetro m implícito aqui significa que só temos de fornecer o parâmetro xs no local de chamada, pois se temos uma List[A] sabemos qual é realmente o tipo A e, portanto, o qual o tipo do Monoid[A] é necessário. Podemos então encontrar implicitamente qualquer val ou objeto no escopo atual que também tem esse tipo e usá-lo sem precisar especificá-lo explicitamente. */ + def sum[A](xs: List[A])(implicit m: Monoid[A]): A = + if (xs.isEmpty) m.unit + else m.add(xs.head, sum(xs.tail)) + + /** Aqui chamamos a função sum duas vezes, com apenas um parâmetro cada vez. Como o segundo parâmetro de soma, m, está implícito, seu valor é procurado no escopo atual, com base no tipo de monóide exigido em cada caso, o que significa que ambas as expressões podem ser totalmente avaliadas. */ + println(sum(List(1, 2, 3))) // uses IntMonoid implicitly + println(sum(List("a", "b", "c"))) // uses StringMonoid implicitly +} +``` + +Aqui está a saída do programa: + +``` +6 +abc +``` From 563a478c96f9c475459671390fba7c53bc27965c Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 21:47:01 -0200 Subject: [PATCH 26/34] Tutorials - Translation PT-BR - Implicit Conversions --- pt-br/tutorials/tour/implicit-conversions.md | 53 ++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 pt-br/tutorials/tour/implicit-conversions.md diff --git a/pt-br/tutorials/tour/implicit-conversions.md b/pt-br/tutorials/tour/implicit-conversions.md new file mode 100644 index 0000000000..4ac1a31f18 --- /dev/null +++ b/pt-br/tutorials/tour/implicit-conversions.md @@ -0,0 +1,53 @@ +--- +layout: tutorial +title: Conversões Implícitas + +disqus: true + +tutorial: scala-tour +num: 26 +tutorial-next: polymorphic-methods +tutorial-previous: implicit-parameters +language: pt-br +--- + +Uma conversão implícita do tipo `S` para o tipo `T` é definida por um valor implícito que tem o tipo de função `S => T`, ou por um método implícito convertível em um valor de tal tipo. + +As conversões implícitas são aplicadas em duas situações: + +* Se uma expressão `e` for do tipo`S` e `S` não estiver em conformidade com o tipo esperado `T` da expressão. +* Em uma seleção `e.m` com `e` do tipo `T`, se o seletor `m` não representar um membro de `T`. + +No primeiro caso, é procurada uma conversão `c` que seja aplicável a `e` e cujo tipo de resultado esteja em conformidade com `T`. + +No segundo caso, é procurada uma conversão `c` que seja aplicável a `e` e cujo resultado contém um membro chamado `m`. + +A seguinte operação nas duas listas xs e ys do tipo `List[Int]` é válida: + +``` +xs <= ys +``` + +Assuma que os métodos implícitos `list2ordered` e` int2ordered` definidos abaixo estão no mesmo escopo: + +``` +implicit def list2ordered[A](x: List[A]) + (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = + new Ordered[List[A]] { /* .. */ } + +implicit def int2ordered(x: Int): Ordered[Int] = + new Ordered[Int] { /* .. */ } +``` + +O objeto implicitamente importado `scala.Predef` declara vários tipos predefinidos (por exemplo, `Pair`) e métodos (por exemplo, `assert`), mas também várias conversões implícitas. + +Por exemplo, ao chamar um método Java que espera um `java.lang.Integer`, você está livre para passar um `scala.Int` em vez disso. Isso ocorre porque `Predef` inclui as seguintes conversões implícitas: + +```tut +import scala.language.implicitConversions + +implicit def int2Integer(x: Int) = + java.lang.Integer.valueOf(x) +``` + +Para definir suas próprias conversões implícitas, primeiro você deve importar `scala.language.implicitConversions` (ou invocar o compilador com a opção `-language: implicitConversions`). Tal recurso deve ser explicitamente habilitado porque pode se tornar complexo se usado indiscriminadamente. From 6fec4cce7636666ddc33b4868726b349535ab76b Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 21:52:05 -0200 Subject: [PATCH 27/34] Tutorials - Translation PT-BR - Polymorphic Methods --- pt-br/tutorials/tour/polymorphic-methods.md | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 pt-br/tutorials/tour/polymorphic-methods.md diff --git a/pt-br/tutorials/tour/polymorphic-methods.md b/pt-br/tutorials/tour/polymorphic-methods.md new file mode 100644 index 0000000000..161f02393f --- /dev/null +++ b/pt-br/tutorials/tour/polymorphic-methods.md @@ -0,0 +1,31 @@ +--- +layout: tutorial +title: Métodos Polimórficos + +disqus: true + +tutorial: scala-tour +num: 27 + +tutorial-next: local-type-inference +tutorial-previous: implicit-conversions +language: pt-br +--- + +Os métodos em Scala podem ser parametrizados com valores e tipos. Como no nível de classe, os parâmetros de valor são declarados entre de parênteses, enquanto os parâmetros de tipo são declarados entre colchetes. + +Por exemplo: + +```tut +def dup[T](x: T, n: Int): List[T] = { + if (n == 0) + Nil + else + x :: dup(x, n - 1) +} + +println(dup[Int](3, 4)) // primeira chamada +println(dup("three", 3)) // segunda chamada +``` + +O método `dup` é parametrizado com o tipo `T` e com os parâmetros de valor `x: T` e `n: Int`. Na primeira chamada de `dup`, o programador fornece os parâmetros necessários, mas como mostra a seguinte linha, o programador não é obrigado a fornecer explicitamente os parâmetros de tipos. O sistema de tipos de Scala pode inferir tais tipos sem problemas. Isso é feito observando-se os tipos dos parâmetros de valor fornecidos ao método e qual o contexto que o mesmo é chamado. From fe50614a6bdaf6b7aedfc6644ef089aee569affd Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 22:04:59 -0200 Subject: [PATCH 28/34] Tutorials - Translation PT-BR - Local Type Inference --- pt-br/tutorials/tour/classes.md | 1 + pt-br/tutorials/tour/local-type-inference.md | 66 ++++++++++++++++++++ pt-br/tutorials/tour/tour-of-scala.md | 1 + pt-br/tutorials/tour/traits.md | 1 + pt-br/tutorials/tour/unified-types.md | 1 + 5 files changed, 70 insertions(+) create mode 100644 pt-br/tutorials/tour/local-type-inference.md diff --git a/pt-br/tutorials/tour/classes.md b/pt-br/tutorials/tour/classes.md index 09c64e14cf..74e7627358 100644 --- a/pt-br/tutorials/tour/classes.md +++ b/pt-br/tutorials/tour/classes.md @@ -8,6 +8,7 @@ tutorial: scala-tour num: 3 tutorial-next: traits tutorial-previous: unified-types +language: pt-br --- Classes em Scala são templates estáticos que podem ser instânciados como vários objetos em tempo de execução. diff --git a/pt-br/tutorials/tour/local-type-inference.md b/pt-br/tutorials/tour/local-type-inference.md new file mode 100644 index 0000000000..d0d40a0017 --- /dev/null +++ b/pt-br/tutorials/tour/local-type-inference.md @@ -0,0 +1,66 @@ +--- +layout: tutorial +title: Inferência de Tipo Local + +disqus: true + +tutorial: scala-tour +num: 28 +tutorial-next: operators +tutorial-previous: polymorphic-methods +language: pt-br +--- + +Scala tem um mecanismo nativo de inferência de tipos que permite ao programador omitir certas anotações. Por exemplo, muitas vezes não é necessário especificar o tipo de uma variável, uma vez que o compilador pode deduzir o tipo a partir da expressão de inicialização da variável. Também os tipos de retorno de métodos podem muitas vezes ser omitidos, uma vez que correspondem ao tipo do corpo do método, que é inferido pelo compilador. + +Por exemplo: + +```tut +object InferenceTest1 extends App { + val x = 1 + 2 * 3 // o tipo de x é Int + val y = x.toString() // o tipo de y é String + def succ(x: Int) = x + 1 // o método succ retorna um valor Int +} +``` + +Para métodos recursivos, o compilador não é capaz de inferir o tipo de retorno. + +Exemplo de um método que não irá compilar por este motivo: + +```tut:fail +object InferenceTest2 { + def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) +} +``` + +Também não é obrigatório especificar os tipos dos parâmetros quando [métodos polimórficos](polymorphic-methods.html) são invocados ou são criadas instâncias de [classes genéricas](generic-classes.html). O compilador Scala irá inferir tais parâmetros que não estão presentes a partir do contexto das chamadas e dos tipos dos parâmetros reais do método/construtor. + +Por exemplo: + +``` +case class MyPair[A, B](x: A, y: B); +object InferenceTest3 extends App { + def id[T](x: T) = x + val p = MyPair(1, "scala") // type: MyPair[Int, String] + val q = id(1) // type: Int +} +``` + +As duas últimas linhas deste programa são equivalentes ao seguinte código onde todos os tipos inferidos são declarados explicitamente: + +``` +val x: MyPair[Int, String] = MyPair[Int, String](1, "scala") +val y: Int = id[Int](1) +``` + +Em algumas situações, pode ser muito perigoso confiar no mecanismo de inferência de tipos de Scala como mostra o seguinte programa: + + +```tut:fail +object InferenceTest4 { + var obj = null + obj = new Object() +} +``` + +Este programa não compila porque o tipo inferido para a variável `obj` é `Null`. Como o único valor desse tipo é `null`, é impossível fazer essa variável se referir a outro valor. diff --git a/pt-br/tutorials/tour/tour-of-scala.md b/pt-br/tutorials/tour/tour-of-scala.md index 125628c459..e4f82bddb0 100644 --- a/pt-br/tutorials/tour/tour-of-scala.md +++ b/pt-br/tutorials/tour/tour-of-scala.md @@ -8,6 +8,7 @@ tutorial: scala-tour num: 1 outof: 33 tutorial-next: unified-types +language: pt-br --- Scala é uma linguagem de programação moderna e multi-paradigma desenvolvida para expressar padrões de programação comuns em uma forma concisa, elegante e com tipagem segura. Integra fácilmente características de linguagens orientadas a objetos e funcional. diff --git a/pt-br/tutorials/tour/traits.md b/pt-br/tutorials/tour/traits.md index 4184c19a66..9ee180dc85 100644 --- a/pt-br/tutorials/tour/traits.md +++ b/pt-br/tutorials/tour/traits.md @@ -8,6 +8,7 @@ tutorial: scala-tour num: 4 tutorial-next: mixin-class-composition tutorial-previous: classes +language: pt-br --- Similar a interfaces em Java, traits são utilizadas para definir tipos de objetos apenas especificando as assinaturas dos métodos suportados. Como em Java 8, Scala permite que traits sejam parcialmente implementadas; ex. é possível definir uma implementação padrão para alguns métodos. Diferentemente de classes, traits não precisam ter construtores com parâmetros. diff --git a/pt-br/tutorials/tour/unified-types.md b/pt-br/tutorials/tour/unified-types.md index 93af193e39..809305dcf1 100644 --- a/pt-br/tutorials/tour/unified-types.md +++ b/pt-br/tutorials/tour/unified-types.md @@ -8,6 +8,7 @@ tutorial: scala-tour num: 2 tutorial-next: classes tutorial-previous: tour-of-scala +language: pt-br --- Diferente de Java, todos os valores em Scala são objetos (incluindo valores numéricos e funções). Dado que Scala é baseada em classes, todos os valores são instâncias de uma classe. O diagrama a seguir ilustra a hierarquia de classes. From 866439c310a6026a6292d365e98b6325ec4c9d17 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 22:09:10 -0200 Subject: [PATCH 29/34] Tutorials - Translation PT-BR - Operators --- pt-br/tutorials/tour/operators.md | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 pt-br/tutorials/tour/operators.md diff --git a/pt-br/tutorials/tour/operators.md b/pt-br/tutorials/tour/operators.md new file mode 100644 index 0000000000..5b097cdb12 --- /dev/null +++ b/pt-br/tutorials/tour/operators.md @@ -0,0 +1,38 @@ +--- +layout: tutorial +title: Operadores + +disqus: true + +tutorial: scala-tour +num: 29 +tutorial-next: automatic-closures +tutorial-previous: local-type-inference +language: pt-br +--- + +Qualquer método que tenha um único parâmetro pode ser usado como um *operador infix* em Scala. Aqui está a definição da classe `MyBool` que inclui os métodos `add` e `or`: + +```tut +case class MyBool(x: Boolean) { + def and(that: MyBool): MyBool = if (x) that else this + def or(that: MyBool): MyBool = if (x) this else that + def negate: MyBool = MyBool(!x) +} +``` + +Agora é possível utilizar as funções `and` and `or` como operadores infix: + +```tut +def not(x: MyBool) = x.negate +def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) +``` + +Isso ajuda a tornar a definição de `xor` mais legível. + +Aqui está o código correspondente em uma sintaxe de linguagem de programação orientada a objetos mais tradicional: + +```tut +def not(x: MyBool) = x.negate +def xor(x: MyBool, y: MyBool) = x.or(y).and(x.and(y).negate) +``` From 14db0cc280cb10a254369402af72cfeae9427159 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 22:19:10 -0200 Subject: [PATCH 30/34] Tutorials - Translation PT-BR - Automatic Closures --- pt-br/tutorials/tour/automatic-closures.md | 72 ++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 pt-br/tutorials/tour/automatic-closures.md diff --git a/pt-br/tutorials/tour/automatic-closures.md b/pt-br/tutorials/tour/automatic-closures.md new file mode 100644 index 0000000000..64c6df8348 --- /dev/null +++ b/pt-br/tutorials/tour/automatic-closures.md @@ -0,0 +1,72 @@ +--- +layout: tutorial +title: Automatic Type-Dependent Closure Construction + +disqus: true + +tutorial: scala-tour +num: 30 +tutorial-next: annotations +tutorial-previous: operators +language: pt-br +--- + +O Scala permite nomes de funções sem parâmetros como parâmetros de métodos. Quando um tal método é chamado, os parâmetros reais para nomes de função sem parâmetros não são avaliados e uma função nula é passada em vez disso, tal função encapsula a computação do parâmetro correspondente (isso é conhecido por avaliação *call-by-name*). + +O código a seguir demonstra esse mecanismo: + +```tut +object TargetTest1 extends App { + def whileLoop(cond: => Boolean)(body: => Unit): Unit = + if (cond) { + body + whileLoop(cond)(body) + } + var i = 10 + whileLoop (i > 0) { + println(i) + i -= 1 + } +} +``` + +A função `whileLoop` tem dois parâmetros `cond` e `body`. Quando a função é aplicada, os parâmetros reais não são avaliados. Mas sempre que os parâmetros formais são usados no corpo de `whileLoop`, as funções nulas criadas implicitamente serão avaliadas em seu lugar. Assim, o nosso método `whileLoop` implementa um while-loop Java-like com um esquema de implementação recursiva. + +Podemos combinar o uso de [operadores infix/postfix](operators.html) com este mecanismo para criar declarações mais complexas (com uma sintaxe agradável). + +Aqui está a implementação de uma instrução que executa loop ao menos que uma condição seja satisfeita: + +```tut +object TargetTest2 extends App { + def loop(body: => Unit): LoopUnlessCond = + new LoopUnlessCond(body) + protected class LoopUnlessCond(body: => Unit) { + def unless(cond: => Boolean) { + body + if (!cond) unless(cond) + } + } + var i = 10 + loop { + println("i = " + i) + i -= 1 + } unless (i == 0) +} +``` + +A função `loop` apenas aceita um corpo de um loop e retorna uma instância da classe` LoopUnlessCond` (que encapsula este objeto de corpo). Note que o corpo ainda não foi avaliado. A classe `LoopUnlessCond` tem um método `unless` que podemos usar como um *operador infix*. Dessa forma, obtemos uma sintaxe bastante natural para nosso novo loop: `loop { } unless ( )`. + +Aqui está a saída de quando o `TargetTest2` é executado: + +``` +i = 10 +i = 9 +i = 8 +i = 7 +i = 6 +i = 5 +i = 4 +i = 3 +i = 2 +i = 1 +``` From 585e848e2350186921733ebfe9afc908c7b5586f Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 22:49:24 -0200 Subject: [PATCH 31/34] Tutorials - Translation PT-BR - Annotations --- pt-br/tutorials/tour/annotations.md | 151 ++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 pt-br/tutorials/tour/annotations.md diff --git a/pt-br/tutorials/tour/annotations.md b/pt-br/tutorials/tour/annotations.md new file mode 100644 index 0000000000..f7e67db9a7 --- /dev/null +++ b/pt-br/tutorials/tour/annotations.md @@ -0,0 +1,151 @@ +--- +layout: tutorial +title: Anotações + +disqus: true + +tutorial: scala-tour +num: 31 +tutorial-next: default-parameter-values +tutorial-previous: automatic-closures +language: pt-br +--- + +Anotações associam meta-informação com definições. + +Uma cláusula de anotação simples tem a forma `@C` ou `@C(a1,..., an)`. Aqui, `C` é um construtor de uma classe `C`, que deve estar em conformidade com a classe `scala.Annotation`. Todos os argumentos de construtor fornecidos `a1, .., an` devem ser expressões constantes (isto é, expressões em literais numéricos, strings, classe, enumerações Java e matrizes uni-dimensionais). + +Uma cláusula de anotação se aplica à primeira definição ou declaração que a segue. Mais de uma cláusula de anotação pode preceder uma definição e uma declaração. Não importa a ordem em que essas cláusulas são declaradas. + +O significado das cláusulas de anotação é _implementação-dependente_. Na plataforma Java, as seguintes anotações Scala têm um significado padrão. + +| Scala | Java | +| ------ | ------ | +| [`scala.SerialVersionUID`](http://www.scala-lang.org/api/2.9.1/scala/SerialVersionUID.html) | [`serialVersionUID`](http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html#navbar_bottom) (field) | +| [`scala.cloneable`](http://www.scala-lang.org/api/2.9.1/scala/cloneable.html) | [`java.lang.Cloneable`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Cloneable.html) | +| [`scala.deprecated`](http://www.scala-lang.org/api/2.9.1/scala/deprecated.html) | [`java.lang.Deprecated`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Deprecated.html) | +| [`scala.inline`](http://www.scala-lang.org/api/2.9.1/scala/inline.html) (desde 2.6.0) | não há equivalente | +| [`scala.native`](http://www.scala-lang.org/api/2.9.1/scala/native.html) (desde 2.6.0) | [`native`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) | +| [`scala.remote`](http://www.scala-lang.org/api/2.9.1/scala/remote.html) | [`java.rmi.Remote`](http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/Remote.html) | +| [`scala.serializable`](http://www.scala-lang.org/api/2.9.1/index.html#scala.annotation.serializable) | [`java.io.Serializable`](http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html) | +| [`scala.throws`](http://www.scala-lang.org/api/2.9.1/scala/throws.html) | [`throws`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) | +| [`scala.transient`](http://www.scala-lang.org/api/2.9.1/scala/transient.html) | [`transient`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) | +| [`scala.unchecked`](http://www.scala-lang.org/api/2.9.1/scala/unchecked.html) (since 2.4.0) | não há equivalente | +| [`scala.volatile`](http://www.scala-lang.org/api/2.9.1/scala/volatile.html) | [`volatile`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) | +| [`scala.reflect.BeanProperty`](http://www.scala-lang.org/api/2.9.1/scala/reflect/BeanProperty.html) | [`Design pattern`](http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html) | + +No exemplo a seguir, adicionamos a anotação `throws` à definição do método `read` para capturar a exceção lançada no código Java. + +> Um compilador Java verifica se um programa contém manipuladores para [exceções verificadas](http://docs.oracle.com/javase/specs/jls/se5.0/html/exceptions.html) analisando quais exceções verificadas podem resultar da execução de um método ou construtor. Para cada exceção verificada que é um resultado possível, a cláusula **throws** para o método ou construtor _deve_ mencionar a classe dessa exceção ou uma das superclasses da classe dessa exceção. +> Como Scala não tem exceções verificadas, os métodos Scala _devem_ ser anotados com uma ou mais anotações `throws`, de forma que o código Java possa capturar exceções lançadas por um método Scala. + + +Exemplo de classe Scala que lança uma exceção do tipo `IOException`: + +``` +package examples +import java.io._ +class Reader(fname: String) { + private val in = new BufferedReader(new FileReader(fname)) + @throws(classOf[IOException]) + def read() = in.read() +} +``` + +O programa Java a seguir imprime o conteúdo do arquivo cujo nome é passado como o primeiro argumento para o método `main`. + +``` +package test; +import examples.Reader; // Classe Scala acima declarada!! +public class AnnotaTest { + public static void main(String[] args) { + try { + Reader in = new Reader(args[0]); + int c; + while ((c = in.read()) != -1) { + System.out.print((char) c); + } + } catch (java.io.IOException e) { + System.out.println(e.getMessage()); + } + } +} +``` + +Se comentar a anotação `throws` na classe `Reader` o complidor produz a seguinte mensagem de erro ao compilar o programa principal Java: + +``` +Main.java:11: exception java.io.IOException is never thrown in body of +corresponding try statement + } catch (java.io.IOException e) { + ^ +1 error +``` + +### Anotações Java ### + +**Nota:** Certifique-se de usar a opção `-target: jvm-1.5` com anotações Java. + +Java 1.5 introduziu metadados definidos pelo usuário na forma de [anotações](http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html). Uma característica chave das anotações é que elas dependem da especificação de pares no formato nome-valor para inicializar seus elementos. Por exemplo, se precisamos de uma anotação para rastrear a origem de alguma classe, podemos defini-la como: + +``` +@interface Source { + public String URL(); + public String mail(); +} +``` + +O uso da anotação Source fica da seguinte forma + +``` +@Source(URL = "http://coders.com/", + mail = "support@coders.com") +public class MyClass extends HisClass ... +``` + +A uso de anotações em Scala parece uma invocação de construtor, para instanciar uma anotação Java é preciso usar argumentos nomeados: + +``` +@Source(URL = "http://coders.com/", + mail = "support@coders.com") +class MyScalaClass ... +``` + +Esta sintaxe é bastante tediosa, se a anotação contiver apenas um parâmetro (sem valor padrão), por convenção, se o nome for especificado como `value`, ele pode ser aplicado em Java usando uma sintaxe semelhante a Scala, ou seja parecido com a invocação de um construtor: + +``` +@interface SourceURL { + public String value(); + public String mail() default ""; +} +``` + +O uso da anotação SourceURL fica da seguinte forma + +``` +@SourceURL("http://coders.com/") +public class MyClass extends HisClass ... +``` + +Neste caso, a Scala oferece a mesma possibilidade + +``` +@SourceURL("http://coders.com/") +class MyScalaClass ... +``` + +O elemento `mail` foi especificado com um valor padrão, portanto não precisamos fornecer explicitamente um valor para ele. No entanto, se precisarmos fazer isso, não podemos misturar e combinar os dois estilos em Java: + +``` +@SourceURL(value = "http://coders.com/", + mail = "support@coders.com") +public class MyClass extends HisClass ... +``` + +A Scala proporciona mais flexibilidade a respeito disso: + +``` +@SourceURL("http://coders.com/", + mail = "support@coders.com") + class MyScalaClass ... +``` \ No newline at end of file From 9cf0f809f90cdcb1182cbc97bae7045d7e1aea3c Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Sun, 8 Jan 2017 23:03:27 -0200 Subject: [PATCH 32/34] Tutorials - Translation PT-BR - Default Parameter Values --- .../tour/default-parameter-values.md | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 pt-br/tutorials/tour/default-parameter-values.md diff --git a/pt-br/tutorials/tour/default-parameter-values.md b/pt-br/tutorials/tour/default-parameter-values.md new file mode 100644 index 0000000000..f7f37e094a --- /dev/null +++ b/pt-br/tutorials/tour/default-parameter-values.md @@ -0,0 +1,74 @@ +--- +layout: tutorial +title: Valor Padrão de Parâmetro + +disqus: true + +tutorial: scala-tour +num: 32 +tutorial-next: named-parameters +tutorial-previous: annotations +language: pt-br +--- + +Scala provê a capacidade de fornecer parâmetros com valores padrão que podem ser usados para permitir que um usuário possa omitir tais parâmetros se preciso. + +Em Java, é comum ver um monte de métodos sobrecarregados que servem apenas para fornecer valores padrão para determinados parâmetros de um método maior. Isso é especialmente verdadeiro com os construtores: + +```java +public class HashMap { + public HashMap(Map m); + /** Cria um novo HashMap com a capacidade padrão (16) + * and loadFactor (0.75) + */ + public HashMap(); + /** Cria um novo HashMap com um fator de carga padrão (0.75) */ + public HashMap(int initialCapacity); + public HashMap(int initialCapacity, float loadFactor); +} +``` + +Há realmente apenas dois construtores aqui; Um que recebe um map e outro que tem uma capacidade e um fator de carga. O terceiro e o quarto construtores estão lá para permitir que os usuários do HashMap criem instâncias com os valores padrões de fator de carga e capacidade, que provavelmente são bons para a maioria dos casos. + +O maior problema é que os valores usados como padrões estão declarados no Javadoc *e* no código. Manter isso atualizado é complicado, pois pode ser esquecido facilmente. Um abordagem típica nesses casos seria adicionar constantes públicas cujos valores aparecerão no Javadoc: + +```java +public class HashMap { + public static final int DEFAULT_CAPACITY = 16; + public static final float DEFAULT_LOAD_FACTOR = 0.75; + + public HashMap(Map m); + /** Cria um novo HashMap com capacidade padrão (16) + * e fator de carga padrão (0.75) + */ + public HashMap(); + /** Cria um novo HashMap com um fator de carga padrão (0.75) */ + public HashMap(int initialCapacity); + public HashMap(int initialCapacity, float loadFactor); +} +``` + +Enquanto isso nos impede de nos repetir, é menos do que expressivo. + +Scala adiciona suporte direto para isso: + +```tut +class HashMap[K,V](initialCapacity:Int = 16, loadFactor:Float = 0.75f) { +} + +// Utiliza os valores padrões (16, 0.75f) +val m1 = new HashMap[String,Int] + +// Inicial com capacidade 20, e fator de carga padrão +val m2= new HashMap[String,Int](20) + +// Sobreescreve ambos os valores +val m3 = new HashMap[String,Int](20,0.8f) + +// Sobreescreve somente o fator de carga +// parâmetro nomeado +val m4 = new HashMap[String,Int](loadFactor = 0.8f) +``` + +Observe como podemos tirar proveito de *qualquer* valor padrão usando [parâmetros nomeados](named-parameters.html). + From 666b876fb54f4c378837db4699ee26984e4904ce Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Mon, 9 Jan 2017 00:25:33 -0200 Subject: [PATCH 33/34] Tutorials - Translation PT-BR - Named Parameters --- .../tour/default-parameter-values.md | 2 +- pt-br/tutorials/tour/named-parameters.md | 39 +++++++++++++++++++ pt-br/tutorials/tour/traits.md | 10 ++--- 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 pt-br/tutorials/tour/named-parameters.md diff --git a/pt-br/tutorials/tour/default-parameter-values.md b/pt-br/tutorials/tour/default-parameter-values.md index f7f37e094a..a794885b79 100644 --- a/pt-br/tutorials/tour/default-parameter-values.md +++ b/pt-br/tutorials/tour/default-parameter-values.md @@ -1,6 +1,6 @@ --- layout: tutorial -title: Valor Padrão de Parâmetro +title: Parâmetro com Valor Padrão disqus: true diff --git a/pt-br/tutorials/tour/named-parameters.md b/pt-br/tutorials/tour/named-parameters.md new file mode 100644 index 0000000000..057c5ae25a --- /dev/null +++ b/pt-br/tutorials/tour/named-parameters.md @@ -0,0 +1,39 @@ +--- +layout: tutorial +title: Parâmetros Nomeados + +disqus: true + +tutorial: scala-tour +num: 33 +tutorial-previous: default-parameter-values +language: pt-br +--- + +Ao chamar métodos e funções, você pode utilizar explicitamente o nome das variáveis nas chamadas, por exemplo: + +```tut + def imprimeNome(nome:String, sobrenome:String) = { + println(nome + " " + sobrenome) + } + + imprimeNome("John","Smith") + // Imprime "John Smith" + imprimeNome(nome = "John",sobrenome = "Smith") + // Imprime "John Smith" + imprimeNome(sobrenome = "Smith",nome = "John") + // Imprime "John Smith" +``` + +Perceba que a ordem não importa quando você utiliza parâmetros nomeados nas chamadas de métodos e funções, desde que todos os parâmetros sejam declarados. Essa funcionalidade pode ser combinada com [parâmetros com valor padrão](default-parameter-values.html): + +```tut + def imprimeNome(nome:String = "John", sobrenome:String = "Smith") = { + println(nome + " " + sobrenome) + } + + imprimeNome(sobrenome = "Forbeck") + // Imprime "John Forbeck" +``` + +Dado que é permitido declarar os parâmetros em qualquer ordem, você pode utilizar o valor padrão para parâmetros que aparecem primeiro na lista de parâmetros da função. diff --git a/pt-br/tutorials/tour/traits.md b/pt-br/tutorials/tour/traits.md index 9ee180dc85..7a017284ce 100644 --- a/pt-br/tutorials/tour/traits.md +++ b/pt-br/tutorials/tour/traits.md @@ -24,7 +24,7 @@ trait Similaridade { Tal trait consiste em dois métodos `eSemelhante` e `naoESemelhante`. Equanto `eSemelhante` não fornece um método com implementação concreta (que é semelhante ao abstract na linguagem Java), o método `naoESemelhante` define um implementação concreta. Consequentemente, classes que integram essa trait só precisam fornecer uma implementação concreta para o método `eSemelhante`. O comportamento para `naoESemelhante` é herdado diretamente da trait. Traits são tipicamente integradas a uma [classe](classes.html) (ou outras traits) utilizando a [composição mesclada de classes](mixin-class-composition.html): ```tut -class Ponto(xc: Int, yc: Int) extends Similaridade { +class Point(xc: Int, yc: Int) extends Similaridade { var x: Int = xc var y: Int = yc def eSemelhante(obj: Any) = @@ -32,10 +32,10 @@ class Ponto(xc: Int, yc: Int) extends Similaridade { obj.asInstanceOf[Point].x == x } object TraitsTest extends App { - val p1 = new Ponto(2, 3) - val p2 = new Ponto(2, 4) - val p3 = new Ponto(3, 3) - val p4 = new Ponto(2, 3) + val p1 = new Point(2, 3) + val p2 = new Point(2, 4) + val p3 = new Point(3, 3) + val p4 = new Point(2, 3) println(p1.eSemelhante(p2)) println(p1.eSemelhante(p3)) // Ponto.naoESemelhante foi definido na classe Similaridade From f843b3111ef0e25f27e7774e96cd296778c72bf8 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Tue, 10 Jan 2017 21:55:08 -0200 Subject: [PATCH 34/34] Fixed: typos and translations --- pt-br/tutorials/tour/abstract-types.md | 12 ++++++------ pt-br/tutorials/tour/annotations.md | 10 +++++----- .../tour/anonymous-function-syntax.md | 4 ++-- pt-br/tutorials/tour/automatic-closures.md | 12 +++++++----- pt-br/tutorials/tour/case-classes.md | 18 +++++++++--------- pt-br/tutorials/tour/classes.md | 6 +++--- pt-br/tutorials/tour/compound-types.md | 4 ++-- pt-br/tutorials/tour/currying.md | 2 +- .../tour/explicitly-typed-self-references.md | 6 +++--- pt-br/tutorials/tour/extractor-objects.md | 10 +++++----- pt-br/tutorials/tour/generic-classes.md | 12 ++++++------ pt-br/tutorials/tour/higher-order-functions.md | 2 +- pt-br/tutorials/tour/implicit-conversions.md | 2 +- pt-br/tutorials/tour/implicit-parameters.md | 6 +++--- pt-br/tutorials/tour/inner-classes.md | 4 ++-- pt-br/tutorials/tour/local-type-inference.md | 2 +- pt-br/tutorials/tour/lower-type-bounds.md | 2 +- pt-br/tutorials/tour/pattern-matching.md | 2 +- pt-br/tutorials/tour/polymorphic-methods.md | 2 +- .../tutorials/tour/sequence-comprehensions.md | 2 +- pt-br/tutorials/tour/singleton-objects.md | 10 +++++----- pt-br/tutorials/tour/tour-of-scala.md | 8 ++++---- pt-br/tutorials/tour/unified-types.md | 2 +- pt-br/tutorials/tour/upper-type-bounds.md | 2 +- 24 files changed, 72 insertions(+), 70 deletions(-) diff --git a/pt-br/tutorials/tour/abstract-types.md b/pt-br/tutorials/tour/abstract-types.md index c2adfab8fe..e6fafa5909 100644 --- a/pt-br/tutorials/tour/abstract-types.md +++ b/pt-br/tutorials/tour/abstract-types.md @@ -11,9 +11,9 @@ tutorial-previous: inner-classes language: pt-br --- -Em Scala, as classes são parametrizadas com valores (parâmetros de construtor) e com tipos (se [classes genéricas](generic-classes.html)). Por razões de regularidade, só não é possível ter valores como membros de um objeto; tipos juntamente com valores são membros de objetos. Além disso, ambas as formas de membros podem ser concretas e abstratas. +Em Scala, as classes são parametrizadas com valores (os parâmetros de construtor) e com tipos (se as [classes genéricas](generic-classes.html)). Por razões de regularidade, só não é possível ter valores como membros de um objeto; tipos juntamente com valores são membros de objetos. Além disso, ambas as formas de membros podem ser concretas e abstratas. -Aqui está um exemplo que define uma definição de valor diferido e uma definição de tipo abstrato como membros de uma [trait](traits.html) chamada `Buffer`. +Aqui está um exemplo que mostra uma definição de valor diferido e uma definição de tipo abstrato como membros de uma [trait](traits.html) chamada `Buffer`. ```tut trait Buffer { @@ -22,9 +22,9 @@ trait Buffer { } ``` -*Tipos Abstratos* são tipos cuja identidade não é precisamente conhecida. No exemplo acima, só sabemos que cada objeto da classe `Buffer` tem um membro de tipo `T`, mas a definição de classe `Buffer` não revela para qual tipo concreto o membro do tipo `T` corresponde. Como definições de valores, podemos sobrescrever definições de tipos em subclasses. Isso nos permite revelar mais informações sobre um tipo abstrato ao limitar o tipo associado (o qual descreve as possíveis instâncias concretas do tipo abstrato). +*Tipos Abstratos* são tipos cuja identidade não é precisamente conhecida. No exemplo acima, só sabemos que cada objeto da classe `Buffer` tem um membro de tipo `T`, mas a definição de classe `Buffer` não revela a qual tipo concreto o membro do tipo `T` corresponde. Como definições de valores, podemos sobrescrever definições de tipos em subclasses. Isso nos permite revelar mais informações sobre um tipo abstrato ao limitar o tipo associado (o qual descreve as possíveis instâncias concretas do tipo abstrato). -No seguinte programa temos uma classe `SeqBuffer` que nos permite armazenar apenas as sequências no buffer ao definir que o tipo `-T` precisa ser um subtipo de `Seq[U]` para um novo tipo abstrato `U`: +No seguinte programa temos uma classe `SeqBuffer` que nos permite armazenar apenas as sequências no buffer ao definir que o tipo `T` precisa ser um subtipo de `Seq[U]` para um novo tipo abstrato `U`: ```tut abstract class SeqBuffer extends Buffer { @@ -53,7 +53,7 @@ object AbstractTypeTest1 extends App { } ``` -O tipo de retorno do método `newIntSeqBuf` refere-se a uma especialização da trait `Buffer` no qual o tipo `U` é agora equivalente a `Int`. Declaramos um tipo alias semelhante ao que temos na instanciação da classe anônima dentro do corpo do método `newIntSeqBuf`. Criamos uma nova instância de `IntSeqBuffer` na qual o tipo `T` refere-se a `List [Int]`. +O tipo de retorno do método `newIntSeqBuf` refere-se a uma especialização da trait `Buffer` no qual o tipo `U` é agora equivalente a `Int`. Declaramos um tipo *alias* semelhante ao que temos na instanciação da classe anônima dentro do corpo do método `newIntSeqBuf`. Criamos uma nova instância de `IntSeqBuffer` na qual o tipo `T` refere-se a `List[Int]`. Observe que muitas vezes é possível transformar os membros de tipo abstrato em parâmetros de tipo de classes e vice-versa. Aqui está uma versão do código acima que usa apenas parâmetros de tipo: @@ -75,5 +75,5 @@ object AbstractTypeTest2 extends App { } ``` -Note que temos que usar [anotação de variância](variances.html) aqui; Caso contrário, não seríamos capazes de ocultar o tipo implementado pela sequência concreta do objeto retornado por `newIntSeqBuf`. Além disso, há casos em que não é possível substituir tipos abstratos com parâmetros de tipo. +Note que temos que usar [anotação de variância](variances.html) aqui; Caso contrário, não seríamos capazes de ocultar o tipo implementado pela sequência concreta do objeto retornado pelo método `newIntSeqBuf`. Além disso, há casos em que não é possível substituir tipos abstratos com parâmetros de tipo. diff --git a/pt-br/tutorials/tour/annotations.md b/pt-br/tutorials/tour/annotations.md index f7e67db9a7..03171b267d 100644 --- a/pt-br/tutorials/tour/annotations.md +++ b/pt-br/tutorials/tour/annotations.md @@ -13,11 +13,11 @@ language: pt-br Anotações associam meta-informação com definições. -Uma cláusula de anotação simples tem a forma `@C` ou `@C(a1,..., an)`. Aqui, `C` é um construtor de uma classe `C`, que deve estar em conformidade com a classe `scala.Annotation`. Todos os argumentos de construtor fornecidos `a1, .., an` devem ser expressões constantes (isto é, expressões em literais numéricos, strings, classe, enumerações Java e matrizes uni-dimensionais). +Uma cláusula de anotação simples tem a forma `@C` ou `@C(a1,..., an)`. Aqui, `C` é um construtor de uma classe `C`, que deve estar em conformidade com a classe `scala.Annotation`. Todos os argumentos de construtor fornecidos `a1, .., an` devem ser expressões constantes (isto é, expressões em literais numéricos, strings, literais de classes, enumerações Java e matrizes uni-dimensionais). -Uma cláusula de anotação se aplica à primeira definição ou declaração que a segue. Mais de uma cláusula de anotação pode preceder uma definição e uma declaração. Não importa a ordem em que essas cláusulas são declaradas. +Uma cláusula de anotação se aplica à primeira definição ou declaração que a segue. Mais de uma cláusula de anotação pode preceder uma definição e uma declaração. Não importa a ordem em que essas cláusulas são declaradas. -O significado das cláusulas de anotação é _implementação-dependente_. Na plataforma Java, as seguintes anotações Scala têm um significado padrão. +O significado das cláusulas de anotação é _dependente da implementação_. Na plataforma Java, as seguintes anotações Scala têm um significado padrão. | Scala | Java | | ------ | ------ | @@ -72,7 +72,7 @@ public class AnnotaTest { } ``` -Se comentar a anotação `throws` na classe `Reader` o complidor produz a seguinte mensagem de erro ao compilar o programa principal Java: +Comentando-se a anotação `throws` na classe `Reader` o compilador produz a seguinte mensagem de erro ao compilar o programa principal Java: ``` Main.java:11: exception java.io.IOException is never thrown in body of @@ -142,7 +142,7 @@ O elemento `mail` foi especificado com um valor padrão, portanto não precisamo public class MyClass extends HisClass ... ``` -A Scala proporciona mais flexibilidade a respeito disso: +Scala proporciona mais flexibilidade a respeito disso: ``` @SourceURL("http://coders.com/", diff --git a/pt-br/tutorials/tour/anonymous-function-syntax.md b/pt-br/tutorials/tour/anonymous-function-syntax.md index d141ab44e3..c1778f6bf5 100644 --- a/pt-br/tutorials/tour/anonymous-function-syntax.md +++ b/pt-br/tutorials/tour/anonymous-function-syntax.md @@ -25,13 +25,13 @@ new Function1[Int, Int] { } ``` -Também é possível definir funções com mútiplos parâmetros: +Também é possível definir funções com múltiplos parâmetros: ```tut (x: Int, y: Int) => "(" + x + ", " + y + ")" ``` -or sem parâmetros: +ou sem parâmetros: ```tut () => { System.getProperty("user.dir") } diff --git a/pt-br/tutorials/tour/automatic-closures.md b/pt-br/tutorials/tour/automatic-closures.md index 64c6df8348..9d0d118651 100644 --- a/pt-br/tutorials/tour/automatic-closures.md +++ b/pt-br/tutorials/tour/automatic-closures.md @@ -1,6 +1,6 @@ --- layout: tutorial -title: Automatic Type-Dependent Closure Construction +title: Construção Automática de Closures de Tipo-Dependente disqus: true @@ -11,7 +11,9 @@ tutorial-previous: operators language: pt-br --- -O Scala permite nomes de funções sem parâmetros como parâmetros de métodos. Quando um tal método é chamado, os parâmetros reais para nomes de função sem parâmetros não são avaliados e uma função nula é passada em vez disso, tal função encapsula a computação do parâmetro correspondente (isso é conhecido por avaliação *call-by-name*). +_Nota de tradução: A palavra `closure` em pode ser traduzida como encerramento/fechamento, porém é preferível utilizar a notação original_ + +Scala permite funções sem parâmetros como parâmetros de métodos. Quando um tal método é chamado, os parâmetros reais para nomes de função sem parâmetros não são avaliados e uma função nula é passada em vez disso, tal função encapsula a computação do parâmetro correspondente (isso é conhecido por avaliação *call-by-name*). O código a seguir demonstra esse mecanismo: @@ -30,11 +32,11 @@ object TargetTest1 extends App { } ``` -A função `whileLoop` tem dois parâmetros `cond` e `body`. Quando a função é aplicada, os parâmetros reais não são avaliados. Mas sempre que os parâmetros formais são usados no corpo de `whileLoop`, as funções nulas criadas implicitamente serão avaliadas em seu lugar. Assim, o nosso método `whileLoop` implementa um while-loop Java-like com um esquema de implementação recursiva. +A função `whileLoop` recebe dois parâmetros: `cond` e `body`. Quando a função é aplicada, os parâmetros reais não são avaliados. Mas sempre que os parâmetros formais são usados no corpo de `whileLoop`, as funções nulas criadas implicitamente serão avaliadas em seu lugar. Assim, o nosso método `whileLoop` implementa um while-loop Java-like com um esquema de implementação recursiva. Podemos combinar o uso de [operadores infix/postfix](operators.html) com este mecanismo para criar declarações mais complexas (com uma sintaxe agradável). -Aqui está a implementação de uma instrução que executa loop ao menos que uma condição seja satisfeita: +Aqui está a implementação de uma instrução que executa loop a menos que uma condição seja satisfeita: ```tut object TargetTest2 extends App { @@ -54,7 +56,7 @@ object TargetTest2 extends App { } ``` -A função `loop` apenas aceita um corpo de um loop e retorna uma instância da classe` LoopUnlessCond` (que encapsula este objeto de corpo). Note que o corpo ainda não foi avaliado. A classe `LoopUnlessCond` tem um método `unless` que podemos usar como um *operador infix*. Dessa forma, obtemos uma sintaxe bastante natural para nosso novo loop: `loop { } unless ( )`. +A função `loop` aceita apenas um corpo e retorna uma instância da classe` LoopUnlessCond` (que encapsula este objeto de corpo). Note que o corpo ainda não foi avaliado. A classe `LoopUnlessCond` tem um método `unless` que podemos usar como um *operador infix*. Dessa forma, obtemos uma sintaxe bastante natural para nosso novo loop: `loop { } unless ( )`. Aqui está a saída de quando o `TargetTest2` é executado: diff --git a/pt-br/tutorials/tour/case-classes.md b/pt-br/tutorials/tour/case-classes.md index f7d371b6fd..c71161872a 100644 --- a/pt-br/tutorials/tour/case-classes.md +++ b/pt-br/tutorials/tour/case-classes.md @@ -15,10 +15,10 @@ Scala suporta o conceito de _classes case_. Classes case são classes regulares * Imutáveis por padrão * Decompostas por meio de [correspondência de padrões](pattern-matching.html) -* Comparadas por igualdade estrututal ao invés de referência +* Comparadas por igualdade estrutural ao invés de referência * Sucintas para instanciar e operar -Aqui um exemplo para hierarquia de tipos de notificação que consiste em uma super classe abstrata `Notification` e três tipos concretos de notificação implementados com classes case `Email`, `SMS`, e `VoiceRecording`. +Aqui temos um exemplo de hierarquia de tipos para *Notification* que consiste em uma super classe abstrata `Notification` e três tipos concretos de notificação implementados com classes case `Email`, `SMS`, e `VoiceRecording`. ```tut abstract class Notification @@ -75,7 +75,7 @@ Somos iguais! SMS é: SMS(12345, Hello!) ``` -Com classes case, você pode utilizar **correspondência de padrões** para manipular seus dados. Aqui um exemplo de uma função que escreve como saída diferente mensagens dependendo do tipo de notificação recebida: +Com classes case, você pode utilizar **correspondência de padrões** para manipular seus dados. Aqui temos um exemplo de uma função que escreve como saída diferente mensagens dependendo do tipo de notificação recebida: ```tut def mostrarNotificacao(notificacao: Notification): String = { @@ -114,17 +114,17 @@ def mostrarNotificacaoEspecial(notificacao: Notification, emailEspecial: String, } } -val NUMERO_ESPECIAL = "55555" -val EMAIL_ESPECIAL = "jane@mail.com" +val NumeroEspecial = "55555" +val EmailEspecial = "jane@mail.com" val algumSMS = SMS("12345", "Você está aí?") val algumaMsgVoz = VoiceRecording("Tom", "voicerecording.org/id/123") val emailEspecial = Email("jane@mail.com", "Beber hoje a noite?", "Estou livre depois das 5!") val smsEspecial = SMS("55555", "Estou aqui! Onde está você?") -println(mostrarNotificacaoEspecial(algumSMS, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) -println(mostrarNotificacaoEspecial(algumaMsgVoz, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) -println(mostrarNotificacaoEspecial(smsEspecial, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) -println(mostrarNotificacaoEspecial(smsEspecial, EMAIL_ESPECIAL, NUMERO_ESPECIAL)) +println(mostrarNotificacaoEspecial(algumSMS, EmailEspecial, NumeroEspecial)) +println(mostrarNotificacaoEspecial(algumaMsgVoz, EmailEspecial, NumeroEspecial)) +println(mostrarNotificacaoEspecial(smsEspecial, EmailEspecial, NumeroEspecial)) +println(mostrarNotificacaoEspecial(smsEspecial, EmailEspecial, NumeroEspecial)) // Saída: // Você recebeu um SMS de 12345! Mensagem: Você está aí? diff --git a/pt-br/tutorials/tour/classes.md b/pt-br/tutorials/tour/classes.md index 74e7627358..ae56fd3f57 100644 --- a/pt-br/tutorials/tour/classes.md +++ b/pt-br/tutorials/tour/classes.md @@ -11,7 +11,7 @@ tutorial-previous: unified-types language: pt-br --- -Classes em Scala são templates estáticos que podem ser instânciados como vários objetos em tempo de execução. +Classes em Scala são templates estáticos que podem ser instanciados como vários objetos em tempo de execução. Aqui uma definição de classe que define a classe `Ponto`: ```tut @@ -27,7 +27,7 @@ class Ponto(var x: Int, var y: Int) { Classes em Scala são parametrizadas com argumentos de construtor. O código acima define dois argumentos de construtor, `x` e `y`; ambos são acessíveis por todo o corpo da classe. -A classe também inclui dois métodos, `move` and `toString`. `move` recebe dois parâmetros inteiros mas não retorna um valor (o tipo de retorno `Unit` equivale ao `void` em linguagens como Java). `toString`, por outro lado, não recebe parâmetro algum mas retorna um valor `String`. Dado que `toString` sobrescreve o método pré-definido `toString`, é marcado com a palavra-chave `override`. +A classe também inclui dois métodos, `move` and `toString`. `move` recebe dois parâmetros inteiros mas não retorna um valor (o tipo de retorno `Unit` equivale ao `void` em linguagens como Java). `toString`, por outro lado, não recebe parâmetro algum mas retorna um valor `String`. Dado que `toString` sobrescreve o método pré-definido `toString`, o mesmo é marcado com a palavra-chave `override`. Perceba que em Scala, não é necessário declarar `return` para então retornar um valor. O valor retornado em um método é simplesmente o último valor no corpo do método. No caso do método `toString` acima, a expressão após o sinal de igual é avaliada e retornada para quem chamou a função. @@ -46,7 +46,7 @@ object Classes { O programa define uma aplicação executável chamada Classes como um [Objeto Singleton](singleton-objects) dentro do método `main`. O método `main` cria um novo `Ponto` e armazena o valor em `pt`. Perceba que valores definidos com o construtor `val` são diferentes das variáveis definidas com o construtor `var` (veja acima a classe `Ponto`), `val` não permite atualização do valor, ou seja, o valor é uma constante. -Aqui a saída do programa: +Aqui está a saída do programa: ``` (1, 2) diff --git a/pt-br/tutorials/tour/compound-types.md b/pt-br/tutorials/tour/compound-types.md index 03e7d5baf4..0b7cbd0466 100644 --- a/pt-br/tutorials/tour/compound-types.md +++ b/pt-br/tutorials/tour/compound-types.md @@ -46,8 +46,8 @@ def cloneAndReset(obj: Cloneable with Resetable): Cloneable = { } ``` -Os tipos de compostos podem consistir em vários tipos de objeto e eles podem ter um único refinamento que pode ser usado para restrigird a assinatura de membros de objetos existentes. +Os tipos de compostos podem consistir em vários tipos de objeto e eles podem ter um único refinamento que pode ser usado para restrigir a assinatura de membros de objetos existentes. -A forma geral é: `A com B com C ... { refinamento }` +A forma geral é: `A with B with C ... { refinamento }` Um exemplo para o uso de refinamentos é dado na página sobre [tipos abstratos](abstract-types.html). diff --git a/pt-br/tutorials/tour/currying.md b/pt-br/tutorials/tour/currying.md index 4cd370ea36..d079153331 100644 --- a/pt-br/tutorials/tour/currying.md +++ b/pt-br/tutorials/tour/currying.md @@ -11,7 +11,7 @@ tutorial-previous: nested-functions language: pt-br --- -_Nota de tradução: Currying é uma técnica de programação funcional nomeada em honra ao matemático e lógico Haskell Curry. Por essa razão a palavra Currying não será traduzida. Entende-se que é uma ação, uma técnica básica de Programação Funcional._ +_Nota de tradução: Currying é uma técnica de programação Funcional nomeada em honra ao matemático e lógico Haskell Curry. Por essa razão a palavra Currying não será traduzida. Entende-se que é uma ação, uma técnica básica de Programação Funcional._ Métodos podem definir múltiplas listas de parâmetros. Quando um método é chamado com uma lista menor de parâmetros, então será retornada uma função que recebe a lista que parâmetros que falta como argumentos. diff --git a/pt-br/tutorials/tour/explicitly-typed-self-references.md b/pt-br/tutorials/tour/explicitly-typed-self-references.md index dd3623ca73..b37d18c189 100644 --- a/pt-br/tutorials/tour/explicitly-typed-self-references.md +++ b/pt-br/tutorials/tour/explicitly-typed-self-references.md @@ -58,7 +58,7 @@ abstract class DirectedGraph extends Graph { } ``` -A classe `DirectedGraph` estende a classe `Graph` fornecendo uma implementação parcial. A implementação é apenas parcial porque gostaríamos de poder ampliar o `DirectedGraph`. Portanto, esta classe deixa todos os detalhes de implementação abertos e assim, tanto as arestas e os nós são definidos como abstrato. No entanto, a classe `DirectedGraph` revela alguns detalhes adicionais sobre a implementação do tipo das arestas ao restringir o limite de tipo para a classe `EdgeImpl`. Além disso, temos algumas implementações preliminares de arestas e nós representados pelas classes `EdgeImpl` e `NodeImpl`. Uma vez que é necessário criar novos objetos nó e aresta dentro da nossa implementação de grafo, também temos que adicionar os métodos de construção `newNode` e `newEdge`. Os métodos `addNode` e `connectWith` são ambos definidos em termos destes métodos de construção. Uma análise mais detalhada da implementação do método `connectWith` revela que, para criar uma aresta, temos que passar a auto-referência `this` para o método de construção `newEdge`. Mas a `this` é atribuído o tipo `NodeImpl`, por isso não é compatível com o tipo `Node` que é exigido pelo método de construção correspondente. Como consequência, o programa acima não é bem-formado e o compilador Scala irá emitir uma mensagem de erro. +A classe `DirectedGraph` estende a classe `Graph` fornecendo uma implementação parcial. A implementação é apenas parcial porque gostaríamos de poder ampliar o `DirectedGraph`. Portanto, esta classe deixa todos os detalhes de implementação abertos e assim, tanto as arestas quanto os nós são definidos como abstratos. No entanto, a classe `DirectedGraph` revela alguns detalhes adicionais sobre a implementação do tipo das arestas ao restringir o limite de tipo para a classe `EdgeImpl`. Além disso, temos algumas implementações preliminares de arestas e nós representados pelas classes `EdgeImpl` e `NodeImpl`. Uma vez que é necessário criar novos objetos nó e aresta dentro da nossa implementação de grafo, também temos que adicionar os métodos de construção `newNode` e `newEdge`. Os métodos `addNode` e `connectWith` são ambos definidos em termos destes métodos de construção. Uma análise mais detalhada da implementação do método `connectWith` revela que, para criar uma aresta, temos que passar a auto-referência `this` para o método de construção `newEdge`. Mas a `this` é atribuído o tipo `NodeImpl`, por isso não é compatível com o tipo `Node` que é exigido pelo método de construção correspondente. Como consequência, o programa acima não é bem-formado e o compilador Scala irá emitir uma mensagem de erro. Em Scala é possível vincular uma classe a outro tipo (que será implementado no futuro) ao fornecer a auto referência `this` ao outro tipo explicitamente. Podemos usar esse mecanismo para corrigir nosso código acima. O tipo explícito de `this` é especificado dentro do corpo da classe `DirectedGraph`. @@ -91,7 +91,7 @@ abstract class DirectedGraph extends Graph { } ``` -Nesta nova definição de classe `NodeImpl`, `this` tem o tipo `Node`. Como o tipo `Node` é abstrato e, portanto, ainda não sabemos se `NodeImpl` é realmente um subtipo de `Node`, o sistema de tipo Scala não nos permitirá instanciar esta classe. Mas, no entanto, declaramos com a anotação de tipo explícito que, em algum ponto, (uma subclasse de) `NodeImpl` precisa denotar um subtipo de tipo `Node` para ser instantiável. +Nesta nova definição de classe `NodeImpl`, `this` tem o tipo `Node`. Como o tipo `Node` é abstrato e, portanto, ainda não sabemos se `NodeImpl` é realmente um subtipo de `Node`, o sistema de tipo Scala não nos permitirá instanciar esta classe. No entanto declaramos com a anotação de tipo explícito que, em algum ponto, (uma subclasse de) `NodeImpl` precisa denotar um subtipo de tipo `Node` para ser instantiável. Aqui está uma especialização concreta de `DirectedGraph` onde todos os membros da classe abstrata são definidos: @@ -105,7 +105,7 @@ class ConcreteDirectedGraph extends DirectedGraph { } ``` -Observe que nesta classe, podemos instanciar `NodeImpl` porque agora sabemos que `NodeImpl` representa um subtipo de tipo `Node` (que é simplesmente um alias para `NodeImpl`). +Observe que nesta classe, podemos instanciar `NodeImpl` porque agora sabemos que `NodeImpl` representa um subtipo de tipo `Node` (que é simplesmente um *alias* para `NodeImpl`). Aqui está um exemplo de uso da classe `ConcreteDirectedGraph`: diff --git a/pt-br/tutorials/tour/extractor-objects.md b/pt-br/tutorials/tour/extractor-objects.md index 1690d96d79..a8afb6522c 100644 --- a/pt-br/tutorials/tour/extractor-objects.md +++ b/pt-br/tutorials/tour/extractor-objects.md @@ -11,7 +11,7 @@ tutorial-previous: regular-expression-patterns language: pt-br --- -Em Scala, padrões podem ser definidos independentemente de classes case. Para este fim, um método chamado `unapply` é definido para retorna o extrator. Um extrator pode ser pensado como um método especial que inverte o efeito da aplicação de um determinado objeto em algumas entradas. Seu objetivo é "extrair" as entradas que estavam presentes antes da operação `apply`. Por exemplo, o código a seguir define um [objeto] (singleton-objects.html) extrator chamado Twice. +Em Scala, padrões podem ser definidos independentemente de classes case. Para este fim, um método chamado `unapply` é definido para retornar um extrator. Um extrator pode ser pensado como um método especial que inverte o efeito da aplicação de um determinado objeto em algumas entradas. Seu objetivo é "extrair" as entradas que estavam presentes antes da operação `apply`. Por exemplo, o código a seguir define um [objeto](singleton-objects.html) extrator chamado Twice. ```tut object Twice { @@ -27,16 +27,16 @@ object TwiceTest extends App { Existem duas convenções sintáticas em ação aqui: -O padrão `case Twice (n)` causa a invocação do método `Twice.unapply`, que é usado para fazer o match de qualquer número par; O valor de retorno de `unapply` indica se houve match ou não, e quaisquer sub-valores que possam ser utilizados para um seguinte match. Aqui, o sub-valor é `z/2`. +O padrão `case Twice (n)` causa a invocação do método `Twice.unapply`, que é usado para fazer a comparação de qualquer número par; O valor de retorno de `unapply` indica se a comparação falhou ou não, e quaisquer sub-valores que possam ser utilizados para uma seguinte comparação. Aqui, o sub-valor é `z/2`. O método `apply` não é necessário na correspondência de padrões. É utilizado somente para simular um construtor. `val x = Twice(21)` é expandido para `val x = Twice.apply(21)`. O tipo de retorno de uma chamada `unapply` deveria ser escolhido da seguinta forma: * Se é somente um teste, retorne `Boolean`. Por exemplo `case even()` -* Se retorna um único sub valor to tipo `T`, retorne `Option[T]` -* Se você quer retornar vários sub valores `T1,...,Tn`, agrupe todos em uma tupla opcional como `Option[(T1,...,Tn)]`. +* Se retorna um único subvalor to tipo `T`, retorne `Option[T]` +* Se você quer retornar vários subvalores `T1,...,Tn`, agrupe todos em uma tupla opcional como `Option[(T1,...,Tn)]`. -Algumas vezes, o número de sub valores é fixo e você precisa retornar uma sequência. Para isso, você pode definir padrões através da chamada `unapplySeq`. O último sub valor do tipo `Tn` precisa ser `Seq[S]`. Tal mecanismo é utilizado como exemplo no padrão `case List(x1, ..., xn)`. +Algumas vezes, o número de subvalores é fixo e você precisa retornar uma sequência. Para isso, você pode definir padrões através da chamada `unapplySeq`. O último subvalor do tipo `Tn` precisa ser `Seq[S]`. Tal mecanismo é utilizado como exemplo no padrão `case List(x1, ..., xn)`. Extratores podem tornar o código mais fácil de manter. Para mais detalhes, leia o artigo ["Matching Objects with Patterns"](https://infoscience.epfl.ch/record/98468/files/MatchingObjectsWithPatterns-TR.pdf) (veja a seção 4) by Emir, Odersky and Williams (January 2007). diff --git a/pt-br/tutorials/tour/generic-classes.md b/pt-br/tutorials/tour/generic-classes.md index d75bd75071..a134f109e4 100644 --- a/pt-br/tutorials/tour/generic-classes.md +++ b/pt-br/tutorials/tour/generic-classes.md @@ -11,8 +11,8 @@ tutorial-previous: sequence-comprehensions language: pt-br --- -Semelhante ao Java 5 (aka. [JDK 1.5](http://java.sun.com/j2se/1.5/)), Scala tem suporte nativo para classes parametrizadas com tipos. Essas classes genéricas são particularmente úteis para o desenvolvimento de classes collection. -Aqui um exemplo que demonstra isso: +Semelhante ao Java 5 (aka. [JDK 1.5](http://java.sun.com/j2se/1.5/)), Scala tem suporte nativo para classes parametrizadas com tipos. Essas classes genéricas são particularmente úteis para o desenvolvimento de classes que representam coleções de dados. +Aqui temos um exemplo que demonstra isso: ```tut class Stack[T] { @@ -23,9 +23,9 @@ class Stack[T] { } ``` -A classe `Stack` modela uma pila mutável que contém elementos de um tipo arbitrário `T`. Os parâmetros de tipo garantem que somente os elementos legais (que são do tipo `T`) são inseridos na pilha. Da mesma forma, com os parâmetros de tipo podemos expressar que o método `top` retorna somente elementos de um único tipo de dado, no caso, `T`. +A classe `Stack` modela uma pilha mutável que contém elementos de um tipo arbitrário `T`. Os parâmetros de tipo garantem que somente os elementos legais (que são do tipo `T`) são inseridos na pilha. Da mesma forma, com os parâmetros de tipo podemos expressar que o método `top` retorna somente elementos de um único tipo de dado, no caso, `T`. -Aqui mais alguns exemplo de uso: +Aqui temos mais alguns exemplos de uso: ```tut object GenericsTest extends App { @@ -38,10 +38,10 @@ object GenericsTest extends App { } ``` -O saída do programa é: +A saída do programa é: ``` 97 1 ``` -_Nota: subtipos de tipos genéricos são *invariantes*. Isto significa que se tivermos uma pilha de caracteres do tipo `Stack [Char]` então não pode ser usado como uma pilha de inteiros do tipo `Stack [Int]`. Isso seria incorreto porque ele nos permitiria inserir inteiros verdadeiros na pilha de caracteres. Para concluir, `Stack [T]` é um subtipo de de `Stack [S]` se e somente se `S = T`. Como isso pode ser bastante restritivo, Scala oferece um [mecanismo de anotação de parâmetro de tipo](variances.html) para controlar o comportamento de subtipo de tipos genéricos._ \ No newline at end of file +_Nota: subtipos de tipos genéricos são *invariantes*. Isto significa que se tivermos uma pilha de caracteres do tipo `Stack[Char]` então ela não pode ser usada como uma pilha de inteiros do tipo `Stack[Int]`. Isso seria incorreto porque isso nos permitiria inserir inteiros verdadeiros na pilha de caracteres. Para concluir, `Stack[T]` é um subtipo de de `Stack[S]` se e somente se `S = T`. Como isso pode ser bastante restritivo, Scala oferece um [mecanismo de anotação de parâmetro de tipo](variances.html) para controlar o comportamento de subtipo de tipos genéricos._ \ No newline at end of file diff --git a/pt-br/tutorials/tour/higher-order-functions.md b/pt-br/tutorials/tour/higher-order-functions.md index c0d8913b07..2466257a99 100644 --- a/pt-br/tutorials/tour/higher-order-functions.md +++ b/pt-br/tutorials/tour/higher-order-functions.md @@ -11,7 +11,7 @@ tutorial-previous: anonymous-function-syntax language: pt-br --- -Scala permite definir funções de ordem superior. Tais funções _recebem outras como parâmetros_, as quais _o resultado é outra função_. Por exemplo, a função `apply` recebe outra função `f` e um valor `v` então aplica a função `f` em`v`: +Scala permite definir funções de ordem superior. Tais funções _recebem outras funções como parâmetros_, ou _resultam em uma função_. Por exemplo, a função `apply` recebe outra função `f` e um valor `v` então aplica a função `f` em`v`: ```tut def apply(f: Int => String, v: Int) = f(v) diff --git a/pt-br/tutorials/tour/implicit-conversions.md b/pt-br/tutorials/tour/implicit-conversions.md index 4ac1a31f18..22f6a97d4b 100644 --- a/pt-br/tutorials/tour/implicit-conversions.md +++ b/pt-br/tutorials/tour/implicit-conversions.md @@ -15,7 +15,7 @@ Uma conversão implícita do tipo `S` para o tipo `T` é definida por um valor i As conversões implícitas são aplicadas em duas situações: -* Se uma expressão `e` for do tipo`S` e `S` não estiver em conformidade com o tipo esperado `T` da expressão. +* Se uma expressão `e` for do tipo `S` e `S` não estiver em conformidade com o tipo esperado `T` da expressão. * Em uma seleção `e.m` com `e` do tipo `T`, se o seletor `m` não representar um membro de `T`. No primeiro caso, é procurada uma conversão `c` que seja aplicável a `e` e cujo tipo de resultado esteja em conformidade com `T`. diff --git a/pt-br/tutorials/tour/implicit-parameters.md b/pt-br/tutorials/tour/implicit-parameters.md index 45112f616b..9a668ca233 100644 --- a/pt-br/tutorials/tour/implicit-parameters.md +++ b/pt-br/tutorials/tour/implicit-parameters.md @@ -11,15 +11,15 @@ tutorial-previous: explicitly-typed-self-references language: pt-br --- -Um método com _parâmetros implícitos_ pode ser aplicado a argumentos como um método normal. Neste caso, o rótulo implícito não tem efeito. No entanto, se esse método faltar argumentos para os parâmetros implícitos declarados, tais argumentos serão automaticamente fornecidos. +Um método com _parâmetros implícitos_ pode ser aplicado a argumentos como um método normal. Neste caso, o rótulo implícito não tem efeito. No entanto, se faltarem argumentos para os parâmetros implícitos declarados, tais argumentos serão automaticamente fornecidos. Os argumentos reais que são elegíveis para serem passados para um parâmetro implícito se dividem em duas categorias: * Primeira, são elegíveis todos os identificadores x que podem ser acessados no ponto da chamada do método sem um prefixo e que denotam uma definição implícita ou um parâmetro implícito. -* Segunda, são elegíveis também todos os membros dos módulos acompanhates do tipo do parâmetro implícito que são rotulados marcados como `implicit`. +* Segunda, são elegíveis também todos os membros dos módulos acompanhantes do tipo do parâmetro implícito que são rotulados como `implicit`. -No exemplo a seguir, definimos um método `sum` que calcula a soma de uma lista de elementos usando as operações `add` e `unit` do monóide. Observe que valores implícitos não podem ser de nível superior, eles precisam ser membros de um modelo. +No exemplo a seguir, definimos um método `sum` que calcula a soma de uma lista de elementos usando as operações `add` e `unit` do monoide. Observe que valores implícitos não podem ser *top-level*, eles precisam ser membros de um modelo. ```tut /** Este exemplo usa uma estrutura da álgebra abstrata para mostrar como funcionam os parâmetros implícitos. Um semigrupo é uma estrutura algébrica em um conjunto A com uma operação (associativa), chamada add, que combina um par de A's e retorna um outro A. */ diff --git a/pt-br/tutorials/tour/inner-classes.md b/pt-br/tutorials/tour/inner-classes.md index b29c7c41e7..aab5e5edfc 100644 --- a/pt-br/tutorials/tour/inner-classes.md +++ b/pt-br/tutorials/tour/inner-classes.md @@ -11,7 +11,7 @@ tutorial-previous: lower-type-bounds language: pt-br --- -Em Scala é possível declarar classes que tenham outras classes como membros. Em constrate com a linguagenm Java, onde classes internas são membros da classe em que foram declaradas, em Scala as classes internas são ligadas ao objeto exterior. Para ilustrar essa diferença, rapidamente esboçamos a implementação de grafo como um tipo de dados: +Em Scala é possível declarar classes que tenham outras classes como membros. Em contraste com a linguagenm Java, onde classes internas são membros da classe em que foram declaradas, em Scala as classes internas são ligadas ao objeto exterior. Para ilustrar essa diferença, rapidamente esboçamos a implementação de grafo como um tipo de dados: ```tut class Graph { @@ -73,7 +73,7 @@ object IllegalGraphTest extends App { } ``` -Observe que em Java a última linha no programa do exemplo anterior é válida. Para nós de ambos os grafos, o Java atribuiria o mesmo tipo `Graph.Node`; isto é, `Node` é prefixado com a classe `Graph`. Em Scala, esse tipo também pode ser expresso, e é escrito `Graph#Node`. Se quisermos ser capazes de conectar nós de diferentes grafos, temos que mudar a definição inicial da nossa implementação do grafo da seguinte maneira: +Observe que em Java a última linha no programa do exemplo anterior é válida. Para nós de ambos os grafos, Java atribuiria o mesmo tipo `Graph.Node`; isto é, `Node` é prefixado com a classe `Graph`. Em Scala, esse tipo também pode ser expresso, e é escrito `Graph#Node`. Se quisermos ser capazes de conectar nós de diferentes grafos, temos que mudar a definição inicial da nossa implementação do grafo da seguinte maneira: ```tut class Graph { diff --git a/pt-br/tutorials/tour/local-type-inference.md b/pt-br/tutorials/tour/local-type-inference.md index d0d40a0017..b84b767930 100644 --- a/pt-br/tutorials/tour/local-type-inference.md +++ b/pt-br/tutorials/tour/local-type-inference.md @@ -11,7 +11,7 @@ tutorial-previous: polymorphic-methods language: pt-br --- -Scala tem um mecanismo nativo de inferência de tipos que permite ao programador omitir certas anotações. Por exemplo, muitas vezes não é necessário especificar o tipo de uma variável, uma vez que o compilador pode deduzir o tipo a partir da expressão de inicialização da variável. Também os tipos de retorno de métodos podem muitas vezes ser omitidos, uma vez que correspondem ao tipo do corpo do método, que é inferido pelo compilador. +Scala tem um mecanismo nativo de inferência de tipos que permite ao programador omitir certas anotações. Por exemplo, muitas vezes não é necessário especificar o tipo de uma variável, uma vez que o compilador pode deduzir o tipo a partir da expressão de inicialização da variável. Os tipos de retorno de métodos também podem muitas vezes ser omitidos, uma vez que correspondem ao tipo do corpo do método, que é inferido pelo compilador. Por exemplo: diff --git a/pt-br/tutorials/tour/lower-type-bounds.md b/pt-br/tutorials/tour/lower-type-bounds.md index 4ac7a9bbb2..e1e65d45dd 100644 --- a/pt-br/tutorials/tour/lower-type-bounds.md +++ b/pt-br/tutorials/tour/lower-type-bounds.md @@ -11,7 +11,7 @@ tutorial-previous: upper-type-bounds language: pt-br --- -Enquanto o [limitante superior de tipos](upper-type-bounds.html) limita um tipo a um subtipo de outro tipo, O *limitante inferior de tipos* declara um tipo para ser supertipo de outro tipo. O termo `T>: A` expressa que o parâmetro de tipo `T` ou tipo abstracto `T` refere-se a um supertipo do tipo `A`. +Enquanto o [limitante superior de tipos](upper-type-bounds.html) limita um tipo a um subtipo de outro tipo, o *limitante inferior de tipos* declara um tipo para ser supertipo de outro tipo. O termo `T>: A` expressa que o parâmetro de tipo `T` ou tipo abstracto `T` refere-se a um supertipo do tipo `A`. Aqui está um exemplo onde isso é útil: diff --git a/pt-br/tutorials/tour/pattern-matching.md b/pt-br/tutorials/tour/pattern-matching.md index e0898bd23f..3216b04b51 100644 --- a/pt-br/tutorials/tour/pattern-matching.md +++ b/pt-br/tutorials/tour/pattern-matching.md @@ -14,7 +14,7 @@ language: pt-br _Nota de tradução: A palavra cujo o significado melhor corresponde a palavra `match` em inglês seria `correspondência`. Também podemos entender que `match` é como "coincidir" ou "concordar" com algo._ -Scala possui mecanismo de correspondência de padrão embutido. Isso permite realizar o match de qualquer tipo de dados any sort of data com a política de primeiro match. +Scala possui mecanismo de correspondência de padrão embutido. Isso permite realizar o match de qualquer tipo de dados com a política de primeiro match. Aqui um pequeno exemplo que mostrar como realizar o match de um número inteiro: ```tut diff --git a/pt-br/tutorials/tour/polymorphic-methods.md b/pt-br/tutorials/tour/polymorphic-methods.md index 161f02393f..2b48dc8dfc 100644 --- a/pt-br/tutorials/tour/polymorphic-methods.md +++ b/pt-br/tutorials/tour/polymorphic-methods.md @@ -12,7 +12,7 @@ tutorial-previous: implicit-conversions language: pt-br --- -Os métodos em Scala podem ser parametrizados com valores e tipos. Como no nível de classe, os parâmetros de valor são declarados entre de parênteses, enquanto os parâmetros de tipo são declarados entre colchetes. +Os métodos em Scala podem ser parametrizados com valores e tipos. Como no nível de classe, os parâmetros de valor são declarados entre parênteses, enquanto os parâmetros de tipo são declarados entre colchetes. Por exemplo: diff --git a/pt-br/tutorials/tour/sequence-comprehensions.md b/pt-br/tutorials/tour/sequence-comprehensions.md index 77250e01ad..026298ca08 100644 --- a/pt-br/tutorials/tour/sequence-comprehensions.md +++ b/pt-br/tutorials/tour/sequence-comprehensions.md @@ -23,7 +23,7 @@ object ComprehensionTest1 extends App { } ``` -A função for-expression in introduz uma nova variável `i` do tipo `Int`, que é subsequentemente associada a todos os valores da lista `List (de, de + 1, ..., ate - 1)`. A restrição `if i% 2 == 0` ignora todos os números ímpares para que o corpo (que só consiste na expressão i) seja avaliado somente para números pares. Consequentemente, toda a expressão `for` retorna uma lista de números pares. +A função for-expression introduz uma nova variável `i` do tipo `Int`, que é subsequentemente associada a todos os valores da lista `List (de, de + 1, ..., ate - 1)`. A restrição `if i% 2 == 0` ignora todos os números ímpares para que o corpo (que só consiste na expressão i) seja avaliado somente para números pares. Consequentemente, toda a expressão `for` retorna uma lista de números pares. O programa produz a seguinte saída: diff --git a/pt-br/tutorials/tour/singleton-objects.md b/pt-br/tutorials/tour/singleton-objects.md index a83c2754c0..a615727d74 100644 --- a/pt-br/tutorials/tour/singleton-objects.md +++ b/pt-br/tutorials/tour/singleton-objects.md @@ -32,7 +32,7 @@ Um objeto singleton pode estender classes e traits. Já uma [classe clase](case- A maioria dos objetos singleton não estão sozinhos, mas sim associados com uma classe de mesmo nome. O “objeto singleton de mesmo nome” que uma classe case, acima mencionado, é um exemplo disso. Quando isso acontece, o objeto singleton é chamado de *objeto acompanhante* de uma classe e, a classe é chamada de *classe acompanhante* de um objeto. -[Scaladoc](https://wiki.scala-lang.org/display/SW/Introduction) possui um um recurso espacial para navegar entre classes e seus acompanhantes: se o grande círculo contendo “C” ou “O” possui sua extremidade superior dobrada para baixo, você pode clicar no círculo para acessar o acompanhante. +[Scaladoc](https://wiki.scala-lang.org/display/SW/Introduction) possui um recurso especial para navegar entre classes e seus acompanhantes: se o grande círculo contendo “C” ou “O” possui sua extremidade superior dobrada para baixo, você pode clicar no círculo para acessar o acompanhante. Se houver um objeto acompanhante para uma classe, ambos devem ser definidos no mesmo aquivo fonte. Por exemplo: @@ -47,11 +47,11 @@ object IntPair { } ``` -É comum ver instâncias de classes de tipo como [valores implicit](implicit-parameters.html), como `ipord` acima, definido no objeto acompanhante quando se segue o padrão da classe de tipo. Isso ocorre porque os membros do objeto acompanhante são incluídos por padrão na busca de valores implicitos. +É comum ver instâncias de classes de tipo como [valores implícitos](implicit-parameters.html), como `ipord` acima, definido no objeto acompanhante quando se segue o padrão da *typeclass*. Isso ocorre porque os membros do objeto acompanhante são incluídos por padrão na busca de valores implícitos. ## Nota para programadores Java ## -`static` não é uma palavra-chava em Scala. Ao invés disso, todos os membros que devem ser estáticos, incluindo classes, devem ser declarados no objeto singleton. Eles podem ser referenciados com a mesma sintaxe, They can be referred to with the same syntax, importados gradativamente ou como um grupo, e assim por diante. +`static` não é uma palavra-chave em Scala. Ao invés disso, todos os membros que devem ser estáticos, incluindo classes, devem ser declarados no objeto singleton. Eles podem ser referenciados com a mesma sintaxe, importados gradativamente ou como um grupo, e assim por diante. Frequentemente, os programadores Java definem membros estáticos, talvez `private`, como auxiliares de implementação para seus membros de instância. Estes são movidos para o acompanhante também; Um padrão comum é importar os membros do objeto acompanhante na classe, da seguinte forma: ``` @@ -68,6 +68,6 @@ object X { Isso demonstra outra característica: no contexto `private`, as classes e seus acompanhantes são amigos. `object X` pode acessar membro privados da `class X`, e vice versa. Para fazer com que um membro seja *realmente* para um ou outro, utilize `private[this]`. -Para conveniência Java, métodos, incluindo `var`s e `val`s, definidos diretamente em um objeto singleton também têm um método estático definido na classe acompanhante, chamado *encaminhadores estáticos*. Outros membros são acessíveis por meio de campos estáticos `X$.MODULE$` para o `object X`. +Por uma melhor interoperabilidade com Java, métodos, incluindo `var`s e `val`s, definidos diretamente em um objeto singleton também têm um método estático definido na classe acompanhante, chamado *encaminhadores estáticos*. Outros membros são acessíveis por meio de campos estáticos `X$.MODULE$` para o `object X`. -Se você mover tudo para um objeto acompanhante e descobrir que tudo o que resta é uma classe que você não deseja que seja instanciada, exclua simplesmente a classe. Encaminhadores estáticos ainda serão criados. \ No newline at end of file +Se você mover tudo para um objeto acompanhante e descobrir que tudo o que resta é uma classe que você não deseja que seja instanciada, simplesmente exclua a classe. Encaminhadores estáticos ainda serão criados. \ No newline at end of file diff --git a/pt-br/tutorials/tour/tour-of-scala.md b/pt-br/tutorials/tour/tour-of-scala.md index e4f82bddb0..0b4dca5e32 100644 --- a/pt-br/tutorials/tour/tour-of-scala.md +++ b/pt-br/tutorials/tour/tour-of-scala.md @@ -11,15 +11,15 @@ tutorial-next: unified-types language: pt-br --- -Scala é uma linguagem de programação moderna e multi-paradigma desenvolvida para expressar padrões de programação comuns em uma forma concisa, elegante e com tipagem segura. Integra fácilmente características de linguagens orientadas a objetos e funcional. +Scala é uma linguagem de programação moderna e multi-paradigma desenvolvida para expressar padrões de programação comuns em uma forma concisa, elegante e com tipagem segura. Integra facilmente características de linguagens orientadas a objetos e funcional. ## Scala é orienta a objetos ## Scala é uma linguagem puramente orientada a objetos no sentido que [todo valor é um objeto](unified-types.html). Tipos e comportamentos de objetos são descritos por [classes](classes.html) e [traits](traits.html). Classes são estendidas por subclasses e por um flexível mecanismo [de composição mesclada](mixin-class-composition.html) como uma alternativa para herança múltipla. -## Scala is functional ## +## Scala é funcional ## Scala é também uma linguagem funcional no sentido que [toda função é um valor](unified-types.html). Scala fornece uma [sintaxe leve](anonymous-function-syntax.html) para definir funções anônimas, suporta [funções de primeira ordem](higher-order-functions.html), permite funções [aninhadas](nested-functions.html), e suporta [currying](currying.html). As [case classes](case-classes.html) da linguagem Scala e o suporte embutido para [correspondência de padrões](pattern-matching.html) modelam tipos algébricos utilizados em muitas linguagens de programação funcional. [Objetos Singleton](singleton-objects.html) fornecem uma alternativa conveniente para agrupar funções que não são membros de uma classe. -Além disso, a noção de correspondência de padrões em scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [objetos extratores](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. +Além disso, a noção de correspondência de padrões em Scala se estende naturalmente ao [processamento de dados de um XML](xml-processing.html) com a ajuda de [expressões regulares](regular-expression-patterns.html), por meio de uma extensão via [objetos extratores](extractor-objects.html). Nesse contexto, [compreensões de sequência](sequence-comprehensions.html) são úteis para formular consultas. Essas funcionalidades tornam Scala ideal para desenvolver aplicações como serviços web. ## Scala é estaticamente tipada ## Scala é equipada com um expressivo sistema de tipos que reforça estaticamente que abstrações são utilizadas de uma forma segura e coerente. Particularmente, o sistema de tipos suporta: @@ -37,7 +37,7 @@ Um [mecanismo de inferência de tipo local](local-type-inference.html) se encarr ## Scala é estensível ## -Na prática, o desenvolvimento de uma aplicaçãoes de um determinado domínio geralmente requer uma linguagem de domínio específico. Scala fornece uma combinação única de mecanismos de linguagem que facilitam a adição suave de novas construções de linguagem na forma de bibliotecas: +Na prática, o desenvolvimento de aplicações de um determinado domínio geralmente requer uma linguagem de domínio específico. Scala fornece uma combinação única de mecanismos de linguagem que facilitam a adição suave de novas construções de linguagem na forma de bibliotecas: * qualquer método pode ser utilizado como um [operador infix ou postfix](operators.html) * [closures são construídas automaticamente dependendo do tipo esperado](automatic-closures.html) (tipo alvo). diff --git a/pt-br/tutorials/tour/unified-types.md b/pt-br/tutorials/tour/unified-types.md index 809305dcf1..29dfa88ba9 100644 --- a/pt-br/tutorials/tour/unified-types.md +++ b/pt-br/tutorials/tour/unified-types.md @@ -36,7 +36,7 @@ object TiposUnificados extends App { } ``` -O programa declare uma aplicação chamada `TiposUnificados` em forma de um [objeto Singleton](singleton-objects.html) que estende `App`. A aplicação define uma variável local `set` que se refere à uma instância da classe `LinkedHashSet[Any]`. As demais linhas adicionam vários elementos à variável set. Tais elementos devem estar em conformidade com o tipo `Any` que foi declarado para o set. Por fim, são escritas as representações em string de todos os elementos adicionados ao set. +O programa declara uma aplicação chamada `TiposUnificados` em forma de um [objeto Singleton](singleton-objects.html) que estende `App`. A aplicação define uma variável local `set` que se refere a uma instância da classe `LinkedHashSet[Any]`. As demais linhas adicionam vários elementos à variável set. Tais elementos devem estar em conformidade com o tipo `Any` que foi declarado para o set. Por fim, são escritas as representações em string de todos os elementos adicionados ao set. Escrita de saída do programa: diff --git a/pt-br/tutorials/tour/upper-type-bounds.md b/pt-br/tutorials/tour/upper-type-bounds.md index f8b5deda11..ed8926d388 100644 --- a/pt-br/tutorials/tour/upper-type-bounds.md +++ b/pt-br/tutorials/tour/upper-type-bounds.md @@ -11,7 +11,7 @@ tutorial-previous: variances language: pt-br --- -Em scala, [parâmetros de tipos](generic-classes.html) e [tipos abstratos](abstract-types.html) podem ser restringidos por um limitante de tipo. Tal limitante de tipo limita os valores concretos de uma variável de tipo e possivelmente revela mais informações sobre os membros de determinados tipos. Um _limitante superiror de tipos_ `T <: A` declare que a variável tipo `T` refere-se a um subtipo do tipo `A`. +Em Scala, [parâmetros de tipos](generic-classes.html) e [tipos abstratos](abstract-types.html) podem ser restringidos por um limitante de tipo. Tal limitante de tipo limita os valores concretos de uma variável de tipo e possivelmente revela mais informações sobre os membros de determinados tipos. Um _limitante superiror de tipos_ `T <: A` declare que a variável tipo `T` refere-se a um subtipo do tipo `A`. Aqui um exemplo que demonstra um limitante superior de tipo para um parâmetro de tipo da classe `Cage`: ```tut