summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--es-es/visualbasic-es.html.markdown286
-rw-r--r--fr-fr/scala.html.markdown9
-rw-r--r--hu-hu/ruby.html.markdown555
-rw-r--r--julia.html.markdown26
-rw-r--r--perl.html.markdown2
-rw-r--r--perl6.html.markdown91
-rw-r--r--pt-br/clojure-macros-pt.html.markdown154
-rw-r--r--pt-pt/scala-pt.html.markdown651
-rw-r--r--scala.html.markdown12
9 files changed, 1728 insertions, 58 deletions
diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown
new file mode 100644
index 00000000..c7f581c0
--- /dev/null
+++ b/es-es/visualbasic-es.html.markdown
@@ -0,0 +1,286 @@
+---
+language: Visual Basic
+contributors:
+ - ["Brian Martin", "http://brianmartin.biz"]
+translators:
+ - ["Adolfo Jayme Barrientos", "https://github.com/fitojb"]
+author: Brian Martin
+author_url: https://github.com/fitojb
+filename: learnvisualbasic-es.vb
+lang: es-es
+---
+
+```vb
+Module Module1
+
+ Sub Main()
+ ' Un vistazo rápido a las aplicaciones de consola de Visual Basic antes
+ ' de que profundicemos en el tema.
+ ' El apóstrofo inicia una línea de comentario.
+ ' Para explorar este tutorial dentro del Compilador de Visual Basic,
+ ' he creado un sistema de navegación.
+ ' Dicho sistema se explicará a medida que avancemos en este
+ ' tutorial; gradualmente entenderás lo que significa todo.
+ Console.Title = ("Aprende X en Y minutos")
+ Console.WriteLine("NAVEGACIÓN") 'Mostrar
+ Console.WriteLine("")
+ Console.ForegroundColor = ConsoleColor.Green
+ Console.WriteLine("1. Salida «Hola, mundo»")
+ Console.WriteLine("2. Entrada «Hola, mundo»")
+ Console.WriteLine("3. Calcular números enteros")
+ Console.WriteLine("4. Calcular números decimales")
+ Console.WriteLine("5. Una calculadora funcional")
+ Console.WriteLine("6. Uso de bucles «Do While»")
+ Console.WriteLine("7. Uso de bucles «For While»")
+ Console.WriteLine("8. Declaraciones condicionales")
+ Console.WriteLine("9. Selecciona una bebida")
+ Console.WriteLine("50. Acerca de")
+ Console.WriteLine("Elige un número de la lista anterior")
+ Dim selection As String = Console.ReadLine
+ Select Case selection
+ Case "1" 'Salida «hola, mundo»
+ Console.Clear() 'Limpia la consola y abre la subrutina privada
+ SalidaHolaMundo() 'Abre la subrutina privada nombrada
+ Case "2" 'Entrada «hola, mundo»
+ Console.Clear()
+ EntradaHolaMundo()
+ Case "3" 'Calcular números enteros
+ Console.Clear()
+ CalcularNumerosEnteros()
+ Case "4" 'Calcular números decimales
+ Console.Clear()
+ CalcularNumerosDecimales()
+ Case "5" 'Una calculadora funcional
+ Console.Clear()
+ CalculadoraFuncional()
+ Case "6" 'Uso de bucles «Do While»
+ Console.Clear()
+ UsoBuclesDoWhile()
+ Case "7" 'Uso de bucles «For While»
+ Console.Clear()
+ UsoBuclesFor()
+ Case "8" 'Declaraciones condicionales
+ Console.Clear()
+ DeclaracionCondicional()
+ Case "9" 'Declaración «If/Else»
+ Console.Clear()
+ DeclaracionIfElse() 'Selecciona una bebida
+ Case "50" 'Cuadro de mensaje «Acerca de»
+ Console.Clear()
+ Console.Title = ("Aprende X en Y minutos :: Acerca de")
+ MsgBox("Tutorial escrito por Brian Martin (@BrianMartinn")
+ Console.Clear()
+ Main()
+ Console.ReadLine()
+
+ End Select
+ End Sub
+
+ 'Uno - He usado números para guiarme por el sistema de navegación anterior
+ 'cuando regrese posteriormente a implementarlo.
+
+ 'Usamos subrutinas privadas para separar distintas secciones del programa.
+ Private Sub SalidaHolaMundo()
+ 'Título de la aplicación de consola
+ Console.Title = "Salida «Hola, mundo» | Aprende X en Y minutos"
+ 'Usa Console.Write("") o Console.WriteLine("") para mostrar salidas.
+ 'Seguido por Console.Read(), o bien, Console.Readline()
+ 'Console.ReadLine() muestra la salida en la consola.
+ Console.WriteLine("Hola, mundo")
+ Console.ReadLine()
+ End Sub
+
+ 'Dos
+ Private Sub EntradaHolaMundo()
+ Console.Title = "«Hola, mundo, soy...» | Aprende X en Y minutos"
+ ' Variables
+ ' Los datos que introduzca un usuario deben almacenarse.
+ ' Las variables también empiezan por Dim y terminan por As VariableType.
+
+ ' En este tutorial queremos conocer tu nombre y hacer que el programa
+ ' responda a este.
+ Dim nombredeusuario As String
+ 'Usamos «string» porque es una variable basada en texto.
+ Console.WriteLine("Hola, ¿cómo te llamas? ") 'Preguntar nombre de usuario.
+ nombredeusuario = Console.ReadLine() 'Almacenar nombre del usuario.
+ Console.WriteLine("Hola, " + nombredeusuario) 'La salida es Hola, nombre
+ Console.ReadLine() 'Muestra lo anterior.
+ 'El código anterior te hará una pregunta y mostrará la respuesta.
+ 'Entre otras variables está Integer, la cual usaremos para números enteros.
+ End Sub
+
+ 'Tres
+ Private Sub CalcularNumerosEnteros()
+ Console.Title = "Calcular números enteros | Aprende X en Y minutos"
+ Console.Write("Primer número: ") 'Escribe un núm. entero, 1, 2, 104, etc
+ Dim a As Integer = Console.ReadLine()
+ Console.Write("Segundo número: ") 'Escribe otro número entero.
+ Dim b As Integer = Console.ReadLine()
+ Dim c As Integer = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ 'Lo anterior es una calculadora sencilla
+ End Sub
+
+ 'Cuatro
+ Private Sub CalcularNumerosDecimales()
+ Console.Title = "Calcular con tipo doble | Aprende X en Y minutos"
+ 'Por supuesto, nos gustaría sumar decimales.
+ 'Por ello podríamos cambiar del tipo Integer al Double.
+
+ 'Escribe un número fraccionario, 1.2, 2.4, 50.1, 104.9 etc
+ Console.Write("Primer número: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Segundo número: ") 'Escribe el segundo número.
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ 'Este programa puede sumar 1.1 y 2.2
+ End Sub
+
+ 'Cinco
+ Private Sub CalculadoraFuncional()
+ Console.Title = "La calculadora funcional | Aprende X en Y minutos"
+ 'Pero si quieres que la calculadora reste, divida, multiplique y
+ 'sume.
+ 'Copia y pega lo anterior.
+ Console.Write("Primer número: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Segundo número: ")
+ Dim b As Integer = Console.ReadLine
+ Dim c As Integer = a + b
+ Dim d As Integer = a * b
+ Dim e As Integer = a - b
+ Dim f As Integer = a / b
+
+ 'Mediante las líneas siguientes podremos restar,
+ 'multiplicar y dividir los valores a y b
+ Console.Write(a.ToString() + " + " + b.ToString())
+ 'Queremos dar un margen izquierdo de 3 espacios a los resultados.
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + f.ToString.PadLeft(3))
+ Console.ReadLine()
+
+ End Sub
+
+ 'Seis
+ Private Sub UsoBuclesDoWhile()
+ 'Igual que la subrutina privada anterior
+ 'Esta vez preguntaremos al usuario si quiere continuar (¿sí o no?)
+ 'Usamos el bucle Do While porque no sabemos si el usuario quiere
+ 'usar el programa más de una vez.
+ Console.Title = "Uso de bucles «Do While» | Aprende X en Y minutos"
+ Dim respuesta As String 'Usamos la variable «String» porque la resp. es texto
+ Do 'Comenzamos el programa con
+ Console.Write("Primer número: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Segundo número: ")
+ Dim b As Integer = Console.ReadLine
+ Dim c As Integer = a + b
+ Dim d As Integer = a * b
+ Dim e As Integer = a - b
+ Dim f As Integer = a / b
+
+ Console.Write(a.ToString() + " + " + b.ToString())
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + f.ToString.PadLeft(3))
+ Console.ReadLine()
+ 'Preguntar si el usuario quiere continuar. Desafortunadamente,
+ 'distingue entre mayúsculas y minúsculas.
+ Console.Write("¿Quieres continuar? (s / n)")
+ 'El programa toma la variable, la muestra y comienza de nuevo.
+ respuesta = Console.ReadLine
+ 'La orden que hará funcionar esta variable es en este caso «s»
+ Loop While respuesta = "s"
+
+ End Sub
+
+ 'Siete
+ Private Sub UsoBuclesFor()
+ 'A veces el programa debe ejecutarse solo una vez.
+ 'En este programa contaremos a partir de 10.
+
+ Console.Title = "Uso de bucles «For» | Aprende X en Y minutos"
+ 'Declarar Variable y desde qué número debe contar en Step -1,
+ 'Step -2, Step -3, etc.
+ For i As Integer = 10 To 0 Step -1
+ Console.WriteLine(i.ToString) 'Muestra el valor del contador
+ Next i 'Calcular el valor nuevo
+ Console.WriteLine("Iniciar") '¡¡Comencemos el programa, nene!!
+ Console.ReadLine() '¡¡ZAS!! - Quizá me he emocionado bastante :)
+ End Sub
+
+ 'Ocho
+ Private Sub DeclaracionCondicional()
+ Console.Title = "Declaraciones condicionales | Aprende X en Y minutos"
+ Dim nombredeUsuario As String = Console.ReadLine
+ Console.WriteLine("Hola, ¿cómo te llamas? ") 'Preguntar nombre de usuario.
+ nombredeUsuario = Console.ReadLine() 'Almacena el nombre de usuario.
+ If nombredeUsuario = "Adam" Then
+ Console.WriteLine("Hola, Adam")
+ Console.WriteLine("Gracias por crear este útil sitio web")
+ Console.ReadLine()
+ Else
+ Console.WriteLine("Hola, " + nombredeUsuario)
+ Console.WriteLine("¿Has visitado www.learnxinyminutes.com?")
+ Console.ReadLine() 'Termina y muestra la declaración anterior.
+ End If
+ End Sub
+
+ 'Nueve
+ Private Sub DeclaracionIfElse()
+ Console.Title = "Declaración «If / Else» | Aprende X en Y minutos"
+ 'A veces es importante considerar más de dos alternativas.
+ 'A veces, algunas de estas son mejores.
+ 'Cuando esto sucede, necesitaríamos más de una declaración «if».
+ 'Una declaración «if» es adecuada para máquinas expendedoras.
+ 'En las que el usuario escribe un código (A1, A2, A3) para elegir.
+ 'Pueden combinarse todas las elecciones en una sola declaración «if».
+
+ Dim seleccion As String = Console.ReadLine 'Valor de la selección
+ Console.WriteLine("A1. para 7Up")
+ Console.WriteLine("A2. para Fanta")
+ Console.WriteLine("A3. para Dr. Pepper")
+ Console.WriteLine("A4. para Coca-Cola")
+ Console.ReadLine()
+ If selection = "A1" Then
+ Console.WriteLine("7up")
+ Console.ReadLine()
+ ElseIf selection = "A2" Then
+ Console.WriteLine("fanta")
+ Console.ReadLine()
+ ElseIf selection = "A3" Then
+ Console.WriteLine("dr. pepper")
+ Console.ReadLine()
+ ElseIf selection = "A4" Then
+ Console.WriteLine("coca-cola")
+ Console.ReadLine()
+ Else
+ Console.WriteLine("Selecciona un producto")
+ Console.ReadLine()
+ End If
+
+ End Sub
+
+End Module
+
+```
+
+## Referencias
+
+Aprendí Visual Basic en la aplicación de consola. Esta me permitió entender los principios de la programación para, posteriormente, aprender otros lenguajes con facilidad.
+
+He creado un <a href="http://www.vbbootcamp.co.uk/" Title="Tutorial de Visual Basic">tutorial de Visual Basic</a> más exhaustivo para quienes quieran saber más.
+
+Toda la sintaxis es válida. Copia el código y pégalo en el compilador de Visual Basic y ejecuta (F5) el programa.
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/hu-hu/ruby.html.markdown b/hu-hu/ruby.html.markdown
new file mode 100644
index 00000000..169f2b8e
--- /dev/null
+++ b/hu-hu/ruby.html.markdown
@@ -0,0 +1,555 @@
+---
+language: ruby
+lang: hu-hu
+filenev: learnruby.rb
+contributors:
+ - ["David Underwood", "http://theflyingdeveloper.com"]
+ - ["Joel Walden", "http://joelwalden.net"]
+ - ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+ - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ translators:
+ - ["Zsolt Prontvai", "https://github.com/prozsolt"]
+---
+
+```ruby
+# Ez egy komment
+
+=begin
+Ez egy többsoros komment
+Senki sem használja
+Neked sem kellene
+=end
+
+# Először is: Minden objektum
+
+# A számok objektumok
+
+3.class #=> Fixnum
+
+3.to_s #=> "3"
+
+
+# Néhány alapvető számtani művelet
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+2**5 #=> 32
+
+# A számtani művelet csak szintaktikus cukor
+# az objektumon történő függvény hívásra
+1.+(3) #=> 4
+10.* 5 #=> 50
+
+# A speciális értékek objektumok
+nil # Nincs itt semmi látnivaló
+true # igaz
+false # hamis
+
+nil.class #=> NilClass
+true.class #=> TrueClass
+false.class #=> FalseClass
+
+# Egyenlőség
+1 == 1 #=> true
+2 == 1 #=> false
+
+# Egyenlőtlenség
+1 != 1 #=> false
+2 != 1 #=> true
+
+# A false-on kívül, nil az egyetlen hamis érték
+
+!nil #=> true
+!false #=> true
+!0 #=> false
+
+# Még több összehasonlítás
+1 < 10 #=> true
+1 > 10 #=> false
+2 <= 2 #=> true
+2 >= 2 #=> true
+
+# Logikai operátorok
+true && false #=> false
+true || false #=> true
+!true #=> false
+
+# A logikai operátoroknak alternatív verziójuk is van sokkal kisebb
+# precedenciával. Ezeket arra szánták, hogy több állítást összeláncoljanak
+# amíg egyikük igaz vagy hamis értékkel nem tér vissza.
+
+# `csinalj_valami_mast` csak akkor fut le, ha `csinalj_valamit` igaz értékkel
+# tért vissza.
+csinalj_valamit() and csinalj_valami_mast()
+# `log_error` csak akkor fut le, ha `csinalj_valamit` hamis értékkel
+# tért vissza.
+csinalj_valamit() or log_error()
+
+
+# A sztringek objektumok
+
+'Én egy sztring vagyok'.class #=> String
+"Én is egy sztring vagyok".class #=> String
+
+helykitolto = 'interpolációt használhatok'
+"Sztring #{helykitolto}, ha dupla időzőjelben van a sztringem"
+#=> "Sztring interpolációt használhatok, ha dupla időzőjelben van a sztringem"
+
+# A szimpla idézőjelet preferáljuk, ahol csak lehet,
+# mert a dupla idézőjel extra számításokat végez.
+
+# Kombinálhatunk sztringeket, de nem számokkal
+'hello ' + 'world' #=> "hello world"
+'hello ' + 3 #=> TypeError: can't convert Fixnum into String
+'hello ' + 3.to_s #=> "hello 3"
+
+# kiírás a kimenetre
+puts "Írok"
+
+# Változók
+x = 25 #=> 25
+x #=> 25
+
+# Értékadás az adott értékkel tér vissza
+# Ez azt jelenti, hogy használhatunk többszörös értékadást:
+
+x = y = 10 #=> 10
+x #=> 10
+y #=> 10
+
+# Konvencióból, snake_case változó neveket használj
+snake_case = true
+
+# Leíró változó neveket használj
+ut_a_projekt_gyokerehez = '/jo/nev/'
+ut = '/rossz/nev/'
+
+# A szimbólumok (objektumok)
+# A szimbólumok megváltoztathatatlan, újra felhasználható konstans,
+# mely belsőleg egész számként reprezentált. Sokszor sztring helyett használják,
+# hogy effektíven közvetítsünk konkrét, értelmes értékeket
+
+:fuggoben.class #=> Symbol
+
+statusz = :fuggoben
+
+statusz == :fuggoben #=> true
+
+statusz == 'fuggoben' #=> false
+
+statusz == :jovahagyott #=> false
+
+# Tömbök
+
+# Ez egy tömb
+tomb = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+
+# A tömmbök különböző tipusú dolgokat tartalmazhat
+
+[1, 'hello', false] #=> [1, "hello", false]
+
+# Tömbök indexelhetőek
+# Az elejéről
+tomb[0] #=> 1
+tomb[12] #=> nil
+
+# Akárcsak a számtani műveletek [var] hozzáférés
+# is csak szintaktikus cukor
+# a [] függvény hívására az objektumon
+tomb.[] 0 #=> 1
+tomb.[] 12 #=> nil
+
+# A végéről
+tomb[-1] #=> 5
+
+# Kezdőértékkel és hosszal
+tomb[2, 3] #=> [3, 4, 5]
+
+# Tömb megfordítása
+a=[1,2,3]
+a.reverse! #=> [3,2,1]
+
+# Vagy tartománnyal
+tomb[1..3] #=> [2, 3, 4]
+
+# Így adhatunk a tömbhöz
+tomb << 6 #=> [1, 2, 3, 4, 5, 6]
+# Vagy így
+tomb.push(6) #=> [1, 2, 3, 4, 5, 6]
+
+# Ellenőrízük, hogy a tömb tartalmaz egy elemet
+tomb.include?(1) #=> true
+
+# Hash-ek a ruby elsődleges szótárjai kulcs/érték párokkal
+# Hash-eket kapcsos zárójellel jelöljük
+hash = { 'szin' => 'zold', 'szam' => 5 }
+
+hash.keys #=> ['szin', 'szam']
+
+# Hash-ekben könnyen kreshetünk a kulcs segítségével:
+hash['szin'] #=> 'zold'
+hash['szam'] #=> 5
+
+# Nem létező kulcsra keresve nil-t kapunk:
+hash['nincs itt semmi'] #=> nil
+
+# Ruby 1.9-től, egy külnleges szintaxist is használhatunk a szimbólumot
+# használunk kulcsnak
+
+uj_hash = { defcon: 3, action: true }
+
+uj_hash.keys #=> [:defcon, :action]
+
+# Ellenőrizzük, hogy az adott kulcs és érték bene-e van a hash-ben
+uj_hash.has_key?(:defcon) #=> true
+uj_hash.has_value?(3) #=> true
+
+# Tip: A tömbök és hash-ek is felsorolhatóak
+# Sok közös függvényük van, akár az each, map, count, és több
+
+# Kontroll Struktúrák
+
+if true
+ 'ha állítás'
+elsif false
+ 'különben ha, opcionális'
+else
+ 'különben, szintén opcionális'
+end
+
+for szamlalo in 1..5
+ puts "iteracio #{szamlalo}"
+end
+#=> iteracio 1
+#=> iteracio 2
+#=> iteracio 3
+#=> iteracio 4
+#=> iteracio 5
+
+# HOWEVER, No-one uses for loops.
+# Instead you should use the "each" method and pass it a block.
+# A block is a bunch of code that you can pass to a method like "each".
+# It is analogous to lambdas, anonymous functions or closures in other
+# programming languages.
+#
+# The "each" method of a range runs the block once for each element of the range.
+# The block is passed a counter as a parameter.
+# Calling the "each" method with a block looks like this:
+
+(1..5).each do |counter|
+ puts "iteration #{counter}"
+end
+#=> iteration 1
+#=> iteration 2
+#=> iteration 3
+#=> iteration 4
+#=> iteration 5
+
+# You can also surround blocks in curly brackets:
+(1..5).each { |counter| puts "iteration #{counter}" }
+
+# The contents of data structures can also be iterated using each.
+array.each do |element|
+ puts "#{element} is part of the array"
+end
+hash.each do |key, value|
+ puts "#{key} is #{value}"
+end
+
+counter = 1
+while counter <= 5 do
+ puts "iteration #{counter}"
+ counter += 1
+end
+#=> iteration 1
+#=> iteration 2
+#=> iteration 3
+#=> iteration 4
+#=> iteration 5
+
+jegy = '4'
+
+case jegy
+when '5'
+ puts 'Kitünő'
+when '4'
+ puts 'Jó'
+when '3'
+ puts 'Közepes'
+when '2'
+ puts 'Elégsége'
+when '1'
+ puts 'Elégtelen'
+else
+ puts 'Alternatív értékelés, hm?'
+end
+#=> "Jó"
+
+# case-ek tartományokat is használhatnak
+jegy = 82
+case jegy
+when 90..100
+ puts 'Hurrá!'
+when 80...90
+ puts 'Jó munka'
+else
+ puts 'Megbuktál!'
+end
+#=> "Jó munka"
+
+# kivétel kezelés:
+begin
+ # kód ami kivételt dobhat
+ raise NoMemoryError, 'Megtelt a memória'
+rescue NoMemoryError => kivetel_valtozo
+ puts 'NoMemoryError-t dobott', kivetel_valtozo
+rescue RuntimeError => mas_kivetel_valtozo
+ puts 'RuntimeError dobott most'
+else
+ puts 'Ez akkor fut ha nem dob kivételt'
+ensure
+ puts 'Ez a kód mindenképpen lefut'
+end
+
+# Függvények
+
+def ketszeres(x)
+ x * 2
+end
+
+# Függvények (és egyébb blokkok) implicit viszatértnek az utolsó értékkel
+ketszeres(2) #=> 4
+
+# Zárójelezés opcionális, ha az eredmény félreérthetetlen
+ketszeres 3 #=> 6
+
+ketszeres ketszeres 3 #=> 12
+
+def osszeg(x, y)
+ x + y
+end
+
+# Függvény argumentumait vesszővel választjuk el.
+osszeg 3, 4 #=> 7
+
+osszeg osszeg(3, 4), 5 #=> 12
+
+# yield
+# Minden függvénynek van egy implicit, opcionális block paramétere
+# 'yield' kulcsszóval hívhatjuk
+
+def korulvesz
+ puts '{'
+ yield
+ puts '}'
+end
+
+korulvesz { puts 'hello world' }
+
+# {
+# hello world
+# }
+
+
+# Fuggvénynek átadhatunk blokkot
+# "&" jelöli az átadott blokk referenciáját
+def vendegek(&block)
+ block.call 'valami_argumentum'
+end
+
+# Argumentum lisát is átadhatunk, ami tömbé lesz konvertálva
+# Erre való a splat operátor ("*")
+def vendegek(*array)
+ array.each { |vendeg| puts vendeg }
+end
+
+# Osztályt a class kulcsszóval definiálhatunk
+class Ember
+
+ # Az osztály változó. Az osztály minden példánnyával megvan osztva
+ @@faj = 'H. sapiens'
+
+ # Alap inicializáló
+ def initialize(nev, kor = 0)
+ # Hozzárendeli az argumentumot a "nev" példány változóhoz
+ @nev = nev
+ # Ha nem adtunk meg kort akkor az alapértemezet értéket fogja használni
+ @kor = kor
+ end
+
+ # Alap setter függvény
+ def nev=(nev)
+ @nev = nev
+ end
+
+ # Alap getter függvény
+ def nev
+ @nev
+ end
+
+ # A fönti funkcionalítást az attr_accessor függvénnyel is elérhetjük
+ attr_accessor :nev
+
+ # Getter/setter függvények egyenként is kreálhatóak
+ attr_reader :nev
+ attr_writer :nev
+
+ # Az osztály függvények "self"-et hasznalnak, hogy megkülönböztessék magukat a
+ # példány függvényektől
+ # Az osztályn hívhatóak, nem a példányon
+ def self.mond(uzenet)
+ puts uzenet
+ end
+
+ def faj
+ @@faj
+ end
+end
+
+
+# Példányosítsuk az osztályt
+jim = Ember.new('Jim Halpert')
+
+dwight = Ember.new('Dwight K. Schrute')
+
+# Hívjunk meg pár függvényt
+jim.faj #=> "H. sapiens"
+jim.nev #=> "Jim Halpert"
+jim.nev = "Jim Halpert II" #=> "Jim Halpert II"
+jim.nev #=> "Jim Halpert II"
+dwight.faj #=> "H. sapiens"
+dwight.nev #=> "Dwight K. Schrute"
+
+# Hívjuk meg az osztály függvényt
+Ember.mond('Hi') #=> "Hi"
+
+# Változók szókjait az elnevezésük definiálja
+# $ kezdetű változók globálisak
+$var = "Én egy globális változó vagyok"
+defined? $var #=> "global-variable"
+
+# Változók amik @-al kezdődnek példány szkópjuk van
+@var = "Én egy példány változó vagyok"
+defined? @var #=> "instance-variable"
+
+# Változók amik @@-al kezdődnek példány szkópjuk van
+@@var = "Én egy osztály változó vagyok"
+defined? @@var #=> "class variable"
+
+# Változók amik nagy betűvel kezdődnek a konstansok
+Var = "Konstans vagyok"
+defined? Var #=> "constant"
+
+# Az osztály is objetum. Tehát az osztálynak lehet példány változója
+# Az osztályváltozón osztozik minden pédány és leszármazott
+
+# Ős osztály
+class Ember
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(ertek)
+ @@foo = ertek
+ end
+end
+
+# Leszarmazott osztály
+class Dolgozo < Ember
+end
+
+Ember.foo # 0
+Dolgozo.foo # 0
+
+Ember.foo = 2 # 2
+Dolgozo.foo # 2
+
+# Az osztálynak példány változóját nem látja az osztály leszármazottja.
+
+class Ember
+ @bar = 0
+
+ def self.bar
+ @bar
+ end
+
+ def self.bar=(ertek)
+ @bar = ertek
+ end
+end
+
+class Doctor < Ember
+end
+
+Ember.bar # 0
+Doctor.bar # nil
+
+module ModulePelda
+ def foo
+ 'foo'
+ end
+end
+
+# Modulok include-olása a fügvényeiket az osztály példányaihoz köti.
+# Modulok extend-elésa a fügvényeiket magához az osztályhoz köti.
+
+class Szemely
+ include ModulePelda
+end
+
+class Konyv
+ extend ModulePelda
+end
+
+Szemely.foo # => NoMethodError: undefined method `foo' for Szemely:Class
+Szemely.new.foo # => 'foo'
+Konyv.foo # => 'foo'
+Konyv.new.foo # => NoMethodError: undefined method `foo'
+
+# Callback-ek végrehajtódnak amikor include-olunk és extend-elünk egy modult
+
+module ConcernPelda
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
+ end
+ end
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
+ end
+end
+
+class Valami
+ include ConcernPelda
+end
+
+Valami.bar # => 'bar'
+Valami.qux # => NoMethodError: undefined method `qux'
+Valami.new.bar # => NoMethodError: undefined method `bar'
+Valami.new.qux # => 'qux'
+```
+
+## Egyéb források
+
+- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338)
+- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/)
+- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
+- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - A régebbi [ingyenes változat](http://ruby-doc.com/docs/ProgrammingRuby/) elérhető online.
+- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide)
diff --git a/julia.html.markdown b/julia.html.markdown
index 66329feb..c5089dc3 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -81,10 +81,13 @@ false
# Strings are created with "
"This is a string."
+# Julia has several types of strings, including ASCIIString and UTF8String.
+# More on this in the Types section.
+
# Character literals are written with '
'a'
-# A string can be indexed like an array of characters
+# Some strings can be indexed like an array of characters
"This is a string"[1] # => 'T' # Julia indexes from 1
# However, this is will not work well for UTF8 strings,
# so iterating over strings is recommended (map, for loops, etc).
@@ -314,7 +317,7 @@ end
# For loops iterate over iterables.
-# Iterable types include Range, Array, Set, Dict, and String.
+# Iterable types include Range, Array, Set, Dict, and AbstractString.
for animal=["dog", "cat", "mouse"]
println("$animal is a mammal")
# You can use $ to interpolate variables or expression into strings
@@ -537,6 +540,17 @@ subtypes(Number) # => 6-element Array{Any,1}:
# Real
subtypes(Cat) # => 0-element Array{Any,1}
+# AbstractString, as the name implies, is also an abstract type
+subtypes(AbstractString) # 8-element Array{Any,1}:
+ # Base.SubstitutionString{T<:AbstractString}
+ # DirectIndexString
+ # RepString
+ # RevString{T<:AbstractString}
+ # RopeString
+ # SubString{T<:AbstractString}
+ # UTF16String
+ # UTF8String
+
# Every type has a super type; use the `super` function to get it.
typeof(5) # => Int64
super(Int64) # => Signed
@@ -546,17 +560,21 @@ super(Number) # => Any
super(super(Signed)) # => Number
super(Any) # => Any
# All of these type, except for Int64, are abstract.
+typeof("fire") # => ASCIIString
+super(ASCIIString) # => DirectIndexString
+super(DirectIndexString) # => AbstractString
+# Likewise here with ASCIIString
# <: is the subtyping operator
type Lion <: Cat # Lion is a subtype of Cat
mane_color
- roar::String
+ roar::AbstractString
end
# You can define more constructors for your type
# Just define a function of the same name as the type
# and call an existing constructor to get a value of the correct type
-Lion(roar::String) = Lion("green",roar)
+Lion(roar::AbstractString) = Lion("green",roar)
# This is an outer constructor because it's outside the type definition
type Panther <: Cat # Panther is also a subtype of Cat
diff --git a/perl.html.markdown b/perl.html.markdown
index 4e172406..1b86f410 100644
--- a/perl.html.markdown
+++ b/perl.html.markdown
@@ -102,6 +102,8 @@ for (@elements) {
print;
}
+# the Perlish post-condition way again
+print for @elements;
#### Regular expressions
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-br/clojure-macros-pt.html.markdown b/pt-br/clojure-macros-pt.html.markdown
new file mode 100644
index 00000000..dbc0c25c
--- /dev/null
+++ b/pt-br/clojure-macros-pt.html.markdown
@@ -0,0 +1,154 @@
+---
+language: clojure
+filename: learnclojure-pt.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Raphael Bezerra do Nascimento"]
+lang: pt-br
+---
+
+Como todas as Lisps, a inerente [homoiconicity](https://en.wikipedia.org/wiki/Homoiconic)
+do Clojure lhe dá acesso a toda a extensão da linguagem
+para escrever rotinas de geração de código chamados "macros". Macros fornecem uma poderosa forma de adequar a linguagem
+às suas necessidades.
+
+Pórem Tenha cuidado. É considerado má pratica escrever uma macro quando uma função vai fazer. Use uma macro apenas
+quando você precisar do controle sobre quando ou se os argumentos para um formulário será avaliado.
+
+Você vai querer estar familiarizado com Clojure. Certifique-se de entender tudo em
+[Clojure em Y Minutos](/docs/clojure/).
+
+```clojure
+;; Defina uma macro utilizando defmacro. Sua macro deve ter como saida uma lista que possa
+;; ser avaliada como codigo Clojure.
+;;
+;; Essa macro é a mesma coisa que se você escrever (reverse "Hello World")
+(defmacro my-first-macro []
+ (list reverse "Hello World"))
+
+;; Inspecione o resultado de uma macro utilizando macroexpand or macroexpand-1.
+;;
+;; Note que a chamada deve utilizar aspas simples.
+(macroexpand '(my-first-macro))
+;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World")
+
+;; Você pode avaliar o resultad de macroexpand diretamente:
+(eval (macroexpand '(my-first-macro)))
+; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; mas você deve usar esse mais suscinto, sintax como de função:
+(my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; Você pode tornar as coisas mais faceis pra você, utilizando a sintaxe de citação mais suscinta
+;; para criar listas nas suas macros:
+(defmacro my-first-quoted-macro []
+ '(reverse "Hello World"))
+
+(macroexpand '(my-first-quoted-macro))
+;; -> (reverse "Hello World")
+;; Note que reverse não é mais uma função objeto, mas um simbolo.
+
+;; Macros podem ter argumentos.
+(defmacro inc2 [arg]
+ (list + 2 arg))
+
+(inc2 2) ; -> 4
+
+;; Mas se você tentar fazer isso com uma lista entre aspas simples, você vai receber um erro, por que o
+;; argumento irá entra aspas simples também. Para contornar isso, Clojure prover uma maneira de utilizar aspas simples
+;; em macros: `. Dentro `, você pode usar ~ para chegar ao escopo externo.
+(defmacro inc2-quoted [arg]
+ `(+ 2 ~arg))
+
+(inc2-quoted 2)
+
+;; Você pode usar os argumentos de destruturação habituais. Expandir lista de variaveis usando ~@
+(defmacro unless [arg & body]
+ `(if (not ~arg)
+ (do ~@body))) ; Lembrar o do!
+
+(macroexpand '(unless true (reverse "Hello World")))
+;; ->
+;; (if (clojure.core/not true) (do (reverse "Hello World")))
+
+;; (unless) avalia e retorna seu corpo, se o primeiro argumento é falso.
+;; caso contrario, retorna nil
+
+(unless true "Hello") ; -> nil
+(unless false "Hello") ; -> "Hello"
+
+;; Usado sem cuidados, macros podem fazer muito mal por sobreporem suas variaveis
+(defmacro define-x []
+ '(do
+ (def x 2)
+ (list x)))
+
+(def x 4)
+(define-x) ; -> (2)
+(list x) ; -> (2)
+
+;;s Para evitar isso, use gensym para receber um identificador unico
+(gensym 'x) ; -> x1281 (ou outra coisa)
+
+(defmacro define-x-safely []
+ (let [sym (gensym 'x)]
+ `(do
+ (def ~sym 2)
+ (list ~sym))))
+
+(def x 4)
+(define-x-safely) ; -> (2)
+(list x) ; -> (4)
+
+;; Você pode usar # dentro de ` para produzir uma gensym para cada simbolo automaticamente
+(defmacro define-x-hygenically []
+ `(do
+ (def x# 2)
+ (list x#)))
+
+(def x 4)
+(define-x-hygenically) ; -> (2)
+(list x) ; -> (4)
+
+;; É típico o uso de funções de auxilio com macros. Vamos criar um pouco
+;; Vamos criar um pouco para nos ajudar a suportar uma sintaxe aritmética inline (estupida)
+(declare inline-2-helper)
+(defn clean-arg [arg]
+ (if (seq? arg)
+ (inline-2-helper arg)
+ arg))
+
+(defn apply-arg
+ "Given args [x (+ y)], return (+ x y)"
+ [val [op arg]]
+ (list op val (clean-arg arg)))
+
+(defn inline-2-helper
+ [[arg1 & ops-and-args]]
+ (let [ops (partition 2 ops-and-args)]
+ (reduce apply-arg (clean-arg arg1) ops)))
+
+;; Podemos testar isso imediatamente, sem criar uma macro
+(inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5))
+
+; Entretanto, temos que tornar isso uma macro caso quisermos que isso seja rodado em tempo de compilação
+(defmacro inline-2 [form]
+ (inline-2-helper form)))
+
+(macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1)))
+; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1)
+
+(inline-2 (1 + (3 / 2) - (1 / 2) + 1))
+; -> 3 (Na verdade, 3N, desde que o numero ficou convertido em uma fração racional com /
+
+### Leitura adicional
+
+Escrevendo Macros de [Clojure para o Brave e True](http://www.braveclojure.com/)
+[http://www.braveclojure.com/writing-macros/](http://www.braveclojure.com/writing-macros/)
+
+Documentos oficiais
+[http://clojure.org/macros](http://clojure.org/macros)
+
+Quando utilizar macros?
+[http://dunsmor.com/lisp/onlisp/onlisp_12.html](http://dunsmor.com/lisp/onlisp/onlisp_12.html)
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