Skip to content

refresh of the scala tour #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 2, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions es/tutorials/tour/automatic-closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Scala permite pasar a un método como parámetro funciones que no reciban parám

Para aclarar un poco esto aquí se muestra un ejemplo:

object TargetTest1 extends Application {
object TargetTest1 extends App {
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
if (cond) {
body
Expand All @@ -32,7 +32,7 @@ Es posible combinar el uso de [operadores de infijo y postfijo (infix/postfix)](

Aquí mostramos la implementación de una declaración tipo repetir-a-menos-que (repetir el bucle a no ser que se cumpla X condición):

object TargetTest2 extends Application {
object TargetTest2 extends App {
def loop(body: => Unit): LoopUnlessCond =
new LoopUnlessCond(body)
protected class LoopUnlessCond(body: => Unit) {
Expand Down
10 changes: 6 additions & 4 deletions es/tutorials/tour/case-classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ Para cada una de las clases Case el compilador de Scala genera el método `equal
val y1 = Var("y")
println("" + x1 + " == " + x2 + " => " + (x1 == x2))
println("" + x1 + " == " + y1 + " => " + (x1 == y1))
imprime

imprime

Var(x) == Var(x) => true
Var(x) == Var(y) => false

Solo tiene sentido definir una clase Case si el reconocimiento de patrones es usado para descomponer la estructura de los datos de la clase. El siguiente objeto define define una linda función que imprime en pantalla nuestra representación del cálculo lambda:

object TermTest extends Application {
object TermTest extends scala.App {
def printTerm(term: Term) {
term match {
case Var(n) =>
Expand All @@ -51,7 +53,7 @@ Solo tiene sentido definir una clase Case si el reconocimiento de patrones es us
print("^" + x + ".")
printTerm(b)
case App(f, v) =>
Console.print("(")
print("(")
printTerm(f)
print(" ")
printTerm(v)
Expand All @@ -70,6 +72,6 @@ Solo tiene sentido definir una clase Case si el reconocimiento de patrones es us
println(isIdentityFun(t))
}

En nuestro ejemplo, la función `print` es expresada como una sentencia basada en reconocimiento de patrones, la cual comienza con la palabra reservada `match` y consiste en secuencias de sentencias tipo `case PatronBuscado => Código que se ejecuta`.
En nuestro ejemplo, la función `printTerm` es expresada como una sentencia basada en reconocimiento de patrones, la cual comienza con la palabra reservada `match` y consiste en secuencias de sentencias tipo `case PatronBuscado => Código que se ejecuta`.

El programa de arriba también define una función `isIdentityFun` la cual comprueba si un término dado se corresponde con una función identidad simple. Ese ejemplo utiliza patrones y guardas más avanzados (obsrvese la guarda `if x==y`). Tras reconocer un patrón con un valor dado, la guarda (definida después de la palabra clave `if`) es evaluada. Si retorna `true` (verdadero), el reconocimiento es exitoso; de no ser así, falla y se intenta con el siguiente patrón.
4 changes: 3 additions & 1 deletion es/tutorials/tour/compound-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Algunas veces es necesario expresar que el tipo de un objeto es un subtipo de va
Suponga que tenemos dos traits `Cloneable` y `Resetable`:

trait Cloneable extends java.lang.Cloneable {
override def clone(): Cloneable = { super.clone(); this }
override def clone(): Cloneable = {
super.clone().asInstanceOf[Cloneable]
}
}
trait Resetable {
def reset: Unit
Expand Down
2 changes: 1 addition & 1 deletion es/tutorials/tour/explicitly-typed-self-references.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Por favor nótese que en esta clase nos es posible instanciar `NodoImpl` porque

Aquí hay un ejemplo de uso de la clase `GrafoDirigidoConcreto`:

object GraphTest extends Application {
object GraphTest extends App {
val g: Grafo = new GrafoDirigidoConcreto
val n1 = g.agregarNodo
val n2 = g.agregarNodo
Expand Down
2 changes: 1 addition & 1 deletion es/tutorials/tour/extractor-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ En Scala pueden ser definidos patrones independientemente de las clases Caso. Pa
def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None
}

object TwiceTest extends Application {
object TwiceTest extends App {
val x = Twice(21)
x match { case Twice(n) => Console.println(n) } // imprime 21
}
Expand Down
2 changes: 1 addition & 1 deletion es/tutorials/tour/generic-classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ La clase `Stack` modela una pila mutable que contiene elementos de un tipo arbit

Aquí se muestra un ejemplo del uso de dicha pila:

object GenericsTest extends Application {
object GenericsTest extends App {
val stack = new Stack[Int]
stack.push(1)
stack.push('a')
Expand Down
2 changes: 1 addition & 1 deletion es/tutorials/tour/higher-order-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Otro ejemplo:
def layout[A](x: A) = left + x.toString() + right
}

object FunTest extends Application {
object FunTest extends App {
def apply(f: Int => String, v: Int) = f(v)
val decorator = new Decorator("[", "]")
println(apply(decorator.layout, 7))
Expand Down
5 changes: 2 additions & 3 deletions es/tutorials/tour/implicit-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ En el siguiente ejemplo definimos un método `sum` el cual computa la suma de un
abstract class Monoid[A] extends SemiGroup[A] {
def unit: A
}
object ImplicitTest extends Application {
object ImplicitTest extends App {
implicit object StringMonoid extends Monoid[String] {
def add(x: String, y: String): String = x concat y
def unit: String = ""
Expand All @@ -39,8 +39,7 @@ En el siguiente ejemplo definimos un método `sum` el cual computa la suma de un
println(sum(List(1, 2, 3)))
println(sum(List("a", "b", "c")))
}



Esta es la salida del programa:

6
Expand Down
8 changes: 4 additions & 4 deletions es/tutorials/tour/inner-classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ En Scala es posible que las clases tengan como miembro otras clases. A diferenci

En nuestro programa, los grafos son representados mediante una lista de nodos. Estos nodos son objetos de la clase interna `Node`. Cada nodo tiene una lista de vecinos que se almacena en la lista `connectedNodes`. Ahora podemos crear un grafo con algunos nodos y conectarlos incrementalmente:

object GraphTest extends Application {
object GraphTest extends App {
val g = new Graph
val n1 = g.newNode
val n2 = g.newNode
Expand All @@ -41,7 +41,7 @@ En nuestro programa, los grafos son representados mediante una lista de nodos. E

Ahora vamos a completar el ejemplo con información relacionada al tipado para definir explicitamente de qué tipo son las entidades anteriormente definidas:

object GraphTest extends Application {
object GraphTest extends App {
val g: Graph = new Graph
val n1: g.Node = g.newNode
val n2: g.Node = g.newNode
Expand All @@ -54,7 +54,7 @@ El código anterior muestra que al tipo del nodo le es prefijado con la instanci

Aquí está el programa ilegal:

object IllegalGraphTest extends Application {
object IllegalGraphTest extends App {
val g: Graph = new Graph
val n1: g.Node = g.newNode
val n2: g.Node = g.newNode
Expand Down Expand Up @@ -83,4 +83,4 @@ Por favor note que en Java la última linea del ejemplo anterior hubiese sido co
}
}

> Por favor note que este programa no nos permite relacionar un nodo con dos grafos diferentes. Si también quisiéramos eliminar esta restricción, sería necesario cambiar el tipo de la variable `nodes` y el tipo retornado por el método `newNode` a `Graph#Node`.
> Por favor note que este programa no nos permite relacionar un nodo con dos grafos diferentes. Si también quisiéramos eliminar esta restricción, sería necesario cambiar el tipo de la variable `nodes` a `Graph#Node`.
10 changes: 5 additions & 5 deletions es/tutorials/tour/local-type-inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Scala tiene incorporado un mecanismo de inferencia de tipos el cual permite al p

Aquí hay un ejemplo:

object InferenceTest1 extends Application {
object InferenceTest1 extends App {
val x = 1 + 2 * 3 // el tipo de x es Int
val y = x.toString() // el tipo de y es String
def succ(x: Int) = x + 1 // el método succ retorna valores Int
Expand All @@ -30,15 +30,15 @@ Tampoco es obligatorio especificar el tipo de los parámetros cuando se trate de
Aquí se muestra un ejemplo que ilustra esto:

case class MyPair[A, B](x: A, y: B);
object InferenceTest3 extends Application {
object InferenceTest3 extends App {
def id[T](x: T) = x
val p = new MyPair(1, "scala") // tipo: MyPair[Int, String]
val q = id(1) // tipo: Int
val p = MyPair(1, "scala") // tipo: MyPair[Int, String]
val q = id(1) // tipo: Int
}

Las últimas dos lineas de este programa son equivalentes al siguiente código, donde todos los tipos inferidos son especificados explicitamente:

val x: MyPair[Int, String] = new MyPair[Int, String](1, "scala")
val x: MyPair[Int, String] = MyPair[Int, String](1, "scala")
val y: Int = id[Int](1)

En algunas situaciones puede ser bastante peligroso confira en el mecanismo de inferencia de tipos de Scala, como se ilustra en el siguiente ejemplo:
Expand Down
2 changes: 1 addition & 1 deletion es/tutorials/tour/lower-type-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ _Nota: el nuevo método `prepend` tiene un tipo un poco menos restrictivo. Esto

Este código ilustra el concepto:

object LowerBoundTest extends Application {
object LowerBoundTest extends App {
val empty: ListNode[Null] = ListNode(null, null)
val strList: ListNode[String] = empty.prepend("hello")
.prepend("world")
Expand Down
2 changes: 1 addition & 1 deletion es/tutorials/tour/nested-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ language: es

En scala es posible anidar definiciones de funciones. El siguiente objeto provee una función `filter` para extraer valores de una lista de enteros que están por debajo de un determinado valor:

object FilterTest extends Application {
object FilterTest extends App {
def filter(xs: List[Int], threshold: Int) = {
def process(ys: List[Int]): List[Int] =
if (ys.isEmpty) ys
Expand Down
4 changes: 2 additions & 2 deletions es/tutorials/tour/pattern-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Here is a small example which shows how to match against an integer value:

Scala tiene incorporado un mecanismo general de reconocimiento de patrones. Este permite identificar cualquier tipo de datos una política primero-encontrado. Aquí se muestra un pequeño ejemplo el cual muestra cómo coincidir un valor entero:

object MatchTest1 extends Application {
object MatchTest1 extends App {
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
Expand All @@ -29,7 +29,7 @@ El bloque con las sentencias `case` define una función la cual mapea enteros a

Aquí se muestra un ejemplo el cual machea un valor contra un patrón de diferentes tipos:

object MatchTest2 extends Application {
object MatchTest2 extends App {
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
Expand Down
5 changes: 3 additions & 2 deletions es/tutorials/tour/polymorphic-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Los métodos en Scala pueden ser parametrizados tanto con valores como con tipos

Aquí hay un ejemplo:

object PolyTest extends Application {
object PolyTest extends App {
def dup[T](x: T, n: Int): List[T] =
if (n == 0) Nil
else x :: dup(x, n - 1)
Expand All @@ -22,4 +22,5 @@ Aquí hay un ejemplo:
}

El método `dup` en el objeto `PolyTest` es parametrizado con el tipo `T` y con los parámetros `x: T` y `n: Int`. Cuando el método `dup` es llamado, el programador provee los parámetros requeridos _(vea la linea 5 del programa anterior)_, pero como se muestra en la linea 6 no es necesario que se provea el parámetro de tipo `T` explicitamente. El sistema de tipado de Scala puede inferir estos tipos. Esto es realizado a través de la observación del tipo de los parámetros pasados y del contexto donde el método es invocado.
Por favor note que el trait `Application` está diseñado para escribir programas cortos de testeo, pero debe ser evitado en código en producción (para versiones de Scala 2.8.x y anteriores) ya que puede afectar la habilidad de la JVM de optimizar el código resultante; por favor use `def main()` en su lugar.

Por favor note que el trait `App` está diseñado para escribir programas cortos de testeo, pero debe ser evitado en código en producción (para versiones de Scala 2.8.x y anteriores) ya que puede afectar la habilidad de la JVM de optimizar el código resultante; por favor use `def main()` en su lugar.
2 changes: 1 addition & 1 deletion es/tutorials/tour/regular-expression-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Los patrones de secuencias que ignoran a la derecha son una característica úti

En esos casos, Scala permite a los patrones que utilicen el cómodin `_*` en la posición más a la derecha que tomen lugar para secuencias arbitrariamente largas. El siguiente ejemplo demuestra un reconocimiento de patrones el cual identifica un prefijo de una secuencia y liga el resto a la variable `rest`.

object RegExpTest1 extends Application {
object RegExpTest1 extends App {
def containsScala(x: String): Boolean = {
val z: Seq[Char] = x
z match {
Expand Down
11 changes: 6 additions & 5 deletions es/tutorials/tour/sequence-comprehensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Scala cuenta con una notación ligera para expresar *sequencias por comprensión

Aquí hay un ejemplo:

object ComprehensionTest1 extends Application {
object ComprehensionTest1 extends App {
def pares(desde: Int, hasta: Int): List[Int] =
for (i <- List.range(desde, hasta) if i % 2 == 0) yield i
Console.println(pares(0, 20))
Expand All @@ -27,10 +27,10 @@ El programa produce los siguientes valores

Aquí se muestra un ejemplo más complicado que computa todos los pares de números entre `0` y `n-1` cuya suma es igual a un número dado `v`:

object ComprehensionTest2 extends Application {
object ComprehensionTest2 extends App {
def foo(n: Int, v: Int) =
for (i <- 0 until n;
j <- i + 1 until n if i + j == v) yield
j <- i until n if i + j == v) yield
Pair(i, j);
foo(20, 32) foreach {
case (i, j) =>
Expand All @@ -45,12 +45,13 @@ Esta es la salida del programa:
(13, 19)
(14, 18)
(15, 17)
(16, 16)

Existe también una forma especial de comprensión de secuencias la cual retorna `Unit`. En este caso las variables que son creadas por la lista de generadores y filtros son usados para realizar tareas con efectos colaterales (modificaciones de algún tipo). El programador tiene que omitir la palabra reservada `yield` para usar una comprensión de este tipo.

object ComprehensionTest3 extends Application {
object ComprehensionTest3 extends App {
for (i <- Iterator.range(0, 20);
j <- Iterator.range(i + 1, 20) if i + j == 32)
j <- Iterator.range(i, 20) if i + j == 32)
println("(" + i + ", " + j + ")")
}

28 changes: 13 additions & 15 deletions es/tutorials/tour/unified-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,25 @@ La superclase de todas las clases, `scala.Any`, tiene dos subclases directas, `s
Por favor note que el diagrama superior también muestra conversiones implícitas llamadas viestas entre las clases para valores.
Aquí se muestra un ejemplo que demuestra que tanto valores numéricos, de caracteres, buleanos y funciones son objetos, tal como cualquier otro objeto:

object UnifiedTypes {
def main(args: Array[String]) {
val set = new scala.collection.mutable.HashSet[Any]
set += "This is a string" // suma un String
set += 732 // suma un número
set += 'c' // suma un caracter
set += true // suma un valor booleano
set += main _ // suma la función main
val iter: Iterator[Any] = set.elements
while (iter.hasNext) {
println(iter.next.toString())
}
object UnifiedTypes extends App {
val set = new scala.collection.mutable.LinkedHashSet[Any]
set += "This is a string" // suma un String
set += 732 // suma un número
set += 'c' // suma un caracter
set += true // suma un valor booleano
set += main _ // suma la función main
val iter: Iterator[Any] = set.iterator
while (iter.hasNext) {
println(iter.next.toString())
}
}

El programa declara una aplicación `UnifiedTypes` en forma de un objeto singleton de primer nive con un método `main`. El método main define una variable local `set` (un conjunto), la cual se refiere a una instancia de la clase `HashSet[Any]`. El programa suma varios elementos a este conjunto. Los elementos tienen que cumplir con el tipo declarado para los elementos por el conjunto, que es `Any`. En el final, una representación en texto (cadena de caracteres, o string) es impresa en pantalla.
El programa declara una aplicación `UnifiedTypes` en forma de un objeto singleton de primer nive con un método `main`. El aplicación define una variable local `set` (un conjunto), la cual se refiere a una instancia de la clase `LinkedHashSet[Any]`. El programa suma varios elementos a este conjunto. Los elementos tienen que cumplir con el tipo declarado para los elementos por el conjunto, que es `Any`. En el final, una representación en texto (cadena de caracteres, o string) es impresa en pantalla.

Aquí se muestra la salida del programa:

This is a string
732
c
true
<function>
732
This is a string
2 changes: 1 addition & 1 deletion es/tutorials/tour/upper-type-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Aquí se muestra un ejemplo el cual se basa en un límite de tipado superior par
m.isInstanceOf[MyInt] &&
m.asInstanceOf[MyInt].x == x
}
object UpperBoundTest extends Application {
object UpperBoundTest extends App {
def findSimilar[T <: Similar](e: T, xs: List[T]): Boolean =
if (xs.isEmpty) false
else if (e.isSimilar(xs.head)) true
Expand Down
10 changes: 5 additions & 5 deletions es/tutorials/tour/variances.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ num: 31
language: es
---

Scala soporta anotaciones de varianza para parámetros de tipo para [clases genéricas.](generic-classes.html). A diferencia de Java 5 (es decir: [JDK 1.5](http://java.sun.com/j2se/1.5/)), las anotaciones de varianza pueden ser agregadas cuando una abstracción de clase es definidia, mientras que en Java 5, las anotaciones de varianza son dadas por los clientes cuando una albstracción de clase es usada.
Scala soporta anotaciones de varianza para parámetros de tipo para [clases genéricas](generic-classes.html). A diferencia de Java 5 (es decir: [JDK 1.5](http://java.sun.com/j2se/1.5/)), las anotaciones de varianza pueden ser agregadas cuando una abstracción de clase es definidia, mientras que en Java 5, las anotaciones de varianza son dadas por los clientes cuando una albstracción de clase es usada.

In the page about generic classes an example for a mutable stack was given. We explained that the type defined by the class `Stack[T]` is subject to invariant subtyping regarding the type parameter. This can restrict the reuse of the class abstraction. We now derive a functional (i.e. immutable) implementation for stacks which does not have this restriction. Please note that this is an advanced example which combines the use of [polymorphic methods](polymorphic-methods.html), [lower type bounds](lower-type-bounds.html), and covariant type parameter annotations in a non-trivial fashion. Furthermore we make use of [inner classes](inner-classes.html) to chain the stack elements without explicit links.

Expand All @@ -22,16 +22,16 @@ En el artículo sobre clases genéricas dimos un ejemplo de una pila mutable. Ex
override def toString() = elem.toString() + " " +
Stack.this.toString()
}
def top: A = error("no element on stack")
def pop: Stack[A] = error("no element on stack")
def top: A = sys.error("no element on stack")
def pop: Stack[A] = sys.error("no element on stack")
override def toString() = ""
}

object VariancesTest extends Application {
object VariancesTest extends App {
var s: Stack[Any] = new Stack().push("hello");
s = s.push(new Object())
s = s.push(7)
Console.println(s)
println(s)
}

La anotación `+T` declara que el tipo `T` sea utilizado solamente en posiciones covariantes. De forma similar, `-T` declara que `T` sea usado en posiciones contravariantes. Para parámetros de tipo covariantes obtenemos una relación de subtipo covariante con respecto al parámetro de tipo. Para nuestro ejemplo, esto significa que `Stack[T]` es un subtipo de `Stack[S]` si `T` es un subtipo de `S`. Lo contrario se cumple para parámetros de tipo que son etiquetados con un signo `-`.
Expand Down
Loading