diff --git a/es/tutorials/tour/automatic-closures.md b/es/tutorials/tour/automatic-closures.md index 8077a25814..f45f4a46e9 100644 --- a/es/tutorials/tour/automatic-closures.md +++ b/es/tutorials/tour/automatic-closures.md @@ -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 @@ -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) { diff --git a/es/tutorials/tour/case-classes.md b/es/tutorials/tour/case-classes.md index 252092374c..d56b7a4667 100644 --- a/es/tutorials/tour/case-classes.md +++ b/es/tutorials/tour/case-classes.md @@ -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) => @@ -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) @@ -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. diff --git a/es/tutorials/tour/compound-types.md b/es/tutorials/tour/compound-types.md index 3e92865bfa..849c59aba4 100644 --- a/es/tutorials/tour/compound-types.md +++ b/es/tutorials/tour/compound-types.md @@ -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 diff --git a/es/tutorials/tour/default_parameter_values.md b/es/tutorials/tour/default-parameter-values.md similarity index 100% rename from es/tutorials/tour/default_parameter_values.md rename to es/tutorials/tour/default-parameter-values.md diff --git a/es/tutorials/tour/explicitly-typed-self-references.md b/es/tutorials/tour/explicitly-typed-self-references.md index 41aee17540..fdf7dcf43f 100644 --- a/es/tutorials/tour/explicitly-typed-self-references.md +++ b/es/tutorials/tour/explicitly-typed-self-references.md @@ -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 diff --git a/es/tutorials/tour/extractor-objects.md b/es/tutorials/tour/extractor-objects.md index 65632e0595..c4f027ecd8 100644 --- a/es/tutorials/tour/extractor-objects.md +++ b/es/tutorials/tour/extractor-objects.md @@ -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 } diff --git a/es/tutorials/tour/generic-classes.md b/es/tutorials/tour/generic-classes.md index 11ea01bc9e..cacbc7ed33 100644 --- a/es/tutorials/tour/generic-classes.md +++ b/es/tutorials/tour/generic-classes.md @@ -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') diff --git a/es/tutorials/tour/higher-order-functions.md b/es/tutorials/tour/higher-order-functions.md index dd51665471..84ac705f7b 100644 --- a/es/tutorials/tour/higher-order-functions.md +++ b/es/tutorials/tour/higher-order-functions.md @@ -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)) diff --git a/es/tutorials/tour/implicit-parameters.md b/es/tutorials/tour/implicit-parameters.md index 3a80a74a87..c95cdf8273 100644 --- a/es/tutorials/tour/implicit-parameters.md +++ b/es/tutorials/tour/implicit-parameters.md @@ -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 = "" @@ -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 diff --git a/es/tutorials/tour/inner-classes.md b/es/tutorials/tour/inner-classes.md index bd2cc5e6c2..2e0ae52611 100644 --- a/es/tutorials/tour/inner-classes.md +++ b/es/tutorials/tour/inner-classes.md @@ -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 @@ -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 @@ -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 @@ -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`. diff --git a/es/tutorials/tour/local-type-inference.md b/es/tutorials/tour/local-type-inference.md index e63795a3c3..af9dbaa1f6 100644 --- a/es/tutorials/tour/local-type-inference.md +++ b/es/tutorials/tour/local-type-inference.md @@ -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 @@ -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: diff --git a/es/tutorials/tour/lower-type-bounds.md b/es/tutorials/tour/lower-type-bounds.md index 512cd93811..9b52f215cc 100644 --- a/es/tutorials/tour/lower-type-bounds.md +++ b/es/tutorials/tour/lower-type-bounds.md @@ -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") diff --git a/es/tutorials/tour/named_parameters.md b/es/tutorials/tour/named-parameters.md similarity index 100% rename from es/tutorials/tour/named_parameters.md rename to es/tutorials/tour/named-parameters.md diff --git a/es/tutorials/tour/nested-functions.md b/es/tutorials/tour/nested-functions.md index 9a2f963979..f3e04e5bf4 100644 --- a/es/tutorials/tour/nested-functions.md +++ b/es/tutorials/tour/nested-functions.md @@ -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 diff --git a/es/tutorials/tour/pattern-matching.md b/es/tutorials/tour/pattern-matching.md index e1d3f4f88d..ad78092582 100644 --- a/es/tutorials/tour/pattern-matching.md +++ b/es/tutorials/tour/pattern-matching.md @@ -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" @@ -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 diff --git a/es/tutorials/tour/polymorphic-methods.md b/es/tutorials/tour/polymorphic-methods.md index d52b1c0576..79c48344e9 100644 --- a/es/tutorials/tour/polymorphic-methods.md +++ b/es/tutorials/tour/polymorphic-methods.md @@ -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) @@ -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. diff --git a/es/tutorials/tour/regular-expression-patterns.md b/es/tutorials/tour/regular-expression-patterns.md index b3f3969dbc..724254d224 100644 --- a/es/tutorials/tour/regular-expression-patterns.md +++ b/es/tutorials/tour/regular-expression-patterns.md @@ -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 { diff --git a/es/tutorials/tour/sequence-comprehensions.md b/es/tutorials/tour/sequence-comprehensions.md index 1603fc468a..0400c5424a 100644 --- a/es/tutorials/tour/sequence-comprehensions.md +++ b/es/tutorials/tour/sequence-comprehensions.md @@ -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)) @@ -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) => @@ -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 + ")") } diff --git a/es/tutorials/tour/unified-types.md b/es/tutorials/tour/unified-types.md index 006343e531..4a5acf7446 100644 --- a/es/tutorials/tour/unified-types.md +++ b/es/tutorials/tour/unified-types.md @@ -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 - 732 - This is a string diff --git a/es/tutorials/tour/upper-type-bounds.md b/es/tutorials/tour/upper-type-bounds.md index c943e4ddba..fb29afc307 100644 --- a/es/tutorials/tour/upper-type-bounds.md +++ b/es/tutorials/tour/upper-type-bounds.md @@ -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 diff --git a/es/tutorials/tour/variances.md b/es/tutorials/tour/variances.md index b944fc6943..d0c0b75a47 100644 --- a/es/tutorials/tour/variances.md +++ b/es/tutorials/tour/variances.md @@ -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. @@ -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 `-`. diff --git a/es/tutorials/tour/views.md b/es/tutorials/tour/views.md index b6e915cb7e..db156b4a03 100644 --- a/es/tutorials/tour/views.md +++ b/es/tutorials/tour/views.md @@ -9,13 +9,14 @@ num: 32 language: es --- -[Parámetros implícitos](implicit-parameters.html) y métodos también pueden definir conversiones implícitas llamadas _vistas_. Una vista de tipo `S` a `T` es definida por un valor implícito que tiene una función del tipo `S => T`, o por un método convertible a un valor de tal tipo. +[Parámetros implícitos](implicit-parameters.html) y métodos también pueden definir conversiones implícitas llamadas _vistas_. Una vista de tipo `S` a `T` es definida por un valor implícito que tiene una función del tipo `S => T`, o por un método implícito convertible a un valor de tal tipo. Las vistas son aplicadas en dos situaciones: -* Si una expresión `e` es de tipo `T`, y `T` no se ajusta al tipo esperado de la expresión `pt`. +* Si una expresión `e` es de tipo `S`, y `S` no se ajusta al tipo esperado de la expresión `T`. * En una selección `e.m` con `e` de tipo `T`, si el selector `m` no es un miembro de `T`. -En el primer caso, una vista `v` es buscada la cual sea aplicable a `e` y cuyo tipo resultado se ajusta a `pt`. En el segundo caso, una vista `v` es buscada para la cual sea aplicable a `e` y cuyor resultado contenga un miembro llamado `m`. +En el primer caso, una vista `v` es buscada la cual sea aplicable a `e` y cuyo tipo resultado se ajusta a `T`. +En el segundo caso, una vista `v` es buscada para la cual sea aplicable a `e` y cuyor resultado contenga un miembro llamado `m`. La siguiente operación entre las dos listas `xs` y `ys` de tipo `List[Int]` es legal: @@ -36,7 +37,7 @@ La función `list2ordered` puede ser también expresada con el uso de un _límit El compilador de Scala que genera después genera el código equivalente a la definición de `list2ordered` vista anteriormente. -El objeto `scala.Predef` importado implicitamente declara varios tipos predefinidos (ej. `Pair`) and métodos (ej. `error`) pero también varias vistas. El siguiente ejemplo muestra una idea de la vista predefinida `charWrapper`: +El objeto `scala.Predef` importado implicitamente declara varios tipos predefinidos (ej. `Pair`) and métodos (ej. `assert`) pero también varias vistas. El siguiente ejemplo muestra una idea de la vista predefinida `charWrapper`: final class RichChar(c: Char) { def isDigit: Boolean = Character.isDigit(c) diff --git a/es/tutorials/tour/xml-processing.md b/es/tutorials/tour/xml-processing.md index 627db96cfe..abb605016a 100644 --- a/es/tutorials/tour/xml-processing.md +++ b/es/tutorials/tour/xml-processing.md @@ -28,7 +28,7 @@ Considera la siguiente documento XMl: Este documento puede ser creado por el siguiente programa en Scala: - object XMLTest1 extends Application { + object XMLTest1 extends App { val page = @@ -44,7 +44,7 @@ Este documento puede ser creado por el siguiente programa en Scala: Es posible mezclar expresiones Scala y XML: - object XMLTest2 extends Application { + object XMLTest2 extends App { import scala.xml._ val df = java.text.DateFormat.getDateInstance() val dateString = df.format(new java.util.Date()) diff --git a/tutorials/tour/automatic-closures.md b/tutorials/tour/automatic-closures.md index 2e83bc16d5..78b254ea84 100644 --- a/tutorials/tour/automatic-closures.md +++ b/tutorials/tour/automatic-closures.md @@ -12,7 +12,7 @@ Scala allows parameterless function names as parameters of methods. When such a The following code demonstrates this mechanism: - object TargetTest1 extends Application { + object TargetTest1 extends App { def whileLoop(cond: => Boolean)(body: => Unit): Unit = if (cond) { body @@ -25,13 +25,13 @@ The following code demonstrates this mechanism: } } -The function whileLoop takes two parameters `cond` and `body`. When the function is applied, the actual parameters do not get evaluated. But whenever the formal parameters are used in the body of `whileLoop`, the implicitly created nullary functions will be evaluated instead. Thus, our method `whileLoop` implements a Java-like while-loop with a recursive implementation scheme. +The function `whileLoop` takes two parameters `cond` and `body`. When the function is applied, the actual parameters do not get evaluated. But whenever the formal parameters are used in the body of `whileLoop`, the implicitly created nullary functions will be evaluated instead. Thus, our method `whileLoop` implements a Java-like while-loop with a recursive implementation scheme. We can combine the use of [infix/postfix operators](operators.html) with this mechanism to create more complex statements (with a nice syntax). Here is the implementation of a loop-unless statement: - object TargetTest2 extends Application { + object TargetTest2 extends App { def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body) protected class LoopUnlessCond(body: => Unit) { diff --git a/tutorials/tour/case-classes.md b/tutorials/tour/case-classes.md index 5a9d998da0..28f4ba3297 100644 --- a/tutorials/tour/case-classes.md +++ b/tutorials/tour/case-classes.md @@ -35,13 +35,15 @@ For every case class the Scala compiler generates an `equals` method which imple val y1 = Var("y") println("" + x1 + " == " + x2 + " => " + (x1 == x2)) println("" + x1 + " == " + y1 + " => " + (x1 == y1)) - will print + +will print + Var(x) == Var(x) => true Var(x) == Var(y) => false It makes only sense to define case classes if pattern matching is used to decompose data structures. The following object defines a pretty printer function for our lambda calculus representation: - object TermTest extends Application { + object TermTest extends scala.App { def printTerm(term: Term) { term match { case Var(n) => @@ -50,7 +52,7 @@ It makes only sense to define case classes if pattern matching is used to decomp print("^" + x + ".") printTerm(b) case App(f, v) => - Console.print("(") + print("(") printTerm(f) print(" ") printTerm(v) @@ -69,5 +71,5 @@ It makes only sense to define case classes if pattern matching is used to decomp println(isIdentityFun(t)) } -In our example, the function `print` is expressed as a pattern matching statement starting with the `match` keyword and consisting of sequences of `case Pattern => Body` clauses. +In our example, the function `printTerm` is expressed as a pattern matching statement starting with the `match` keyword and consisting of sequences of `case Pattern => Body` clauses. The program above also defines a function `isIdentityFun` which checks if a given term corresponds to a simple identity function. This example uses deep patterns and guards. After matching a pattern with a given value, the guard (defined after the keyword `if`) is evaluated. If it returns `true`, the match succeeds; otherwise, it fails and the next pattern will be tried. diff --git a/tutorials/tour/compound-types.md b/tutorials/tour/compound-types.md index 30eff21a44..d82bc865f0 100644 --- a/tutorials/tour/compound-types.md +++ b/tutorials/tour/compound-types.md @@ -13,7 +13,9 @@ Sometimes it is necessary to express that the type of an object is a subtype of Suppose we have two traits `Cloneable` and `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 diff --git a/tutorials/tour/default_parameter_values.md b/tutorials/tour/default-parameter-values.md similarity index 100% rename from tutorials/tour/default_parameter_values.md rename to tutorials/tour/default-parameter-values.md diff --git a/tutorials/tour/explicitly-typed-self-references.md b/tutorials/tour/explicitly-typed-self-references.md index 5c137adf6c..7359b80fa6 100644 --- a/tutorials/tour/explicitly-typed-self-references.md +++ b/tutorials/tour/explicitly-typed-self-references.md @@ -23,9 +23,9 @@ Here is a definition describing graphs: def addNode: Node } -Graphs consist of a list of nodes and edges where both the node and the edge type are left abstract. The use of [abstract types](abstract-types.html) allows implementations of trait Graph to provide their own concrete classes for nodes and edges. Furthermore, there is a method `addNode` for adding new nodes to a graph. Nodes are connected using `methodconnectWith`. +Graphs consist of a list of nodes and edges where both the node and the edge type are left abstract. The use of [abstract types](abstract-types.html) allows implementations of trait Graph to provide their own concrete classes for nodes and edges. Furthermore, there is a method `addNode` for adding new nodes to a graph. Nodes are connected using method `connectWith`. -A possible implementation of class `Graph` is given in the next program: +A possible implementation of class `Graph` is given in the next class: abstract class DirectedGraph extends Graph { type Edge <: EdgeImpl @@ -51,9 +51,9 @@ A possible implementation of class `Graph` is given in the next program: } } -Class `DirectedGraph` specializes the `Graph` class by providing a partial implementation. The implementation is only partial, because we would like to be able to extend `DirectedGraph` further. Therefore this class leaves all implementation details open and thus both the edge and the node type are left abstract. Nevertheless, class `DirectedGraph` reveals some additional details about the implementation of the edge type by tightening the bound to class `EdgeImpl`. Furthermore, we have some preliminary implementations of edges and nodes represented by the classes `EdgeImpl` and `NodeImpl`. Since it is necessary to create new node and edge objects within our partial graph implementation, we also have to add the factory methods `newNode` and `newEdge`. The methods `addNode` and `connectWith` are both defined in terms of these factory methods. A closer look at the implementation of method `connectWith` reveals that for creating an edge, we have to pass the self reference `this` to the factory method `newEdge`. But this is assigned the type `NodeImpl`, so it's not compatible with type `Node` which is required by the corresponding factory method. As a consequence, the program above is not well-formed and the Scala compiler will issue an error message. +Class `DirectedGraph` specializes the `Graph` class by providing a partial implementation. The implementation is only partial, because we would like to be able to extend `DirectedGraph` further. Therefore this class leaves all implementation details open and thus both the edge and the node type are left abstract. Nevertheless, class `DirectedGraph` reveals some additional details about the implementation of the edge type by tightening the bound to class `EdgeImpl`. Furthermore, we have some preliminary implementations of edges and nodes represented by the classes `EdgeImpl` and `NodeImpl`. Since it is necessary to create new node and edge objects within our partial graph implementation, we also have to add the factory methods `newNode` and `newEdge`. The methods `addNode` and `connectWith` are both defined in terms of these factory methods. A closer look at the implementation of method `connectWith` reveals that for creating an edge, we have to pass the self reference `this` to the factory method `newEdge`. But `this` is assigned the type `NodeImpl`, so it's not compatible with type `Node` which is required by the corresponding factory method. As a consequence, the program above is not well-formed and the Scala compiler will issue an error message. -In Scala it is possible to tie a class to another type (which will be implemented in future) by giving self reference thisthe other type explicitly. We can use this mechanism for fixing our code above. The explicit self type is specified within the body of the class `DirectedGraph`. +In Scala it is possible to tie a class to another type (which will be implemented in future) by giving self reference `this` the other type explicitly. We can use this mechanism for fixing our code above. The explicit self type is specified within the body of the class `DirectedGraph`. Here is the fixed program: @@ -86,7 +86,7 @@ Please note that in this class, we can instantiate `NodeImpl` because now we kno Here is a usage example of class `ConcreteDirectedGraph`: - object GraphTest extends Application { + object GraphTest extends App { val g: Graph = new ConcreteDirectedGraph val n1 = g.addNode val n2 = g.addNode diff --git a/tutorials/tour/extractor-objects.md b/tutorials/tour/extractor-objects.md index 7776ef1a1b..c5d63d96dd 100644 --- a/tutorials/tour/extractor-objects.md +++ b/tutorials/tour/extractor-objects.md @@ -15,7 +15,7 @@ In Scala, patterns can be defined independently of case classes. To this end, a 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) } // prints 21 } diff --git a/tutorials/tour/generic-classes.md b/tutorials/tour/generic-classes.md index 1e91653372..751166ec54 100644 --- a/tutorials/tour/generic-classes.md +++ b/tutorials/tour/generic-classes.md @@ -22,7 +22,7 @@ Class `Stack` models imperative (mutable) stacks of an arbitrary element type `T Here are some usage examples: - object GenericsTest extends Application { + object GenericsTest extends App { val stack = new Stack[Int] stack.push(1) stack.push('a') diff --git a/tutorials/tour/higher-order-functions.md b/tutorials/tour/higher-order-functions.md index aff90b01f1..f5e58dba13 100644 --- a/tutorials/tour/higher-order-functions.md +++ b/tutorials/tour/higher-order-functions.md @@ -20,7 +20,7 @@ Here is another example: 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)) diff --git a/tutorials/tour/implicit-parameters.md b/tutorials/tour/implicit-parameters.md index 8f0ba9e3bd..19e775821f 100644 --- a/tutorials/tour/implicit-parameters.md +++ b/tutorials/tour/implicit-parameters.md @@ -14,7 +14,7 @@ The actual arguments that are eligible to be passed to an implicit parameter fal * First, eligible are all identifiers x that can be accessed at the point of the method call without a prefix and that denote an implicit definition or an implicit parameter. * Second, eligible are also all members of companion modules of the implicit parameter's type that are labeled implicit. -In the following example we define a method `sum` which computes the sum of a list of elements using the monoid's add and unit operations. Please note that implicit values can not be top-level, they have to be members of a template. +In the following example we define a method `sum` which computes the sum of a list of elements using the monoid's `add` and `unit` operations. Please note that implicit values can not be top-level, they have to be members of a template. abstract class SemiGroup[A] { def add(x: A, y: A): A @@ -22,7 +22,7 @@ In the following example we define a method `sum` which computes the sum of a li 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 = "" @@ -38,8 +38,7 @@ In the following example we define a method `sum` which computes the sum of a li println(sum(List(1, 2, 3))) println(sum(List("a", "b", "c"))) } - - + Here is the output of the Scala program: 6 diff --git a/tutorials/tour/inner-classes.md b/tutorials/tour/inner-classes.md index 425af12dca..9b23d86df2 100644 --- a/tutorials/tour/inner-classes.md +++ b/tutorials/tour/inner-classes.md @@ -29,7 +29,7 @@ In Scala it is possible to let classes have other classes as members. Opposed to In our program, graphs are represented by a list of nodes. Nodes are objects of inner class `Node`. Each node has a list of neighbours, which get stored in the list `connectedNodes`. Now we can set up a graph with some nodes and connect the nodes incrementally: - object GraphTest extends Application { + object GraphTest extends App { val g = new Graph val n1 = g.newNode val n2 = g.newNode @@ -38,9 +38,9 @@ In our program, graphs are represented by a list of nodes. Nodes are objects of n3.connectTo(n1) } -We now enrich the following example with types to state explicitly what the type of the various defined entities is: +We now enrich the above example with types to state explicitly what the type of the various defined entities is: - 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 @@ -49,10 +49,10 @@ We now enrich the following example with types to state explicitly what the type n3.connectTo(n1) } -This code clearly shows that a node type is prefixed with its outer instance (which is object g in our example). If we now have two graphs, the type system of Scala does not allow us to mix nodes defined within one graph with the nodes of another graph, since the nodes of the other graph have a different type. +This code clearly shows that a node type is prefixed with its outer instance (which is object `g` in our example). If we now have two graphs, the type system of Scala does not allow us to mix nodes defined within one graph with the nodes of another graph, since the nodes of the other graph have a different type. Here is an illegal program: - 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 @@ -81,4 +81,4 @@ Please note that in Java the last line in the previous example program would hav } } -> Please note that this program doesn't allow us to attach a node to two different graphs. If we want to remove this restriction as well, we have to change the type of variable nodes and the return type of method `newNode` to `Graph#Node`. +> Please note that this program doesn't allow us to attach a node to two different graphs. If we want to remove this restriction as well, we have to change the type of variable nodes to `Graph#Node`. diff --git a/tutorials/tour/local-type-inference.md b/tutorials/tour/local-type-inference.md index 2979324238..ed413fbf69 100644 --- a/tutorials/tour/local-type-inference.md +++ b/tutorials/tour/local-type-inference.md @@ -11,7 +11,7 @@ Scala has a built-in type inference mechanism which allows the programmer to omi Here is an example: - object InferenceTest1 extends Application { + object InferenceTest1 extends App { val x = 1 + 2 * 3 // the type of x is Int val y = x.toString() // the type of y is String def succ(x: Int) = x + 1 // method succ returns Int values @@ -28,15 +28,15 @@ It is also not compulsory to specify type parameters when [polymorphic methods]( Here is an example which illustrates this: 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") // type: MyPair[Int, String] - val q = id(1) // type: Int + val p = MyPair(1, "scala") // type: MyPair[Int, String] + val q = id(1) // type: Int } The last two lines of this program are equivalent to the following code where all inferred types are made explicit: - 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) In some situations it can be quite dangerous to rely on Scala's type inference mechanism as the following program shows: diff --git a/tutorials/tour/lower-type-bounds.md b/tutorials/tour/lower-type-bounds.md index 28e77dc359..3a3632c83a 100644 --- a/tutorials/tour/lower-type-bounds.md +++ b/tutorials/tour/lower-type-bounds.md @@ -38,7 +38,7 @@ _Note:_ the new `prepend` method has a slightly less restrictive type. It allows Here is some code which illustrates this: - object LowerBoundTest extends Application { + object LowerBoundTest extends App { val empty: ListNode[Null] = ListNode(null, null) val strList: ListNode[String] = empty.prepend("hello") .prepend("world") diff --git a/tutorials/tour/named_parameters.md b/tutorials/tour/named-parameters.md similarity index 100% rename from tutorials/tour/named_parameters.md rename to tutorials/tour/named-parameters.md diff --git a/tutorials/tour/nested-functions.md b/tutorials/tour/nested-functions.md index e344f36b9c..a6235b54fc 100644 --- a/tutorials/tour/nested-functions.md +++ b/tutorials/tour/nested-functions.md @@ -10,7 +10,7 @@ num: 13 In Scala it is possible to nest function definitions. The following object provides a `filter` function for extracting values from a list of integers that are below a threshold value: - 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 diff --git a/tutorials/tour/operators.md b/tutorials/tour/operators.md index f573c73ae1..68d49c7888 100644 --- a/tutorials/tour/operators.md +++ b/tutorials/tour/operators.md @@ -21,7 +21,7 @@ It is now possible to use `and` and `or` as infix operators: def not(x: MyBool) = x negate; // semicolon required here def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) -As the first line of this code shows, it is also possible to use nullary methods as postfix operators. The second line defines an xor function using the and and or methods as well as the new `not` function. In this example the use of _infix operators_ helps to make the definition of `xor` more readable. +As the first line of this code shows, it is also possible to use nullary methods as postfix operators. The second line defines an `xor` function using the `and` and `or` methods as well as the new `not` function. In this example the use of _infix operators_ helps to make the definition of `xor` more readable. Here is the corresponding code in a more traditional object-oriented programming language syntax: diff --git a/tutorials/tour/pattern-matching.md b/tutorials/tour/pattern-matching.md index 53ede06e4b..5f8a527bd5 100644 --- a/tutorials/tour/pattern-matching.md +++ b/tutorials/tour/pattern-matching.md @@ -11,7 +11,7 @@ num: 20 Scala has a built-in general pattern matching mechanism. It allows to match on any sort of data with a first-match policy. Here is a small example which shows how to match against an integer value: - object MatchTest1 extends Application { + object MatchTest1 extends App { def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" @@ -24,7 +24,7 @@ The block with the `case` statements defines a function which maps integers to s Here is a second example which matches a value against patterns of different types: - object MatchTest2 extends Application { + object MatchTest2 extends App { def matchTest(x: Any): Any = x match { case 1 => "one" case "two" => 2 @@ -36,4 +36,4 @@ Here is a second example which matches a value against patterns of different typ The first `case` matches if `x` refers to the integer value `1`. The second `case` matches if `x` is equal to the string `"two"`. The third case consists of a typed pattern; it matches against any integer and binds the selector value `x` to the variable `y` of type integer. Scala's pattern matching statement is most useful for matching on algebraic types expressed via [case classes](case-classes.html). -Scala also allows the definition of patterns independently of case classes, using unapply methods in [extractor objects](extractor-objects.html). +Scala also allows the definition of patterns independently of case classes, using `unapply` methods in [extractor objects](extractor-objects.html). diff --git a/tutorials/tour/polymorphic-methods.md b/tutorials/tour/polymorphic-methods.md index 6fa1f9af05..bed931a7bb 100644 --- a/tutorials/tour/polymorphic-methods.md +++ b/tutorials/tour/polymorphic-methods.md @@ -12,7 +12,7 @@ Methods in Scala can be parameterized with both values and types. Like on the cl Here is an example: - 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) @@ -20,5 +20,6 @@ Here is an example: println(dup("three", 3)) } -Method `dup` in object PolyTest is parameterized with type T and with the value parameters `x: T` and `n: Int`. When method `dup` is called, the programmer provides the required parameters _(see line 5 in the program above)_, but as line 6 in the program above shows, the programmer is not required to give actual type parameters explicitly. The type system of Scala can infer such types. This is done by looking at the types of the given value parameters and at the context where the method is called. -Please note that the trait `Application` is designed for writing short test programs, but should be avoided for production code (for scala versions 2.8.x and earlier) as it may affect the ability of the JVM to optimize the resulting code; please use `def main()` instead. +Method `dup` in object `PolyTest` is parameterized with type `T` and with the value parameters `x: T` and `n: Int`. When method `dup` is called, the programmer provides the required parameters _(see line 5 in the program above)_, but as line 6 in the program above shows, the programmer is not required to give actual type parameters explicitly. The type system of Scala can infer such types. This is done by looking at the types of the given value parameters and at the context where the method is called. + +Please note that the trait `App` is designed for writing short test programs, but should be avoided for production code (for Scala versions 2.8.x and earlier) as it may affect the ability of the JVM to optimize the resulting code; please use `def main()` instead. diff --git a/tutorials/tour/regular-expression-patterns.md b/tutorials/tour/regular-expression-patterns.md index 9e8cac48ad..7b8b5cea1b 100644 --- a/tutorials/tour/regular-expression-patterns.md +++ b/tutorials/tour/regular-expression-patterns.md @@ -10,14 +10,14 @@ num: 22 ## Right-ignoring sequence patterns ## -Right-ignoring patterns are a useful feature to decompose any data which is either a subtype of Seq[A] or a case class with an iterated formal parameter, like for instance +Right-ignoring patterns are a useful feature to decompose any data which is either a subtype of `Seq[A]` or a case class with an iterated formal parameter, like for instance Elem(prefix:String, label:String, attrs:MetaData, scp:NamespaceBinding, children:Node*) In those cases, Scala allows patterns having a wildcard-star `_*` in the rightmost position to stand for arbitrary long sequences. The following example demostrate a pattern match which matches a prefix of a sequence and binds the rest to the variable `rest`. - object RegExpTest1 extends Application { + object RegExpTest1 extends App { def containsScala(x: String): Boolean = { val z: Seq[Char] = x z match { @@ -30,8 +30,9 @@ The following example demostrate a pattern match which matches a prefix of a seq } } -In contrast to previous Scala version, it is no longer allowed to have arbitrary regular expressions, for the reasons described below. -General `RegExp` patterns temporarily retracted from Scala +In contrast to previous Scala versions, it is no longer allowed to have arbitrary regular expressions, for the reasons described below. + +###General `RegExp` patterns temporarily retracted from Scala### Since we discovered a problem in correctness, this feature is temporarily retracted from the Scala language. If there is request from the user community, we might reactivate it in an improved form. diff --git a/tutorials/tour/sequence-comprehensions.md b/tutorials/tour/sequence-comprehensions.md index 058ef69bb2..1e193d8d48 100644 --- a/tutorials/tour/sequence-comprehensions.md +++ b/tutorials/tour/sequence-comprehensions.md @@ -12,7 +12,7 @@ Scala offers a lightweight notation for expressing *sequence comprehensions*. Co Here is an example: - object ComprehensionTest1 extends Application { + object ComprehensionTest1 extends App { def even(from: Int, to: Int): List[Int] = for (i <- List.range(from, to) if i % 2 == 0) yield i Console.println(even(0, 20)) @@ -26,10 +26,10 @@ The program yields the following output: Here is a more complicated example which computes all pairs of numbers between `0` and `n-1` whose sum is equal to a given value `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) => @@ -44,13 +44,14 @@ Here's the output of the program: (13, 19) (14, 18) (15, 17) + (16, 16) There is also a special form of sequence comprehension which returns `Unit`. Here the bindings that are created from the list of generators and filters are used to perform side-effects. The programmer has to omit the keyword `yield` to make use of such a sequence comprehension. Here's a program which is equivalent to the previous one but uses the special for comprehension returning `Unit`: - 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 + ")") } diff --git a/tutorials/tour/unified-types.md b/tutorials/tour/unified-types.md new file mode 100644 index 0000000000..37073a79ad --- /dev/null +++ b/tutorials/tour/unified-types.md @@ -0,0 +1,42 @@ +--- +layout: tutorial +title: Unified Types + +disqus: true + +tutorial: scala-tour +num: 30 +--- + +In contrast to Java, all values in Scala are objects (including numerical values and functions). Since Scala is class-based, all values are instances of a class. The diagram below illustrates the class hierarchy. + +![Scala Type Hierarchy]({{ site.baseurl }}/resources/images/classhierarchy.img_assist_custom.png) + +## Scala Class Hierarchy ## + +The superclass of all classes `scala.Any` has two direct subclasses `scala.AnyVal` and `scala.AnyRef` representing two different class worlds: value classes and reference classes. All value classes are predefined; they correspond to the primitive types of Java-like languages. All other classes define reference types. User-defined classes define reference types by default; i.e. they always (indirectly) subclass `scala.AnyRef`. Every user-defined class in Scala implicitly extends the trait `scala.ScalaObject`. Classes from the infrastructure on which Scala is running (e.g. the Java runtime environment) do not extend `scala.ScalaObject`. If Scala is used in the context of a Java runtime environment, then `scala.AnyRef` corresponds to `java.lang.Object`. +Please note that the diagram above also shows implicit conversions called views between the value classs. +Here is an example that demonstrates that both numbers, characters, boolean values, and functions are objects just like every other object: + + object UnifiedTypes extends App { + val set = new scala.collection.mutable.LinkedHashSet[Any] + set += "This is a string" // add a string + set += 732 // add a number + set += 'c' // add a character + set += true // add a boolean value + set += main _ // add the main function + val iter: Iterator[Any] = set.iterator + while (iter.hasNext) { + println(iter.next.toString()) + } + } + +The program declares an application `UnifiedTypes` in form of a top-level singleton object extending `App`. The application defines a local variable `set` which refers to an instance of class `LinkedHashSet[Any]`. The program adds various elements to this set. The elements have to conform to the declared set element type `Any`. In the end, string representations of all elements are printed out. + +Here is the output of the program: + + This is a string + 732 + c + true + diff --git a/tutorials/tour/unified_types.md b/tutorials/tour/unified_types.md deleted file mode 100644 index 819ebd3084..0000000000 --- a/tutorials/tour/unified_types.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -layout: tutorial -title: Unified Types - -disqus: true - -tutorial: scala-tour -num: 30 ---- - -In contrast to Java, all values in Scala are objects (including numerical values and functions). Since Scala is class-based, all values are instances of a class. The diagram below illustrates the class hierarchy. - -![Scala Type Hierarchy]({{ site.baseurl }}/resources/images/classhierarchy.img_assist_custom.png) - -## Scala Class Hierarchy ## - -The superclass of all classes scala.Any has two direct subclasses scala.AnyVal and scala.AnyRef representing two different class worlds: value classes and reference classes. All value classes are predefined; they correspond to the primitive types of Java-like languages. All other classes define reference types. User-defined classes define reference types by default; i.e. they always (indirectly) subclass scala.AnyRef. Every user-defined class in Scala implicitly extends the trait scala.ScalaObject. Classes from the infrastructure on which Scala is running (e.g. the Java runtime environment) do not extend scala.ScalaObject. If Scala is used in the context of a Java runtime environment, then scala.AnyRef corresponds to java.lang.Object. -Please note that the diagram above also shows implicit conversions called views between the value classs. -Here is an example that demonstrates that both numbers, characters, boolean values, and functions are objects just like every other object: - - object UnifiedTypes { - def main(args: Array[String]) { - val set = new scala.collection.mutable.HashSet[Any] - set += "This is a string" // add a string - set += 732 // add a number - set += 'c' // add a character - set += true // add a boolean value - set += main _ // add the main function - val iter: Iterator[Any] = set.elements - while (iter.hasNext) { - println(iter.next.toString()) - } - } - } - -The program declares an application UnifiedTypes in form of a top-level singleton object with a main method. Themain method defines a local variable set which refers to an instance of class `HashSet[Any]`. The program adds various elements to this set. The elements have to conform to the declared set element type Any. In the end, string representations of all elements are printed out. - -Here is the output of the program: - - c - true - - 732 - This is a string diff --git a/tutorials/tour/upper-type-bounds.md b/tutorials/tour/upper-type-bounds.md index 8bbba32dbd..94b6bc011c 100644 --- a/tutorials/tour/upper-type-bounds.md +++ b/tutorials/tour/upper-type-bounds.md @@ -19,7 +19,7 @@ Here is an example which relies on an upper type bound for the implementation of 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 diff --git a/tutorials/tour/variances.md b/tutorials/tour/variances.md index 0d18981cfc..622dafe21e 100644 --- a/tutorials/tour/variances.md +++ b/tutorials/tour/variances.md @@ -10,7 +10,7 @@ num: 31 Scala supports variance annotations of type parameters of [generic classes](generic-classes.html). In contrast to Java 5 (aka. [JDK 1.5](http://java.sun.com/j2se/1.5/)), variance annotations may be added when a class abstraction is defined, whereas in Java 5, variance annotations are given by clients when a class abstraction is used. -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. +In the page about [generic classes](generic-classes.html) 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. class Stack[+A] { def push[B >: A](elem: B): Stack[B] = new Stack[B] { @@ -19,16 +19,16 @@ In the page about generic classes an example for a mutable stack was given. We e 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) } The annotation `+T` declares type `T` to be used only in covariant positions. Similarly, `-T` would declare `T` to be used only in contravariant positions. For covariant type parameters we get a covariant subtype relationship regarding this type parameter. For our example this means `Stack[T]` is a subtype of `Stack[S]` if `T` is a subtype of `S`. The opposite holds for type parameters that are tagged with a `-`. diff --git a/tutorials/tour/views.md b/tutorials/tour/views.md index b2f12f08f2..3376dd4d8c 100644 --- a/tutorials/tour/views.md +++ b/tutorials/tour/views.md @@ -8,13 +8,14 @@ tutorial: scala-tour num: 32 --- -[Implicit parameters](implicit-parameters.html) and methods can also define implicit conversions called _views_. A view from type `S` to type `T` is defined by an implicit value which has function type `S => T`, or by a method convertible to a value of that type. +[Implicit parameters](implicit-parameters.html) and methods can also define implicit conversions called _views_. A view from type `S` to type `T` is defined by an implicit value which has function type `S => T`, or by an implicit method convertible to a value of that type. Views are applied in two situations: -* If an expression `e` is of type `T`, and `T` does not conform to the expression's expected type `pt`. +* If an expression `e` is of type `S`, and `S` does not conform to the expression's expected type `T`. * In a selection `e.m` with `e` of type `T`, if the selector `m` does not denote a member of `T`. -In the first case, a view `v` is searched which is applicable to `e` and whose result type conforms to `pt`. In the second case, a view `v` is searched which is applicable to `e` and whose result contains a member named `m`. +In the first case, a view `v` is searched which is applicable to `e` and whose result type conforms to `T`. +In the second case, a view `v` is searched which is applicable to `e` and whose result contains a member named `m`. The following operation on the two lists xs and ys of type `List[Int]` is legal: @@ -35,7 +36,7 @@ The `list2ordered` function can also be expressed with the use of a _view bound_ The Scala compiler then generates code equivalent to the definition of `list2ordered` given above. -The implicitly imported object `scala.Predef` declares several predefined types (e.g. `Pair`) and methods (e.g. `error`) but also several views. The following example gives an idea of the predefined view `charWrapper`: +The implicitly imported object `scala.Predef` declares several predefined types (e.g. `Pair`) and methods (e.g. `assert`) but also several views. The following example gives an idea of the predefined view `charWrapper`: final class RichChar(c: Char) { def isDigit: Boolean = Character.isDigit(c) diff --git a/tutorials/tour/xml-processing.md b/tutorials/tour/xml-processing.md index a1bfc43846..bb9c4cc534 100644 --- a/tutorials/tour/xml-processing.md +++ b/tutorials/tour/xml-processing.md @@ -27,7 +27,7 @@ Consider the following XML document: This document can be created by the following Scala program: - object XMLTest1 extends Application { + object XMLTest1 extends App { val page = @@ -43,7 +43,7 @@ This document can be created by the following Scala program: It is possible to mix Scala expressions and XML: - object XMLTest2 extends Application { + object XMLTest2 extends App { import scala.xml._ val df = java.text.DateFormat.getDateInstance() val dateString = df.format(new java.util.Date())