Commits

Miguel Gordian  committed 5083adb

Agregar: Tema unión, intersección y enumerado entre otras correcciones

Se agrega el tema de unión, intersección y enumerado.

Se modifican los títulos y subtítulos de el archivo basico.rst que ocasinaban warnings
cuando se construye con sphinx en readthedocs.

Se eliminaron las substituciones de el archivo clases.rst y se agrego el uso del
comodín para permitir a sphinx elegir entre una imagen svg o png al momento de
construir un pdf o html.

  • Participants
  • Parent commits 2295dd7

Comments (0)

Files changed (6)

File source/_static/feel-like-a-sir.png

Added
New image

File source/_static/matryoshka_plain.png

Added
New image

File source/basico.rst

 El lenguaje de programación ceylon
 ==================================
 
-
-------------------------
-Practico desde el inicio
-------------------------
-
-
+---------------------
 Un clasico hola mundo
-=====================
+---------------------
 
 Comenzemos escribiendo en nuestro editor preferido en un archivo
 llamado hola.ceylon el siguiente fragmento de codigo:
 De acuerdo a la documentación, Ceylon por el momento no soporta scripting,
 y no podemos escribir codigo fuera de clases y funciones.
 
-
+------------------------
 Compilacion del programa
-========================
+------------------------
 
 Es importante tener un area de trabajo asi que por limpieza crearemos
 una carpta llamada ceylon donde mantendremos la estructura que necesita
     Note: Created module default
 
 .. Investigar el proposito de estas carpetas a fondo
+
 Durante la compilación se crearan las carpeta llamada modules/default, las 
 cuales contendran los bytecodes de nuestro programa.
 
     $ ceylon help run
 
 
+------------------------
 Fundamentos del lenguaje
-========================
+------------------------
 
-
+########################
 Sintaxis, como aperitivo
-------------------------
+########################
 
 Sin duda los elementos basicos forman la base de estructuras complejas es por
 eso que antes de pasar a elementos propios de caylon debemos entender sus
 poder trabajar sobre el.
 
 
+##############
 String literal
 ##############
 
 
     Hola mundo!
 
-
+#################################
 Documentación, como una prioridad
 #################################
 
 Debes tener cuidado al indentar las multistring literal pues Markdown
 es sensible a la primera columna en que el texto aparece.
 
+####################
 Secuencias de escape
 ####################
 
 Las Ceylon strings son compuestas de UTF-32 caracteres, pero esto
 lo retomaremos mas adelante.
 
+################
 Strings Verbatim
-###############
+################
 
 Algunas veces, las interpolación de secuencias de escape puede ser molesto,
 por ejemplo en aquellas veces que embebemos codigo dentro de las string literals.
 
     print(""""Hola!", dijo el programa.""");
 
-
+####################################
 String Interpolacion y concatenacion
 ####################################
 
 string para convertir expresiones numericas a cadenas. *EL operador
 + no convierte automaticamente sus operandos a cadenas*.
 
-
+###################################
 Lidiando con objetos que no existen
 ###################################
 
 para alguna otra cosa fuera de la condicional (pero esta no es la manera mas compacta
 de escribir el codigo).
 
+###############
 Tipo opcionales
 ###############
 
 de Ceylon hace algun tipo de magia especial para transformar este valor a un null a nivel de la 
 maquina virtual.
 
-
+#######################################
 Operadores para el manejo de los `null`
 #######################################
 
 
 Despues de todo solo es una linea.
 
-Funciones y |valores|
-===================
+-------------------
+Funciones y valores
+-------------------
 
 Los dos elementos mas basicos encontrados en todos los lenguages de 
 programacion son las funciones y las variables. En ceylon, las "variables"
     - Parametros por defecto, y
     - parametros variables(variadic)
 
+######################
 Parametros por defecto
 ######################
 
 requeridos en la lista de parametros.
 
 
+####################
 Parametros variables
 ####################
 
 
 Volveremos a el tercer caso, comprenhencion, mas adelante.
 
+#################################
 Fat arrows y declaracion adelante
 #################################
 
 mas adelante. (Por que si lo hacemos, deberia de resultar en un 
 `NullPointerException`, el cual !Ceylon no tiene!)
 
+-------
 Numeros
-=======
+-------
 
 Desafotunadamente, no todos los programas son simples y elegantes com "hola mundo!".
 En los negocios o computación cientifica, podemos encontrar comunmente programas que
 Este fue solo un pequeño rompecabezas para mantener tu interes, Explicaremos
 la sintaxis que usamos aqui mas adelante.
 
