summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--fr-fr/scala.html.markdown9
-rw-r--r--perl6.html.markdown91
-rw-r--r--pt-pt/scala-pt.html.markdown651
-rw-r--r--scala.html.markdown12
4 files changed, 709 insertions, 54 deletions
diff --git a/fr-fr/scala.html.markdown b/fr-fr/scala.html.markdown
index a43edf16..c6d06361 100644
--- a/fr-fr/scala.html.markdown
+++ b/fr-fr/scala.html.markdown
@@ -208,6 +208,7 @@ sSquared.reduce (_+_)
// La fonction filter prend un prédicat (une fonction de type A -> Booléen) et
// sélectionne tous les éléments qui satisfont ce prédicat
List(1, 2, 3) filter (_ > 2) // List(3)
+case class Person(name: String, age: Int)
List(
Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30)
@@ -217,6 +218,7 @@ List(
// Scala a une méthode foreach définie pour certaines collections
// qui prend en argument une fonction renvoyant Unit (une méthode void)
+val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
aListOfNumbers foreach (x => println(x))
aListOfNumbers foreach println
@@ -271,11 +273,12 @@ i // Montre la valeur de i. Notez que while est une boucle au sens classique.
// mais utiliser des combinateurs et des compréhensions comme ci-dessus est plus
// facile pour comprendre et pour faire la parallélisation
+i = 0
// La boucle do while
do {
println("x is still less then 10");
- x += 1
-} while (x < 10)
+ i += 1
+} while (i < 10)
// La récursivité est un moyen idiomatique de faire une chose répétitive en Scala.
@@ -370,7 +373,7 @@ val email(user, domain) = "henry@zkpr.com"
"Les chaînes de caractères Scala sont entourées de doubles guillements"
'a' // Un caractère de Scala
-'Les simples guillemets n'existent pas en Scala // Erreur
+// 'Les simples guillemets n'existent pas en Scala' // Erreur
"Les chaînes de caractères possèdent les méthodes usuelles de Java".length
"Il y a aussi quelques méthodes extra de Scala.".reverse
diff --git a/perl6.html.markdown b/perl6.html.markdown
index 43327edb..0f015b45 100644
--- a/perl6.html.markdown
+++ b/perl6.html.markdown
@@ -75,7 +75,7 @@ say @array; #=> a 6 b
# except they get "flattened" (hash context), removing duplicated keys.
my %hash = 1 => 2,
3 => 4;
-my %hash = autoquoted => "key", # keys get auto-quoted
+my %hash = foo => "bar", # keys get auto-quoted
"some other" => "value", # trailing commas are okay
;
my %hash = <key1 value1 key2 value2>; # you can also create a hash
@@ -96,7 +96,6 @@ say %hash<key2>; # If it's a string, you can actually use <>
# (`{key1}` doesn't work, as Perl6 doesn't have barewords)
## * Subs (subroutines, or functions in most other languages).
-# Stored in variable, they use `&`.
sub say-hello { say "Hello, world" }
sub say-hello-to(Str $name) { # You can provide the type of an argument
@@ -107,8 +106,8 @@ sub say-hello-to(Str $name) { # You can provide the type of an argument
## It can also have optional arguments:
sub with-optional($arg?) { # the "?" marks the argument optional
- say "I might return `(Any)` if I don't have an argument passed,
- or I'll return my argument";
+ say "I might return `(Any)` (Perl's "null"-like value) if I don't have
+ an argument passed, or I'll return my argument";
$arg;
}
with-optional; # returns Any
@@ -125,7 +124,7 @@ hello-to('You'); #=> Hello, You !
## You can also, by using a syntax akin to the one of hashes (yay unified syntax !),
## pass *named* arguments to a `sub`.
-# They're optional, and will default to "Any" (Perl's "null"-like value).
+# They're optional, and will default to "Any".
sub with-named($normal-arg, :$named) {
say $normal-arg + $named;
}
@@ -162,7 +161,7 @@ named-def; #=> 5
named-def(def => 15); #=> 15
# Since you can omit parenthesis to call a function with no arguments,
-# you need "&" in the name to capture `say-hello`.
+# you need "&" in the name to store `say-hello` in a variable.
my &s = &say-hello;
my &other-s = sub { say "Anonymous function !" }
@@ -173,8 +172,8 @@ sub as-many($head, *@rest) { # `*@` (slurpy) will basically "take everything els
say @rest.join(' / ') ~ " !";
}
say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
- # Note that the splat did not consume
- # the parameter before.
+ # Note that the splat (the *) did not
+ # consume the parameter before.
## You can call a function with an array using the
# "argument list flattening" operator `|`
@@ -380,7 +379,9 @@ say join(' ', @array[-> $n { 15..$n }]);
# You can use that in most places you'd expect, even assigning to an array
my @numbers = ^20;
-my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99
+
+# Here numbers increase by "6"; more on `...` operator later.
+my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99;
@numbers[5..*] = 3, 9 ... *; # even though the sequence is infinite,
# only the 15 needed values will be calculated.
say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
@@ -525,7 +526,7 @@ map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`)
# The constructs for declaring types are "class", "role",
# which you'll see later.
-# For now, let us examinate "subset":
+# For now, let us examine "subset":
# a "subset" is a "sub-type" with additional checks.
# For example: "a very big integer is an Int that's greater than 500"
# You can specify the type you're subtyping (by default, Any),
@@ -608,27 +609,26 @@ sub foo {
bar(); # call `bar` in-place
}
sub bar {
- say $*foo; # `$*a` will be looked in the call stack, and find `foo`'s,
+ say $*foo; # `$*foo` will be looked in the call stack, and find `foo`'s,
# even though the blocks aren't nested (they're call-nested).
#=> 1
}
### Object Model
-## Perl 6 has a quite comprehensive object model
# You declare a class with the keyword `class`, fields with `has`,
-# methods with `method`. Every field to private, and is named `$!attr`,
-# but you have `$.` to get a public (immutable) accessor along with it.
-# (using `$.` is like using `$!` plus a `method` with the same name)
+# methods with `method`. Every attribute that is private is named `$!attr`.
+# Immutable public attributes are named `$.attr`
+# (you can make them mutable with `is rw`)
-# (Perl 6's object model ("SixModel") is very flexible,
+# Perl 6's object model ("SixModel") is very flexible,
# and allows you to dynamically add methods, change semantics, etc ...
# (this will not be covered here, and you should refer to the Synopsis).
class A {
has $.field; # `$.field` is immutable.
# From inside the class, use `$!field` to modify it.
- has $.other-field is rw; # You can obviously mark a public field `rw`.
+ has $.other-field is rw; # You can mark a public attribute `rw`.
has Int $!private-field = 10;
method get-value {
@@ -656,7 +656,6 @@ $a.other-field = 10; # This, however, works, because the public field
# is mutable (`rw`).
## Perl 6 also has inheritance (along with multiple inheritance)
-# (though considered a misfeature by many)
class A {
has $.val;
@@ -751,7 +750,7 @@ fail "foo"; # We're not trying to access the value, so no problem.
try {
fail "foo";
CATCH {
- default { say "It threw because we try to get the fail's value!" }
+ default { say "It threw because we tried to get the fail's value!" }
}
}
@@ -763,7 +762,7 @@ try {
### Packages
# Packages are a way to reuse code. Packages are like "namespaces", and any
# element of the six model (`module`, `role`, `class`, `grammar`, `subset`
-# and `enum`) are actually packages. (Packages are the lowest common denomitor)
+# and `enum`) are actually packages. (Packages are the lowest common denominator)
# Packages are important - especially as Perl is well-known for CPAN,
# the Comprehensive Perl Archive Network.
# You usually don't use packages directly: you use `class Package::Name::Here;`,
@@ -773,7 +772,7 @@ module Hello::World { # Bracketed form
# that can be redeclared as something else later.
# ... declarations here ...
}
-module Parse::Text; # file-scoped form
+unit module Parse::Text; # file-scoped form
grammar Parse::Text::Grammar { # A grammar is a package, which you could `use`
}
@@ -797,10 +796,8 @@ my $actions = JSON::Tiny::Actions.new;
# You've already seen `my` and `has`, we'll now explore the others.
## * `our` (happens at `INIT` time -- see "Phasers" below)
-# Along with `my`, there are several others declarators you can use.
-# The first one you'll want for the previous part is `our`.
+# It's like `my`, but it also creates a package variable.
# (All packagish things (`class`, `role`, etc) are `our` by default)
-# it's like `my`, but it also creates a package variable:
module Foo::Bar {
our $n = 1; # note: you can't put a type constraint on an `our` variable
our sub inc {
@@ -829,7 +826,7 @@ constant why-not = 5, 15 ... *;
say why-not[^5]; #=> 5 15 25 35 45
## * `state` (happens at run time, but only once)
-# State variables are only executed one time
+# State variables are only initialized one time
# (they exist in other langages such as C as `static`)
sub fixed-rand {
state $val = rand;
@@ -862,7 +859,7 @@ for ^5 -> $a {
## * Compile-time phasers
BEGIN { say "[*] Runs at compile time, as soon as possible, only once" }
-CHECK { say "[*] Runs at compile time, instead as late as possible, only once" }
+CHECK { say "[*] Runs at compile time, as late as possible, only once" }
## * Run-time phasers
INIT { say "[*] Runs at run time, as soon as possible, only once" }
@@ -870,10 +867,13 @@ END { say "Runs at run time, as late as possible, only once" }
## * Block phasers
ENTER { say "[*] Runs everytime you enter a block, repeats on loop blocks" }
-LEAVE { say "Runs everytime you leave a block, even when an exception happened. Repeats on loop blocks." }
+LEAVE { say "Runs everytime you leave a block, even when an exception
+ happened. Repeats on loop blocks." }
-PRE { say "Asserts a precondition at every block entry, before ENTER (especially useful for loops)" }
-POST { say "Asserts a postcondition at every block exit, after LEAVE (especially useful for loops)" }
+PRE { say "Asserts a precondition at every block entry,
+ before ENTER (especially useful for loops)" }
+POST { say "Asserts a postcondition at every block exit,
+ after LEAVE (especially useful for loops)" }
## * Block/exceptions phasers
sub {
@@ -891,12 +891,12 @@ for ^5 {
## * Role/class phasers
COMPOSE { "When a role is composed into a class. /!\ NOT YET IMPLEMENTED" }
-# They allow for cute trick or clever code ...:
-say "This code took " ~ (time - CHECK time) ~ "s to run";
+# They allow for cute tricks or clever code ...:
+say "This code took " ~ (time - CHECK time) ~ "s to compile";
# ... or clever organization:
sub do-db-stuff {
- ENTER $db.start-transaction; # New transaction everytime we enter the sub
+ $db.start-transaction; # start a new transaction
KEEP $db.commit; # commit the transaction if all went well
UNDO $db.rollback; # or rollback if all hell broke loose
}
@@ -1020,7 +1020,7 @@ sub circumfix:<[ ]>(Int $n) {
$n ** $n
}
say [5]; #=> 3125
- # circumfix is around. Again, not whitespace.
+ # circumfix is around. Again, no whitespace.
sub postcircumfix:<{ }>(Str $s, Int $idx) {
# post-circumfix is
@@ -1052,9 +1052,9 @@ postcircumfix:<{ }>(%h, $key, :delete); # (you can call operators like that)
# Basically, they're operators that apply another operator.
## * Reduce meta-operator
-# It's a prefix meta-operator that takes a binary functions and
+# It's a prefix meta-operator that takes a binary function and
# one or many lists. If it doesn't get passed any argument,
-# it either return a "default value" for this operator
+# it either returns a "default value" for this operator
# (a meaningless value) or `Any` if there's none (examples below).
#
# Otherwise, it pops an element from the list(s) one at a time, and applies
@@ -1089,7 +1089,7 @@ say [[&add]] 1, 2, 3; #=> 6
# This one is an infix meta-operator than also can be used as a "normal" operator.
# It takes an optional binary function (by default, it just creates a pair),
# and will pop one value off of each array and call its binary function on these
-# until it runs out of elements. It runs the an array with all these new elements.
+# until it runs out of elements. It returns an array with all of these new elements.
(1, 2) Z (3, 4); # ((1, 3), (2, 4)), since by default, the function makes an array
1..3 Z+ 4..6; # (5, 7, 9), using the custom infix:<+> function
@@ -1109,8 +1109,7 @@ say [[&add]] 1, 2, 3; #=> 6
# (and might include a closure), and on the right, a value or the predicate
# that says when to stop (or Whatever for a lazy infinite list).
my @list = 1, 2, 3 ... 10; # basic deducing
-#my @list = 1, 3, 6 ... 10; # this throws you into an infinite loop,
- # because Perl 6 can't figure out the end
+#my @list = 1, 3, 6 ... 10; # this dies because Perl 6 can't figure out the end
my @list = 1, 2, 3 ...^ 10; # as with ranges, you can exclude the last element
# (the iteration when the predicate matches).
my @list = 1, 3, 9 ... * > 30; # you can use a predicate
@@ -1222,7 +1221,7 @@ so 'abbbbbbc' ~~ / a b ** 3..* c /; # `True` (infinite ranges are okay)
# they use a more perl6-ish syntax:
say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa'
# You can use ranges:
-say 'aeiou' ~~ / a <[ e..w ]> /; #=> 'aeiou'
+say 'aeiou' ~~ / a <[ e..w ]> /; #=> 'ae'
# Just like in normal regexes, if you want to use a special character, escape it
# (the last one is escaping a space)
say 'he-he !' ~~ / 'he-' <[ a..z \! \ ]> + /; #=> 'he-he !'
@@ -1244,7 +1243,7 @@ so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (the + doesn't replace the left
so 'abc' ~~ / a [ b ] c /; # `True`. The grouping does pretty much nothing
so 'fooABCABCbar' ~~ / foo [ A B C ] + bar /;
# The previous line returns `True`.
-# We match the "abc" 1 or more time (the `+` was applied to the group).
+# We match the "ABC" 1 or more time (the `+` was applied to the group).
# But this does not go far enough, because we can't actually get back what
# we matched.
@@ -1287,10 +1286,12 @@ say $/[0][0].Str; #=> ~
# This stems from a very simple fact: `$/` does not contain strings, integers or arrays,
# it only contains match objects. These contain the `.list`, `.hash` and `.Str` methods.
-# (but you can also just use `match<key>` for hash access and `match[idx]` for array access)
+# (but you can also just use `match<key>` for hash access
+# and `match[idx]` for array access)
say $/[0].list.perl; #=> (Match.new(...),).list
- # We can see it's a list of Match objects. Those contain a bunch of infos:
- # where the match started/ended, the "ast" (see actions later), etc.
+ # We can see it's a list of Match objects. Those contain
+ # a bunch of infos: where the match started/ended,
+ # the "ast" (see actions later), etc.
# You'll see named capture below with grammars.
## Alternatives - the `or` of regexps
@@ -1328,7 +1329,7 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviously enough ...
### Extra: the MAIN subroutime
# The `MAIN` subroutine is called when you run a Perl 6 file directly.
-# It's very powerful, because Perl 6 actually parses the argument
+# It's very powerful, because Perl 6 actually parses the arguments
# and pass them as such to the sub. It also handles named argument (`--foo`)
# and will even go as far as to autogenerate a `--help`
sub MAIN($name) { say "Hello, $name !" }
@@ -1346,7 +1347,7 @@ multi MAIN('add', $key, $value, Bool :$replace) { ... }
multi MAIN('remove', $key) { ... }
multi MAIN('import', File, Str :$as) { ... } # omitting parameter name
# This produces:
-# $ perl 6 cli.pl
+# $ perl6 cli.pl
# Usage:
# t.pl [--replace] add <key> <value>
# t.pl remove <key>
diff --git a/pt-pt/scala-pt.html.markdown b/pt-pt/scala-pt.html.markdown
new file mode 100644
index 00000000..a4c1c02b
--- /dev/null
+++ b/pt-pt/scala-pt.html.markdown
@@ -0,0 +1,651 @@
+---
+language: Scala
+filename: learnscala-pt.scala
+contributors:
+ - ["George Petrov", "http://github.com/petrovg"]
+ - ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Ha-Duong Nguyen", "http://reference-error.org"]
+translators:
+ - ["João Costa", "http://joaocosta.eu"]
+lang: pt-pt
+---
+
+Scala - a linguagem escalável
+
+```scala
+
+/*
+ Prepare tudo:
+
+ 1) Faça Download do Scala - http://www.scala-lang.org/downloads
+ 2) Faça unzip/untar para onde preferir e coloque o subdirectório `bin` na
+ variável de ambiente `PATH`
+ 3) Inicie a REPL de Scala correndo o comando `scala`. Deve aparecer:
+
+ scala>
+
+ Isto é chamado de REPL (Read-Eval-Print Loop / Lê-Avalia-Imprime Repete).
+ Pode escrever qualquer expressão de Scala e o resultado será imprimido.
+ Vamos mostrar ficheiros de Scala mais à frente neste tutorial mas, para já,
+ vamos começar com os básicos.
+
+*/
+
+
+/////////////////////////////////////////////////
+// 1. Basicos
+/////////////////////////////////////////////////
+
+// Uma linha de comentários é marcada com duas barras
+
+/*
+ Comentários de multiplas linhas, como se pode ver neste exemplo, são assim.
+*/
+
+// Imprimir, forçando uma nova linha no final
+println("Hello world!")
+println(10)
+
+// Imprimir, sem forçar uma nova linha no final
+print("Hello world")
+
+// Valores são declarados com var ou val.
+// As declarações val são imutáveis, enquanto que vars são mutáveis.
+// A immutabilidade é uma propriedade geralmente vantajosa.
+val x = 10 // x é agora 10
+x = 20 // erro: reatribuição de um val
+var y = 10
+y = 20 // y é agora 12
+
+/*
+ Scala é uma linguagem estaticamente tipada, no entanto, nas declarações acima
+ não especificamos um tipo. Isto é devido a uma funcionalidade chamada
+ inferência de tipos. Na maior parte dos casos, o compilador de scala consegue
+ inferir qual o tipo de uma variável, pelo que não o temos de o declarar sempre.
+ Podemos declarar o tipo de uma variável da seguinte forma:
+*/
+val z: Int = 10
+val a: Double = 1.0
+
+// Note a conversão automática de Int para Double: o resultado é 10.0, não 10
+val b: Double = 10
+
+// Valores booleanos
+true
+false
+
+// Operações booleanas
+!true // false
+!false // true
+true == false // false
+10 > 5 // true
+
+// A matemática funciona da maneira habitual
+1 + 1 // 2
+2 - 1 // 1
+5 * 3 // 15
+6 / 2 // 3
+6 / 4 // 1
+6.0 / 4 // 1.5
+
+
+// Avaliar expressões na REPL dá o tipo e valor do resultado
+
+1 + 7
+
+/* A linha acima resulta em:
+
+ scala> 1 + 7
+ res29: Int = 8
+
+ Isto significa que o resultado de avaliar 1 + 7 é um objecto do tipo Int com
+ o valor 8.
+
+ Note que "res29" é um nome de uma variavel gerado sequencialmente para
+ armazenar os resultados das expressões que escreveu, por isso o resultado
+ pode ser ligeiramente diferente.
+*/
+
+"Strings em scala são rodeadas por aspas"
+'a' // Um caracter de Scala
+// 'Strings entre plicas não existem' <= Isto causa um erro
+
+// Strings tem os métodos de Java habituais definidos
+"olá mundo".length
+"olá mundo".substring(2, 6)
+"olá mundo".replace("á", "é")
+
+// Para além disso, também possuem métodos de Scala.
+// Ver: scala.collection.immutable.StringOps
+"olá mundo".take(5)
+"olá mundo".drop(5)
+
+// Interpolação de Strings: repare no prefixo "s"
+val n = 45
+s"Temos $n maçãs" // => "Temos 45 maçãs"
+
+// Expressões dentro de Strings interpoladas também são possíveis
+val a = Array(11, 9, 6)
+s"A minha segunda filha tem ${a(0) - a(2)} anos." // => "A minha segunda filha tem 5 anos."
+s"Temos o dobro de ${n / 2.0} em maçãs." // => "Temos o dobro de 22.5 em maçãs."
+s"Potência de 2: ${math.pow(2, 2)}" // => "Potência de 2: 4"
+
+// Strings interpoladas são formatadas com o prefixo "f"
+f"Potência de 5: ${math.pow(5, 2)}%1.0f" // "Potência de 5: 25"
+f"Raíz quadrada 122: ${math.sqrt(122)}%1.4f" // "Raíz quadrada de 122: 11.0454"
+
+// Strings prefixadas com "raw" ignoram caracteres especiais
+raw"Nova linha: \n. Retorno: \r." // => "Nova Linha: \n. Retorno: \r."
+
+// Alguns caracteres tem de ser "escapados", e.g. uma aspa dentro de uma string:
+"Esperaram fora do \"Rose and Crown\"" // => "Esperaram fora do "Rose and Crown""
+
+// Strings rodeadas por três aspas podem-se estender por varias linhas e conter aspas
+val html = """<form id="daform">
+ <p>Carrega aqui, Zé</p>
+ <input type="submit">
+ </form>"""
+
+
+/////////////////////////////////////////////////
+// 2. Funções
+/////////////////////////////////////////////////
+
+// Funções são definidas como:
+//
+// def nomeDaFuncao(args...): TipoDeRetorno = { corpo... }
+//
+// Se vem de linugagens mais tradicionais, repare na omissão da palavra
+// return keyword. Em Scala, a ultima expressão de um bloco é o seu
+// valor de retorno
+def somaQuadrados(x: Int, y: Int): Int = {
+ val x2 = x * x
+ val y2 = y * y
+ x2 + y2
+}
+
+// As { } podem ser omitidas se o corpo da função for apenas uma expressão:
+def somaQuadradosCurto(x: Int, y: Int): Int = x * x + y * y
+
+// A sintaxe para chamar funções deve ser familiar:
+somaQuadrados(3, 4) // => 25
+
+// Na maior parte dos casos (sendo funções recursivas a principal excepção), o
+// tipo de retorno da função pode ser omitido, sendo que a inferencia de tipos
+// é aplicada aos valores de retorno
+def quadrado(x: Int) = x * x // O compilador infere o tipo de retorno Int
+
+// Funções podem ter parâmetros por omissão:
+def somaComOmissão(x: Int, y: Int = 5) = x + y
+somaComOmissão(1, 2) // => 3
+somaComOmissão(1) // => 6
+
+
+// Funções anónimas são definidas da seguinte forma:
+(x: Int) => x * x
+
+// Ao contrário de defs, o tipo de input de funções anónimas pode ser omitido
+// se o contexto o tornar óbvio. Note que o tipo "Int => Int" representa uma
+// funão que recebe Int e retorna Int.
+val quadrado: Int => Int = x => x * x
+
+// Funcões anónimas são chamadas como funções normais:
+quadrado(10) // => 100
+
+// Se cada argumento de uma função anónima for usado apenas uma vez, existe
+// uma forma ainda mais curta de os definir. Estas funções anónumas são
+// extremamente comuns, como será visto na secção sobre estruturas de dados.
+val somaUm: Int => Int = _ + 1
+val somaEstranha: (Int, Int) => Int = (_ * 2 + _ * 3)
+
+somaUm(5) // => 6
+somaEstranha(2, 4) // => 16
+
+
+// O código return existe em Scala, mas apenas retorna do def mais interior
+// que o rodeia.
+// AVISO: Usar return em Scala deve ser evitado, pois facilmente leva a erros.
+// Não tem qualquer efeito em funções anónimas, por exemplo:
+def foo(x: Int): Int = {
+ val funcAnon: Int => Int = { z =>
+ if (z > 5)
+ return z // Esta linha faz com que z seja o retorno de foo!
+ else
+ z + 2 // Esta linha define o retorno de funcAnon
+ }
+ funcAnon(x) // Esta linha define o valor de retorno de foo
+}
+
+
+/////////////////////////////////////////////////
+// 3. Controlo de fluxo
+/////////////////////////////////////////////////
+
+1 to 5
+val r = 1 to 5
+r.foreach(println)
+
+r foreach println
+// NB: Scala é bastante brando no que toca a pontos e parentisis - estude as
+// regras separadamente. Isto permite escrever APIs e DSLs bastante legiveis
+
+(5 to 1 by -1) foreach (println)
+
+// Ciclos while
+var i = 0
+while (i < 10) { println("i " + i); i += 1 }
+
+while (i < 10) { println("i " + i); i += 1 } // Sim, outra vez. O que aconteceu? Porquê?
+
+i // Mostra o valor de i. Note que o while é um ciclo no sentido clássico -
+ // executa sequencialmente enquanto muda uma variável. Ciclos while são
+ // rápidos, por vezes até mais que ciclos de Java, mas combinadores e
+ // compreensões (usados anteriormente) são mais fáceis de entender e
+ // paralelizar
+
+// Um ciclo do while
+i = 0
+do {
+ println("i ainda é menor que 10")
+ i += 1
+} while (i < 10)
+
+// A forma idiomática em Scala de definir acções recorrentes é através de
+// recursão em cauda.
+// Funções recursivas necessitam de um tipo de retorno definido explicitamente.
+// Neste caso, é Unit.
+def mostraNumerosEntre(a: Int, b: Int): Unit = {
+ print(a)
+ if (a < b)
+ mostraNumerosEntre(a + 1, b)
+}
+mostraNumerosEntre(1, 14)
+
+
+// Condicionais
+
+val x = 10
+
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println ("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+
+/////////////////////////////////////////////////
+// 4. Estruturas de dados
+/////////////////////////////////////////////////
+
+val a = Array(1, 2, 3, 5, 8, 13)
+a(0)
+a(3)
+a(21) // Lança uma excepção
+
+val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+m("fork")
+m("spoon")
+m("bottle") // Lança uma excepção
+
+val safeM = m.withDefaultValue("no lo se")
+safeM("bottle")
+
+val s = Set(1, 3, 7)
+s(0)
+s(1)
+
+/* Veja a documentação de mapas de scala em -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * e verifique que a consegue aceder
+ */
+
+
+// Tuplos
+
+(1, 2)
+
+(4, 3, 2)
+
+(1, 2, "três")
+
+(a, 2, "três")
+
+// Porquê ter isto?
+val divideInts = (x: Int, y: Int) => (x / y, x % y)
+
+divideInts(10, 3) // A função divideInts returna o resultado e o resto
+
+// Para aceder aos elementos de um tuplo, pode-se usar _._n, onde n é o indice
+// (começado em 1) do elemento
+val d = divideInts(10, 3)
+
+d._1
+
+d._2
+
+
+/////////////////////////////////////////////////
+// 5. Programação Orientada a Objectos
+/////////////////////////////////////////////////
+
+/*
+ Aparte: Até agora tudo o que fizemos neste tutorial foram expressões simples
+ (valores, funções, etc). Estas expressões são suficientes para executar no
+ interpretador da linha de comandos para testes rápidos, mas não podem existir
+ isoladas num ficheiro de Scala. Por exemplo, não é possivel correr um
+ ficheiro scala que apenas contenha "val x = 5". Em vez disso, as únicas
+ construções de topo permitidas são:
+
+ - object
+ - class
+ - case class
+ - trait
+
+ Vamos agora explicar o que são:
+*/
+
+// Classes são semelhantes a classes noutras linguagens. Os argumentos do
+// construtor são declarados após o nome da classe, sendo a inicialização feita
+// no corpo da classe.
+class Cão(rc: String) {
+ // Código de construção
+ var raça: String = rc
+
+ // Define um método chamado "ladra", que retorna uma String
+ def ladra = "Woof, woof!"
+
+ // Valores e métodos são assumidos como públicos, mas é possivel usar
+ // os códigos "protected" and "private".
+ private def dormir(horas: Int) =
+ println(s"Vou dormir por $horas horas")
+
+ // Métodos abstractos são métodos sem corpo. Se descomentarmos a próxima
+ // linha, a classe Cão é declarada como abstracta
+ // abstract class Cão(...) { ... }
+ // def persegue(oQue: String): String
+}
+
+val oMeuCão = new Cão("greyhound")
+println(oMeuCão.raça) // => "greyhound"
+println(oMeuCão.ladra) // => "Woof, woof!"
+
+
+// O termo "object" cria um tipo e uma instancia singleton desse tipo. É comum
+// que classes de Scala possuam um "objecto companheiro", onde o comportamento
+// por instância é capturado nas classes, equanto que o comportamento
+// relacionado com todas as instancias dessa classe ficam no objecto.
+// A diferença é semelhante a métodos de classes e métodos estáticos noutras
+// linguagens. Note que objectos e classes podem ter o mesmo nome.
+object Cão {
+ def raçasConhecidas = List("pitbull", "shepherd", "retriever")
+ def criarCão(raça: String) = new Cão(raça)
+}
+
+
+// Case classes são classes com funcionalidades extra incluidas. Uma questão
+// comum de iniciantes de scala é quando devem usar classes e quando devem usar
+// case classes. A linha é difusa mas, em geral, classes tendem a concentrar-se
+// em encapsulamento, polimorfismo e comportamento. Os valores nestas classes
+// tendem a ser privados, sendo apenas exposotos métodos. O propósito principal
+// das case classes é armazenarem dados imutáveis. Geralmente possuem poucos
+// métods, sendo que estes raramente possuem efeitos secundários.
+case class Pessoa(nome: String, telefone: String)
+
+// Cria uma nova instancia. De notar que case classes não precisam de "new"
+val jorge = Pessoa("Jorge", "1234")
+val cátia = Pessoa("Cátia", "4567")
+
+// Case classes trazem algumas vantagens de borla, como acessores:
+jorge.telefone // => "1234"
+
+// Igualdade por campo (não é preciso fazer override do .equals)
+Pessoa("Jorge", "1234") == Pessoa("Cátia", "1236") // => false
+
+// Cópia simples
+// outroJorge == Person("jorge", "9876")
+val outroJorge = jorge.copy(telefone = "9876")
+
+// Entre outras. Case classes também suportam correspondência de padrões de
+// borla, como pode ser visto de seguida.
+
+
+// Traits em breve!
+
+
+/////////////////////////////////////////////////
+// 6. Correspondência de Padrões
+/////////////////////////////////////////////////
+
+// A correspondência de padrões é uma funcionalidade poderosa e bastante
+// utilizada em Scala. Eis como fazer correspondência de padrões numa case class:
+// Nota: Ao contrário de outras linguagens, cases em scala não necessitam de
+// breaks, a computação termina no primeiro sucesso.
+
+def reconhecePessoa(pessoa: Pessoa): String = pessoa match {
+ // Agora, especifique os padrões:
+ case Pessoa("Jorge", tel) => "Encontramos o Jorge! O seu número é " + tel
+ case Pessoa("Cátia", tel) => "Encontramos a Cátia! O seu número é " + tel
+ case Pessoa(nome, tel) => "Econtramos alguém : " + nome + ", telefone : " + tel
+}
+
+val email = "(.*)@(.*)".r // Define uma regex para o próximo exemplo.
+
+// A correspondência de padrões pode parecer familiar aos switches em linguagens
+// derivadas de C, mas é muto mais poderoso. Em Scala, é possível fazer
+// correspondências com muito mais:
+def correspondeTudo(obj: Any): String = obj match {
+ // Pode-se corresponder valores:
+ case "Olá mundo" => "Recebi uma string Olá mundo."
+
+ // Corresponder por tipo:
+ case x: Double => "Recebi um Double: " + x
+
+ // Corresponder tendo em conta condições especificas:
+ case x: Int if x > 10000 => "Recebi um número bem grande!"
+
+ // Fazer correspondências com case classes (visto anteriormente):
+ case Pessoa(nome, tel) => s"Recebi o contacto para $nome!"
+
+ // Fazer correspondência com expressões regulares:
+ case email(nome, dominio) => s"Recebi o endereço de email $nome@$dominio"
+
+ // Corresponder tuplos:
+ case (a: Int, b: Double, c: String) => s"Recebi o tuplo: $a, $b, $c"
+
+ // Corresponder estruturas de dados:
+ case List(1, b, c) => s"Recebi uma lista de 3 elementos começada em 1: 1, $b, $c"
+
+ // Combinar padrões:
+ case List(List((1, 2, "YAY"))) => "Recebi uma lista de lista de triplo"
+}
+
+// Na realidade, é possível fazer correspondência com qualquer objecto que
+// defina o método "unapply". Esta funcionalidade é tão poderosa que permite
+// definir funções sob a forma de padrões:
+val funcPaddrao: Pessoa => String = {
+ case Pessoa("Jorge", tel) => s"Número do Jorge: $tel"
+ case Pessoa(nome, tel) => s"Número de alguém: $tel"
+}
+
+
+/////////////////////////////////////////////////
+// 7. Programação Funcional
+/////////////////////////////////////////////////
+
+// Scala permite que funções e métodos retornem, ou recebam como parámetros,
+// outras funções ou métodos
+
+val soma10: Int => Int = _ + 10 // Função que recebe um Int e retorna um Int
+List(1, 2, 3) map soma10 // List(11, 12, 13) - soma10 é aplicado a cada elemento
+
+// Funções anónimas também podem ser usadas
+List(1, 2, 3) map (x => x + 10)
+
+// Sendo que o símbolo _ também pode ser usado se a função anónima só receber
+// um argumento. Este fica com o valor da variável
+List(1, 2, 3) map (_ + 10)
+
+// Se tanto o bloco como a função apenas receberem um argumento, o próprio
+// _ pode ser omitido
+List("Dom", "Bob", "Natalia") foreach println
+
+
+// Combinadores
+
+s.map(quadrado)
+
+val sQuadrado = s.map(quadrado)
+
+sQuadrado.filter(_ < 10)
+
+sQuadrado.reduce (_+_)
+
+// O método filter recebe um predicado (uma função de A => Boolean) e escolhe
+// todos os elementos que satisfazem o predicado
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Pessoa(nome: String, idade: Int)
+List(
+ Pessoa(nome = "Dom", idade = 23),
+ Pessoa(nome = "Bob", idade = 30)
+).filter(_.idade > 25) // List(Pessoa("Bob", 30))
+
+
+// O método foreach recebe uma função de A => Unit, executando essa função em
+// cada elemento da colecção
+val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
+aListOfNumbers foreach (x => println(x))
+aListOfNumbers foreach println
+
+// Compreensões For
+
+for { n <- s } yield quadrado(n)
+
+val nQuadrado2 = for { n <- s } yield quadrado(n)
+
+for { n <- nQuadrado2 if n < 10 } yield n
+
+for { n <- s; nQuadrado = n * n if nQuadrado < 10} yield nQuadrado
+
+/* Nota: isto não são ciclos for: A semântica de um ciclo é 'repetir', enquanto
+ que uma compreensão define a relação entre dois conjuntos de dados. */
+
+
+/////////////////////////////////////////////////
+// 8. Implicitos
+/////////////////////////////////////////////////
+
+/* AVISO IMPORTANTE: Implicitos são um conjunto de funcionalidades muito
+ * poderosas em Scala, que podem ser fácilmente abusadas. Iniciantes devem
+ * resistir a tentação de usá-los até que compreendam não só como funcionam,
+ * mas também as melhores práticas. Apenas incluimos esta secção no tutorial
+ * devido a estes serem tão comuns em bibliotecas de Scala que muitas delas
+ * se tornam impossíveis de usar sem conhecer implicitos. Este capítulo serve
+ * para compreender como trabalhar com implicitos, não como declará-los.
+*/
+
+// Qualquer valor (vals, funções, objectos, etc) pode ser declarado como
+// implicito usando a palavra "implicit". Vamos usar a classe Cão da secção 5
+// nestes exemplos
+
+implicit val oMeuIntImplicito = 100
+implicit def aMinhaFunçãoImplicita(raça: String) = new Cão("Golden " + raça)
+
+// Por si só, a palavra implicit não altera o comportamento de um valor, sendo
+// que estes podem ser usados da forma habitual.
+oMeuIntImplicito + 2 // => 102
+aMinhaFunçãoImplicita("Pitbull").raça // => "Golden Pitbull"
+
+// A diferença é que estes valores podem ser utilizados quando outro pedaço de
+// código "necessite" de uma valor implicito. Um exemplo são argumentos
+// implicitos de funções:
+def enviaCumprimentos(aQuem: String)(implicit quantos: Int) =
+ s"Olá $aQuem, $quantos cumprimentos para ti e para os teus!"
+
+// Se dermos um valor a "quantos", a função comporta-se normalmente
+enviaCumprimentos("João")(1000) // => "Olá João, 1000 cumprimentos para ti e para os teus!"
+
+// Mas, se omitirmos o parâmetro implicito, um valor implicito do mesmo tipo é
+// usado, neste caso, "oMeuInteiroImplicito"
+enviaCumprimentos("Joana") // => "Olá Joana, 100 cumprimentos para ti e para os teus!"
+
+// Parâmentros implicitos de funções permitem-nos simular classes de tipos de
+// outras linguagens funcionais. Isto é tão comum que tem a sua própria notação.
+// As seguintes linhas representam a mesma coisa
+// def foo[T](implicit c: C[T]) = ...
+// def foo[T : C] = ...
+
+
+// Outra situação em que o compilador prouca um implicito é se encontrar uma
+// expressão
+// obj.método(...)
+// mas "obj" não possuir um método chamado "método". Neste cso, se houver uma
+// conversão implicita A => B, onde A é o tipo de obj, e B possui um método
+// chamado "método", a conversão é aplicada. Ou seja, tendo
+// aMinhaFunçãoImplicita definida, podemos dizer
+"Retriever".raça // => "Golden Retriever"
+"Sheperd".ladra // => "Woof, woof!"
+
+// Neste caso, a String é primeiro convertida para Cão usando a nossa funão,
+// sendo depois chamado o método apropriado. Esta é uma funcionalidade
+// incrivelmente poderosa, sendo que deve ser usada com cautela. Na verdade,
+// ao definir a função implicita, o compilador deve lançar um aviso a insisitir
+// que só deve definir a função se souber o que está a fazer.
+
+
+/////////////////////////////////////////////////
+// 9. Misc
+/////////////////////////////////////////////////
+
+// Importar coisas
+import scala.collection.immutable.List
+
+// Importar todos os "sub pacotes"
+import scala.collection.immutable._
+
+// Importar multiplas classes numa linha
+import scala.collection.immutable.{List, Map}
+
+// Renomear uma classe importada usando '=>'
+import scala.collection.immutable.{List => ImmutableList}
+
+// Importar todas as classes excepto algumas. Set e Map são excluidos:
+import scala.collection.immutable.{Map => _, Set => _, _}
+
+// O ponto de entrada de um programa em Scala é definido por un ficheiro .scala
+// com um método main:
+object Aplicação {
+ def main(args: Array[String]): Unit = {
+ // código aqui.
+ }
+}
+
+// Ficheiros podem conter várias classes o objectos. Compilar com scalac
+
+
+
+
+// Input e output
+
+// Ler um ficheiro linha a linha
+import scala.io.Source
+for(linha <- Source.fromFile("ficheiro.txt").getLines())
+ println(linha)
+
+// Escrever um ficheiro usando o PrintWriter de Java
+val writer = new PrintWriter("ficheiro.txt")
+writer.write("Escrevendo linha por linha" + util.Properties.lineSeparator)
+writer.write("Outra linha aqui" + util.Properties.lineSeparator)
+writer.close()
+
+```
+
+## Mais recursos
+
+* [Scala for the impatient](http://horstmann.com/scala/)
+* [Twitter Scala school](http://twitter.github.io/scala_school/)
+* [The scala documentation](http://docs.scala-lang.org/)
+* [Try Scala in your browser](http://scalatutorials.com/tour/)
+* Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
diff --git a/scala.html.markdown b/scala.html.markdown
index 7189be10..7f545196 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -6,7 +6,6 @@ contributors:
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
- ["Geoff Liu", "http://geoffliu.me"]
- ["Ha-Duong Nguyen", "http://reference-error.org"]
-filename: learn.scala
---
Scala - the scalable language
@@ -244,10 +243,11 @@ i // Show the value of i. Note that while is a loop in the classical sense -
// comprehensions above is easier to understand and parallelize
// A do while loop
+i = 0
do {
- println("x is still less than 10")
- x += 1
-} while (x < 10)
+ println("i is still less than 10")
+ i += 1
+} while (i < 10)
// Tail recursion is an idiomatic way of doing recurring things in Scala.
// Recursive functions need an explicit return type, the compiler can't infer it.
@@ -566,8 +566,8 @@ sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
// Implicit function parameters enable us to simulate type classes in other
// functional languages. It is so often used that it gets its own shorthand. The
// following two lines mean the same thing:
-def foo[T](implicit c: C[T]) = ...
-def foo[T : C] = ...
+// def foo[T](implicit c: C[T]) = ...
+// def foo[T : C] = ...
// Another situation in which the compiler looks for an implicit is if you have