-Aun hay mas...
-##############
+###########
+Aun hay mas
+###########
 
 Ceylon es un lenguage orientado a objetos, asi que una gran cantindad de codigo 
 que escribamos en Ceylon es contenido en clases. Aprendamos acerca de 

File source/clases.rst

 Nuestra primera clase haremos que represente un punto en un sistema de coordenadas polares. Nuestra clase toma
 dos parámetros, dos métodos y un atributo.
 
-.. |Con-Clase|  figure:: _static/feel-like-a-sir.svg
+.. figure:: _static/feel-like-a-sir.*
    :align: left
    :width: 200
    :height: 300
 
 
 
-Ceylon no hace dinstinciń entre `public, protected` y `default` visibilidad como |matryoshka|
+Ceylon no hace dinstinciń entre `public, protected` y `default` visibilidad como
 java lo hace; `Aqui el porque <http://ceylon-lang.org/documentation/1.0/faq/language-design/#no_protected_modifier>`_
 En vez de ello, el lenguaje distingue entre:
 
-.. |matryoshka|  figure:: _static/matryoshka_plain.svg
+.. figure:: _static/matryoshka_plain.*
    :align: right
    :width: 400
    :height: 300
-   :scale: 30 
+   :scale: 80 
    :alt: matryoshka doll
 
 - Elementos del programa que son visibles unicamente en el scope o alcance
-      donde ellos fueron definidos, y
+  donde ellos fueron definidos, y
     
 - Elementos del programaque son visibles donde sea que el objeto donde el
-      pertenece sea visible.
+  pertenece sea visible.
 
 Por defecto, los miembros de la clase son ocultados para todos afuera de la 
 definición de la clase. Por anotación, un miembro con la anotación `shared`,
 usando una sintaxis muy conveniente.
 
 .. code-block:: ceylon
+
     shared Cartesian cartesian(Polar polar) {
         return Cartesian(polar.radius*cos(polar.angle),
                          polar.radius*sin(polar.angle));

File source/index.rst

 Un tour por Ceylon
 ==================
 
+Esta es el intento de traducción(no muy bueno) al español de el Tour de Ceylon,
+el cual lo puede encontrar en la pagina oficial del lenguaje `Ceylon <http://ceylon-lang.org>`_.
+
+    **Pretende ser una guia de iniciación a las poderosas características que provee Ceylon.**
+
+El contenido de esta pagina se encuentra en bitbucket en el repositorio 
+`CeylonTour <https://bitbucket.org/zoek/ceylontour>`_, donde toda ayuda es 
+bienvenida y agradecida.
+
 ..  toctree::
-    :maxdepth: 3
+    :maxdepth: 2
 
-    introducción
     basico
     clases
     atributos_estructuras
     anonimos_clasesMiembro
     iterables_secuencias_tuplas
     aliasTipos_inferenciaTipo
+    union_interseccion_enumerated
+
+Para alguna critica o sugerencia puedes contactarme a 
+`@ilcapitanozoek <https://twitter.com/ilcapitanozoek>`_ en twitter.

File source/union_interseccion_enumerated.rst

+======================================
+Unión, intersección y tipos enumerados
+======================================
+
+Este es la octava parada en el tour de Ceylon. En la parada anterior aprendimos
+acerca de los alias y la inferencia de tipos. Continuemos explorando el sistema 
+de tipos de Ceylon.
+
+En este capitulo, vamos a discutir los cercanos tópicos de tipos unión e 
+intersección y los tipos enumerados. En esta área, el sistema de tipos de Ceylon
+trabaja un poco distinto a otros lenguajes de tipos estáticos.
+
+
+------------------------------------------
+Reduciendo el tipo de un objeto referencia
+------------------------------------------
+
+En cualquier lenguaje con subtipos hay ocasiones en las que necesitas realizar
+reducción con conversiones. En demasiados lenguajes de tipos estáticos, esta es
+la segunda parte del proceso. Por ejemplo, en Java primero probamos el tipo del
+objeto usando el operador `instanceof`, y entonces intentar reducirlo usando 
+un `typecast` estilo C.  Esto es un poco curioso, desde que estos no son 
+virtualmente buenos usos para `instanceof`  que no involucra una conversión
+inmediata al tipo que fue probado, y el cambio de tipo sin probar el tipo es 
+peligrosamente un tipo no seguro.
+
+Como puedes imaginar, Ceylon, con su énfasis sobre los tipos estáticos, hace las
+cosas diferente, Ceylon no tiene un cambio de tipos al estilo de C. En ves de ellos,
+debemos de probar y reducir el tipo de la referencia de un objeto en un solo paso, 
+usando la construcción especial `if (is ...)`. Esta construcción es muy parecida a
+`if (exists ...)` y `if (nonempty ...)`, las cuales conocimos tempranamente.
+
+.. code-block:: ceylon
+    
+    void PrintIfPrintable(Object obj) {
+        if (is Printable obj){
+            obj.printObj();
+        }
+    }
+
+También hay una construcción especial `if (!is ...)` que es practica algunas veces.
+
+La declaración `switch` puede ser usada de una manera similar:
+
+.. code-block:: ceylon
+    
+    void switchingPrint(Object obj) {
+        switch(obj)
+        case (is Hello) {
+            obj.printMsg();
+        }
+        case (is Person) {
+            print(obj.firstName);
+        }
+        else {
+            print(obj.string);
+        }
+    }
+
+Estas construcciones nos protegen de escribir inadvertidamente codigo que
+pueda causar una  `ClassCastException` en Java, justo como `if (exists ...)`
+nos protege de escribir codigo que pueda causar `NullPointerException`.
+
+La construcción `if (is ...)` actualmente reduce el código a un tipo 
+intersección.
+
+------------------
+Tipos intersección
+------------------
+
+Una expresión es asignable a un tipo intersección, escrito X&Y, si este es
+asignable a ambos X&Y. Por ejemplo, desde que `Tuple` es un subtipo de 
+`Iterable<Nothing>` y de `Correspondence`, la tupla tipo `[String,String]`
+es también un subtipo de la intersección.
+
+`Iterable<String>&Correspondence<Integer,String>`. El supertipo de un 
+tipo intersección incluye todos los supertipos de cada tipo interceptado.
+
+
+Entonces, el siguiente código esta bien tipado:
+
+.. code-block:: ceylon
+    
+    Iterable<String>&Correspondece<Integer,String> string =
+            ["Hello", "world"];
+    String? str = strings.get(0);
+    Integer size = strings.size;
+
+Ahora considerar este código, para ver el efecto de `if (is ...)`:
+
+.. code-block:: ceylon
+    
+    Iterable<String> strings = ["hello","world"];
+    if (is Correspondence<Integer,String> strings) {
+        //Aqui string tiene el tipo
+        //Iterables<String> & Correspondence<Integer,String>
+        String? str = strings.get(0);
+        Integer size = strings.size();
+    }
+
+Dentro del cuerpo de la construcción `if`, `strings` tiene el tipo
+`Iterable<String>&Correspondence<Integer,String>`, así podemos
+llamar las operaciones de ambos, `Iterable` y `Correspondence`.
+
+
+-----------
+Tipos unión
+-----------
+
+Una expresión es asignable a un tipo unión, escrito X|Y, si este es
+asignable a cualquiera X o Y. El tipo X|Y es siempre un supertipo de
+ambos X y Y. El siguiente código esta bien tipado:
+
+.. code-block:: ceylon
+    
+    void printType(String|Integer|Float val) { ... }
+
+    printType("hello");
+    printType(69);
+    printType(-1.0);
+
+Pero, ¿qué operaciones tiene un tipo como `String|Integer|Float`? 
+¿Cuales son sus supertipos? Bueno, la respuesta es muy intuitiva: T
+es un supertipo de X|Y si y solo si  es un supertipo de X y de Y.
+El compilador de Ceylon determina esto automáticamente. Así el 
+siguiente código esta bien tipado.
+
+.. code-block:: ceylon
+    
+    Integer|Float x= -1;
+    Number num = x; // number es un supertipo de ambos Integer y Float
+    String|Integer|Float val = x; // String|Integer|Float es un supertipo 
+                                  // de Integer|Float
+    Object obj = val; //Object es un supertipo de String, Integer y Float.
+
+Sin embargo, el siguiente código no esta bien tipado, desde que `Number` no
+es un supertipo of `String`.
+
+.. code-block:: ceylon
+    
+    String|Integer|Float x = -1;
+    Number num = x; //compile error:  String is not a subtype of Number
+
+Por supuesto, es muy común reducir una expresión de tipo unión usando una
+declaración `switch`. Usualmente el compilador de Ceylon nos fuerza a escribir
+una clausula `else` en un `switch` para recordarnos que puede haber casos 
+adicionales que no han sido manejados. Pero si agotamos todos los casos de un 
+tipo unión, el compilador nos permitirá dejar fuera la clausula `else`.
+
+.. code-block:: ceylon
+    
+    void printType(String|Integer|Float val) {
+        switch (val)
+        case (is String) { print("String: ``val``"); }
+        case (is Integer) { print("Integer: ``val``"); }
+        case (is Float) { print("Float: ``val``"); }
+    }
+
+Un tipo unión es una especia de tipo enumerado.
+
+---------------
+Tipos Enumerado
+---------------
+
+Algunas veces es útil que este disponible realizar el mismo tipo de cosas
+con subtipos de una clase o interfaz. Primero, necesitamos explícitamente
+enumerar los subtipos de el tipo usando la clausula `of`:
+
+.. code-block:: ceylon
+    
+    abstract class Point()
+            of Polar | Cartesian {
+        //...
+    }
+
+(Esto crea un punto en la versión de Ceylon de lo que llaman en la comunidad de 
+programación funcional un tipo "algebraico" o "sum".
+
+Ahora el compilador no nos permitirá declarar subclases adicionales a `Point`, 
+así el tipo unión `Polar|Cartesian` es exactamente el mismo tipo como `Point`.
+Ademas podemos escribir declaraciones `switch` sin la clausula `else`:
+
+.. code-block:: ceylon
+
+    void printPoint(Point point) {
+        switch (point)
+        case (is Polar){
+            print("r = " + point.radius.string);
+            print("theta = " + point.angle.string);
+        }
+        case (is Cartesian) {
+            print("x = " + point.x.string);
+            print("y = " + point.y.string);
+        }
+    }
+    
+Ahora, es usualmente considerado una mala practica escribir largas 
+declaraciones de `switch` que manejen todos los subtipos de un tipo. Esto
+crea un código no extensibles. Agregar una nueva subclase a `Point` significa 
+romper todas las declaraciones que agotaron los subtipos. En programación 
+orientada a objetos, tratamos de refactorizar construcciones como esta usando
+un método abstracto de la superclase que es sobrescrita apropiadamente por 
+subclases.
+
+Sin embargo, esta es una clase de problema donde este tipo de refactorisación
+no es apropiado. En muchos lenguajes de programación orientados a objetos, estos
+problemas son usualmente resueltos usando el patrón "visitor".
+
+
+########
+Visitors
+########
+
+Consideremos las 3 siguientes implementaciones visitor:
+
+.. code-block:: ceylon
+    
+    abstract class Node() {
+        shared formal void accept(Visitor v);
+    }
+
+    class Leaf(shared object element)
+            extends Node() {
+        accept (Visitor v) => v.visitLeaf(this);
+    }
+
+    class Branch(shared Node left, shared Node rigth)
+            extends node() {
+        accept(Visitor v) => v.visitBranch(this);
+    }
+
+    interface Visitor {
+        shared formal void visitLeaf(Leaf l);
+        shared formal void visitBranch(Branch b);
+    }
+
+Podemos crear un método que imprima las tres implementando la 
+interfaz `Visitor`:
+
+.. code-block:: ceylon
+    
+    void printTree(Node node) {
+        object printVisitor satisfies Visitor {
+            shared actual void visitLeaf(Leaf leaf) {
+                print("Found a leaf: ``leaf.element``!");
+            }
+            shared actual void visitBranch(Branch branch){
+                branch.left.accept(this);
+                branch.rigth.accept(this);
+            }
+        }
+        node.accept(printVisitor);
+    }
+
+Note que el código de `printVisitor` luce como la delaración de `switch`.
+El deberá explícitamente enumerar todos los subtipos de `Node`. Estará
+"roto" si agregamos un nuevo subtipo de `Node` a la interfaz `Visitor`.
+Esto es correcto, y es el comportamiento deseado; "roto" significa que
+el compilador nos permitirá conocer que tenemos que actualizar nuestro
+código para manejar un nuevo subtipo.
+
+En Ceylon podemos lograr el mismo efecto, con menos verbosidad, enumerando
+los subtipos de `Node` en su definición y usando un switch:
+
+.. code-block:: ceylon
+    
+    abstract class Node() of Leaf | Branch {}
+
+    class Leaf(shared Object element) 
+            extends Node() {}
+
+    class Branch(shared Node left, shared Node  right)
+            extends Node() {}
+
+Nuestro método `print()` es ahora mucho mas simple, pero aun tiene el mismo
+comportamiento deseado de "romperse" cuando un nuevo subtipo de `Node` es 
+agregado.
+
+.. code-block:: ceylon
+    
+    void printTree(Node node) {
+        switch (node)
+        case (is Leaf) {
+            print("Found a leaf: ``node.element``!");
+        }
+        case (is Branch) {
+            printTree(node.left);
+            printTree(node.right);
+        }
+    }
+
+
+###################
+Interfaz enumeradas
+###################
+
+Ordinariamente, Ceylon no nos permitirá usar tipos interfaz como un `case` de 
+`switch`. Si `File,Directory,` y `Link` son interfaces, no podemos escribir tal
+cual:
+
+.. code-block:: ceylon
+    
+    File|Directory|Link resources = ...;
+    switch (resources)
+    case (is File) { ... }
+    case (is Directory) { ... } //compile error: cases are not disjoint
+    case (is Link) { ... } //compile error: cases are not disjoint
+
+El problema es que los casos no están disjuntos. Podemos tener una clase que 
+satisfaga ambos `File` y `Directory` y entonces no saber que rama ejecutar.
+
+(En todos nuestros ejemplos anteriores, nuestros `case` referenciaban a tipos
+que eran probablemente disjuntos, debido a que eran clases, que soportan
+únicamente herencia simple.)
+
+Hay una solución, a pesar de todo. Cuando una interfaz tiene subtipos enumerados,
+el compilador fuerza a estos subtipos a estar disjuntos. Así que si definimos 
+la siguiente interfaz enumerada:
+
+.. code-block:: ceylon
+
+    interface Resource of File|Directory|Link { ... }
+
+Entonces la siguiente declaración es un error:
+
+.. code-block:: ceylon
+    
+    class DirectoryFile()
+            satisfies File&Directory {} //compile error: File and Directory are
+                                        // disjoint types
+
+Ahora esto es aceptado por el compilador:
+
+.. code-block:: ceylon
+    
+    Resource resource = ...;
+    switch (resource)
+    case (is File) { ... }
+    case (is Directory) { ... }
+    case (is Link) { ... }
+
+El compilador es muy inteligente cuando razón acerca de las desuniones y 
+agotamiento. Por ejemplo, esto es aceptable:
+
+.. code-block:: ceylon
+    
+    Resources resource = ...;
+    switch (resource)
+    case (is File|Directory) { ... }
+    case (is Link) { ... }
+
+Como este, asumiendo la anterior declaración de `Resource`:
+
+.. code-block:: ceylon
+    
+    File|Link resource = ... ;
+    switch (resource) 
+    case (is File) { ... }
+    case (is Link) { ... }
+
+Si estas interesando en conocer mas acerca de esto, `lee esto <http://goo.gl/OujwYN>`_
+    
+#####################
+Instancias enumeradas
+#####################
+
+Ceylon no tiene algo exactamente como la declaración `enum` de Java. Pero
+emular el efecto usando la clausula `of`.
+
+.. code-block:: ceylon
+    
+    abstract class Suit(String name)
+            of hearts|diamons|clubs|spades {}
+
+    object hearts extends Suit("hearts") {}
+    object diamonds extends Suit("diamonds") {}
+    object clubs extends Suit("clubs") {}
+    object spades extends Suit("spades") {}
+
+Es permitido usar los nombres de las declaraciones `object` en la clausula
+`of`.
+
+Ahora podemos agotar todos los casos de `Suit` en un `switch`:
+
+.. code-block:: ceylon
+    
+    void printSuit(Suit suit) {
+        switch (suit)
+        case (hearts) { print("Heartzes"); }   
+        case (diamonds) { print("Diamondzes"); }
+        case (clubs) { print("Clidubs"); }
+        case (spades) { print("Spidades"); }
+    }
+
+Note que estos casos son casos de valor, no casos de tipo `case (is ...)`.
+Ellos no necesitan reducir el tipo `Suit`
+
+Así es esto es un poco mas verboso que el `enum` de Java, pero también es
+algo mas flexible.
+
+Para mas ejemplos prácticos, revisa la definición de `Boolean` y `Comparison`
+en el modulo del lenguaje.
+
+###########
+Aun hay mas
+###########
+
+En la siguiente estación veremos el `sistema genérico de tipos` en profundidad.