Commits

Miguel Gordian committed 2d80f98

Ceylon tour

Este repo prentende ser una referencia en el aprendizaje del lenguaje de
programación ceylon.

Una breve introducción en el archivo basico.rst, se necesita hacer una
revisión minuciosa de la ortografia y redacción.

En el archivo index.rst se mantiene el toctree del projecto de
documentación.

Comments (0)

Files changed (2)

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:
+
+.. code-block:: ceylon
+
+    void hola(){
+        print("hola mundo!");
+    }
+
+La sintaxis es muy similar a la de java, esta es la manera de definir
+una función en este caso solo imprime un mensaje "Hola mundo!", un clasico,
+pero en este momento no me enfocare en la sintaxis de la funcion si no en 
+su rol dentro del programa.
+
+Esta funcion es conocida toplevel function  por que no es miembro del algun
+tipo de dato. Esto quiere decir que no necesitamos crear un objeto para poder
+utilizar la funcion hola, solo necesitas llamarla de la sig. forma:
+
+.. code-block:: ceylon
+
+    hola()
+
+Ceylon no tiene metodos estaticos como Java o C++ pero se pueden pensar que
+las funciones toplevel puden servir para el mismo proposito. La razon que 
+las diferencia es que ceylon tiene una structura de bloques muy estricta -
+un bloque anidado siempre tiene acceso a las declaraciones en todos los bloques
+que la contienen.
+Esto no es el caso con los metodos estaticos de Java.
+
+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
+ceylon para trabajar.
+
+Dentro de la carpeta ceylon crearemos una llamada source y dentro de ella
+colocaremos el archivo hola.ceylon.
+A continuacion mostraremos la manera de compilar el programa.
+
+.. code-block:: console
+        
+    $ ceylon compile source/hola.ceylon 
+    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.
+
+.. code-block:: console
+
+    $ ceylon run --run hola default
+    hola mundo!
+
+Con estos ejecutaremos el programa, la descripcion es simple:
+
+    - run  : Le indica a el comando ceylon que ejecutaremos un programa
+    - --run : Le indicamos a ceylon que el punto de entrada el cual puede
+            ser una funcion toplevel o una clase.
+    - default :  Es el nombre del modulo que ejecutaremos, por defecto es 
+        default.
+
+Este modulo tienen por nombre defult.car y se encuentra  en el directorio 
+modules/default.
+
+LA documentación oficial recomienda hecharle un ojo a la ayuda proporcionada
+por ceylon.
+
+.. code-block:: console
+
+    $ ceylon help compile
+    $ 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
+pilares.
+
+Comenzemos hablando de los literales, los cuales son datos que podemos
+escribir en el programa y el compilador se encargara de transformalo para
+poder trabajar sobre el.
+
+
+String literal
+##############
+
+La forma de escribir una string literal dentro de nuestro programa, 
+es colocando el texto deseado dentro de comillas dobles, como lo hemos
+hecho anteriormente en nuestro programa.
+
+.. code-block:: ceylon
+
+    void hola() {
+        print("Hola mundo!");
+    }
+
+Las cadenas en ceylon tienen un comportamiento especial, por ejemplo:
+
+.. code-block:: ceylon
+
+    void hola() {
+        print("Hola 
+               mundo!");
+    }
+
+Se mostrara como:
+
+.. code-block:: console
+
+    Hola,
+    Mundo!
+
+Cabe destacar que apesar de que en la segunda linea contenia espacios hasta
+el primer carater de esa linea, ceylon se encarga de remover estos espacios,
+Esto ayuda a darle un formato al codigo mas agradable a la vista.
+
+Es frecuente querer quitar(collapse) todos los espacios en blanco de una 
+string literal, para ello Ceylon nos provee de una clase String, la cual
+tiene un atributo llamado <normalized "">:
+
+.. code-block:: ceylon
+
+    void hola() {
+        value mensaje = "Hola,
+                         mundo";
+        print(mensaje.normalized);
+    }
+
+El cual da una salida como la siguiente:
+
+.. code-block:: console
+
+    Hola mundo!
+
+
+Documentación, como una prioridad
+#################################
+
+Siempre es bueno agregar algo de documentacón, sobre todo si
+son funciones imporantes como hola().
+
+Una forma de hacerlo is usando un comentario estilo C, como el siguiente:
+
+.. code-block:: ceylon
+
+    /* El clasico programa hola mundo*/
+    void hola() {
+        print("Hola mundo!\n");
+    }
+
+o como esta:
+
+.. code-block:: ceylon
+
+    // El clasico programa hola mundo
+    void hola() {
+        print("Hola mundo!\n");
+    }
+
+Pero es mucho mejor usar la anotacion `doc` para comentarios
+que describen declaraciones.
+
+.. code-block:: ceylon
+
+    doc ("El clasico hola mundo")
+    by ("Zoek")
+    see (adios)
+    throws (IOException)
+    void hola() {
+        print("Hola mundo!\n");
+    }
+
+Las anotaciones `doc, by, see,` y `tagged` contienen documentación que es
+incluida en la salida de la herramienta de documentación de Ceylon, `ceylon doc`.
+
+Anotaciones como `doc, by, see, throws` son son palabras reservadas, ellos son 
+solo identificadores ordinarios.
+Lo mismo aplica para identificadores que son parte de la definicion del lenguaje, 
+por ejemplo: `abstract, variable, shared, formal, default, actual,` etc.
+
+La anotacion `doc` es ubicuo(omnipresente) los parentesis y la anotacion pueden
+ser obviadas cuando es la primera anotación en la lista de anotaciones:
+
+.. code-block:: ceylon
+
+    "El clasico hola mundo"
+    by ("Zoek")
+    see (adios)
+    throws (IOException)
+    void hola() {
+        print("Hola mundo!\n");
+    }
+
+La anotación doc pueden ser escritas on formato Markdown.
+
+.. code-block:: ceylon
+
+    "El Clasico [Programa Hola mundo][holamundo]
+     que imprime un mesaje a la consola, esta vez
+     escrito en [Ceylon][].
+
+     Este simple programa demuestra:
+
+     1. Como definir una funcion toplevel, y
+     2. como imprimir con `print()` una literal `String`.
+
+     Tu puedes compilar y ejecutar `hello()` desde la
+     linea de comandos:
+
+        ceylon compile source/hola.ceylon
+        ceylon run -run hola default
+
+     [holamundo]: http://en.wikipedia.org/wiki/Hello_world_program
+     [Ceylon]: http://ceylon-lang.com"
+
+    void hola () {
+        print("Hola mundo!\n");
+    }
+
+Debes tener cuidado al indentar las multistring literal pues Markdown
+es sensible a la primera columna en que el texto aparece.
+
+Secuencias de escape
+####################
+
+Dentro de las string literals, puedes usar secuencias de escape como 
+`\n, \t, \\, \"`
+
+.. code-block:: ceylon
+
+    print("\"Hola!\", dijo el programa");
+
+Tambien puedes usar secuencias de escape hecadecimales de 2-bytes y 4-bytes.
+
+.. code-block:: ceylon
+
+    "La constante matematica \{#03C0}, el
+     el radio de la circunferencia de un circulo
+     a su diametro."
+    Float pi=calculatePi();
+ 
+    "La constante matematica \{#0001D452},
+     la base del logaritmo natural."
+    Float e=calculateE();
+
+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.
+Si utilizamos tres comillas dobles, `"""`, para delimitar nuestra cadena, 
+obtendremos una string verbatim, que puede contener backlash no escapados y 
+comillas dobles:
+
+.. code-block:: ceylon
+
+    print(""""Hola!", dijo el programa.""");
+
+
+String Interpolacion y concatenacion
+####################################
+
+Supongamos que queremos conocer mejor a nuestro programa,
+que nos habla de el:
+
+.. code-block:: ceylon
+
+    "The Hello World program ... version 1.1!"
+    void hello() {
+        print("Hola, Este es Ceylon ``language.version`` 
+               corriendo sobre Java ``process.vmVersion``!\n
+               Me corriste en ``process.milliseconds`` ms,
+               con ``process.arguments.size`` argumentos.");
+    }
+
+Notese como nuestro mensaje contiene expresiones interpoladas,
+delemitadas por doble acentos graves, \`\`, estas son conocidas
+como string templates.
+
+En mi maquina, este programa da la siguiente salida:
+
+.. code-block:: console
+
+   Hola, Este es Ceylon 0.5 
+   corriendo sobre Java 1.7!
+
+   Me corriste en 1374960853214 ms,
+   con 0 argumentos.
+
+Otro elemento importante hablando de cadenas es la concatenación,
+esta atravez del operador +:
+
+.. code-block:: ceylon
+
+    print("Hola, Este es Ceylon " + language.version +
+           "corriendo sobre Java " + process.vmVersion + "!\n" +
+           "Me corriste en " + process.milliseconds.string 
+           + " ms, con " + process.arguments.size.string +
+           " argumentos.");
+ 
+Notese que hemos tenido que invocar explicitamente al atributo
+string para convertir expresiones numericas a cadenas. *EL operador
++ no convierte automaticamente sus operandos a cadenas*.
+
+
+Lidiando con objetos que no existen
+###################################
+
+Vamos a tomar un nombre como entrada desde la linea de comandos y 
+necesitamos cubrir el caso donde nada ha sido especidicado, esto nos
+da la oportunidad de explorar como los valores null son tratados en 
+ceylon.Consideremos un overlay-verbose ejemplo para comenzar:
+
+.. code-block:: ceylon
+
+    "Print a personalized greeting"
+    void hello() {
+        String? name = process.arguments.first;
+        String greeting;
+        if (exists name) {
+            greeting = "Hello, ``name``!";
+        }
+        else {
+            greeting = "Hello, World!";
+        }
+        print(greeting);
+    } 
+
+El tipo String? indica que nombre puede contener un valor null. Entonces usaremos 
+bloque if para manejar el caso de un valor null separandolo del de un valor no null.
+
+Pero tambien es posible abreviar el codigo, delarando localmente al nombre dentro de 
+la codicion del if:
+
+.. code-block:: ceylon
+
+    String greeting;
+    if (exists name =
+            process.arguments.first) {
+        greeting = "Hello, ``name``!";
+    }
+    else {
+        greeting = "Hello, World!";
+    }
+    print(greeting);
+
+Esta es estilo preferido la mayor parte de la veces, puesto que no usaremos nombre
+para alguna otra cosa fuera de la condicional (pero esta no es la manera mas compacta
+de escribir el codigo).
+
+Tipo opcionales
+###############
+
+A diferencia de java, locales, parametros y atributos que pueden contener el valor `null`
+deberan de ser declaradas explicitamente como de tipo opcional (la sintaxis T?).
+A su vez no existe una manera de asignar un valor `null` a una variable local que no sea
+de tipo opcional, el compilador no debera permitirlo. Este es un error.
+
+.. code-block:: ceylon
+
+    String name = null; // compile error: null is not an instance of String
+
+El compilador de ceylon no te permitira hacer algo peligroso con un valor de yipo `T?` -
+esto es nada que puede causar un `NullPointerException` en Java - Sin primero revisar que
+el valor no es `null` usando un `if (exists ...)`. El siguiente codigo tambien es un error.
+
+.. code-block:: ceylon
+
+    String? name = process.arguments.first;
+    print("Hello " + name + "!");  // compile error: name is not Summable
+
+De hecho, no es posible usar el operador == con una expresion de tipo opcional asi es que no
+podemos escribir lo siguiente sin causar un error.
+
+.. code-block:: ceylon
+
+    String? name = process.arguments.first;
+    if ( name == null) { ... } // compile error: name is not Object
+
+En un leguaje con tipado estatico, siempre quieres conocer que tipo tienen los objetos.
+Entonces, ¿Cual es el tipo de `null`?
+
+La respuesta simple es: `null` es de tipo `Null`
+
+Asi como se lee, el valor `null` no es valor primitivo en Ceylon, es una instacia ordinaria
+de una clase ordinaria `Nul`, al menos desde el punto de vista del sistemas de tipos de Ceylon.
+
+Y la sintaxis `String?` es solo una abreviacion del tipo `union`: `Null|String`.
+
+Dado esto, podemos entender claramente por que no podemos hacer operaciones de `String` en
+`String?`. Simplemente son tipos distintos. La construcción `if (exists ...`, reduce el tipo de nombre
+dentro del bloque `if ` permitiendo tratarlo como de tipo `String`.
+
+(si eres de los que se preocupan por el performace, esta de mas mencionar que el compilador 
+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`
+#######################################
+
+Existen in conjunto de operadores que pueden ser de ayuda cuando se tratan con
+valores `null`. El primero es `else`:
+
+.. code-block:: ceylon
+    
+    String greeting = "Hello," +  (name else "World");
+
+El operador `else` da como resultado:
+
+    - El primero operador si no es `null`, or
+    - El segundo operado si sí lo es.
+
+Es mas conveniente manejar valores `null`, en casos simples. Tambien puedes 
+crear una cadena de `else`:
+
+.. code-block:: ceylon
+
+    String name = firstName else userId else "Guest";
+
+Tambien existe un operador para producir un valor `null`:
+  
+.. code-block:: ceylon
+    
+    String? name = !arg.trimmed.empty then arg;
+
+El operador `then` produce:
+
+    - El segundo operador si el primer operando evalua a verdadero, o
+    - `null` si no es asi.
+
+Tambien puedes ligar un else despues de un then para reproducir el 
+comprotamiento del operador ternario en C:
+
+.. code-block:: ceylon
+
+    String name = !arg.trimmed.empty then arg else "World!";
+
+Usando el operador `else`, podemos simplificar nuestro ejemplo a algo 
+mas razonable:
+
+.. code-block:: ceylon
+    
+    "Imprime un mensaje personalizado"
+    void hola() {
+        print("Hola, ``process.arguments.first else "World"``!");
+    }
+
+Despues de todo solo es una linea.
+
+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"
+por defecto solo se pueden asignar una vez. Esto es, que las variables 
+no pueden ser asignadas a otro valor despues de que han sido asignadas 
+a un valor por primera vez. 
+
+Sin embargo, usaremos la palabra `value` para referirnos a "variables" en 
+general y reservar la palabra `variable` para referirnos a un `value` que
+explicitamente definido para ser reasignable.
+
+.. code-block:: ceylon
+    
+    String adios = "adios"; // un value
+    variable Integer contador = 0; // una variable
+
+    adios = "Adeu"; // compile error
+    count = 1; // permitido
+
+Notese que un `value` que no es una variable en este sentido, puede aun ser
+una "variable" en el sentido que su valor varia entre dinstintas ejecuciones
+del programa o entres contextos dentro de la ejecuion de un programa.
+
+Un value puede ser recalculado cada vex que es evaluado.
+
+.. code-block:: ceylon
+
+    String nombre = { return primerNombre + " " + segundoNombre; }
+
+Si el valor de primerNombre y segundoNombre varia entonces el valor de nombre
+tambien varia entre evaluaciones.
+
+Una funcion toma un paso adeante en esta idea,El valor de una funcion depende 
+no unicamente del contexto en que es evaluado pero tambien el argumento a los
+parametros.
+
+.. code-block:: ceylon
+    
+    Float sqr (Float x) { return x * x; }
+
+En ceylon la declaración de un valor o de una funcion puede ocurrir en casi 
+cualquier lugar : Como un `toplevel`, pertene a un paquete directamente, como un
+atributo o un metodo de una clase o como una declaracion local de bloque dentro
+un `different value` o el cuerpo de una función, De hecho, como veremos mas adelante,
+la declaracion de un `value` o funcion pueden ocurrir dentro de una expresion en algunos
+casos.
+
+La declaracion de funciones es muy similar a la que probablemente hallas usado en otros
+lenguajes parecidos a C, pero con dos excepciones. Ceylon has:
+
+    - Parametros por defecto, y
+    - parametros variables(variadic)
+
+Parametros por defecto
+######################
+
+Un parametros de una funcion puede especificar un valor por defecto.
+
+.. code-block:: ceylon
+    
+    void hola (String nombre="Mundo") {
+        print("Hola  ``nombre``!");
+    }
+
+Entonces no necesitamos forsosamente pasarle argumentos cuando se 
+llama a la función.
+
+.. code-block:: ceylon
+    
+    hola(); // Hola mundo!
+    hola("JBoss); // Hola JBoss!
+
+Parametros por defecto deberan de ser declarados despues de los parametros
+requeridos en la lista de parametros.
+
+
+Parametros variables
+####################
+
+Un parametro `variadic` de una funcion o clase es declarado usando un asterisco 
+posfijo, por ejemplo String*. Una funcion o clase solo puede tener un parametro 
+`variadic` y debera ser el ultimo parametro.
+
+.. code-block:: ceylon
+
+    void HolaTodos (String* nombres) {
+        //...
+    } 
+
+Dentro del cuerpo de la funcion, el parametro nombres tiene el tipo `[String*]`, 
+un tipo `sequence`, del cual hablaremos mas tarde. Para acceder a cada uno de sus
+elementos podemos iterar sobre el utilizando un ciclo for.
+
+.. code-block:: ceylon
+
+    void holaTodos (String* nombres) {
+        for (nombre in nombres) {
+            hola(nombre);
+        }
+    }
+    
+Para pasar un argumento a un parametro secuenciado tenemos tres alternativas.
+Podemos:
+
+    - Proveer una lista explicita de argumentos,
+    - pasar un objeto iterable produciendo el argumentos,o 
+    - especificando un `comprehencion`
+
+El primer caso es facil:
+
+.. code-block:: ceylon
+    
+    holaTodos("world", "marte", "saturno");
+
+Para el segundo caso, Ceylon requiere utilizar el operador `spread`:
+
+.. code-block:: ceylon
+
+    String[] todos = ["world", "marte", "saturno"];
+    holaTodos(\*todos);
+
+Volveremos a el tercer caso, comprenhencion, mas adelante.
+
+Fat arrows y declaracion adelante
+#################################
+
+Las expresiones en Ceylon son mas poderosas que las de Java, y 
+dado esto es posible expresar mas en una expresion mas compacta y 
+es por lo tanto *extremadamente* comun encontrar funciones y valores 
+que simplemente evaluan y devuelven una expresion. Asi que Ceylon nos
+permite abreviar tales definiones de funciones y valores usando una 
+`fat arrow`, `=>`. Por ejemplo:
+
+.. code-block:: ceylon
+    
+    String nombre => PrimerNombre + " " + ultimoNombre;
+
+.. code-block:: ceylon
+
+    Float sqr (Float) => x*x;
+
+Ahora es el tiempo para que te empiezes a sentir comodo con esta sintaxis, 
+debido a que estar viendo comunmente muchos ejemplo de esto. Toma 
+especial atencion a la diferencia entre un `fat arrow`:
+
+.. code-block:: ceylon
+    
+    String nombre => nombre + " " + apellido;
+
+Y una asignación:
+
+.. code-block:: ceylon
+    
+    String nombre = nombre + " " + apellido;
+
+En el primer ejemplo, la exprecion es recomputada cada vez que nombre es
+evaluado. En el segundo ejemplo la expresion es computada una sola vez y el 
+resultado es asignado a nombre.
+
+Tambien podemos definir uan funcion de tipo `void` usando una `fat arrow`.
+En nuestro primer ejemplo pudimos  haber escrito `hola()` como lo siguiente:
+
+.. code-block:: ceylon
+    
+    voide hola() => print("Hola mundo!);
+
+En java y C#, nos permite separar la declaracion de una variable y la iniciación
+de su valor. Hemos visto que esto es permitido en ceylon. Asi que podemos escribir:
+
+.. code-block:: ceylon
+    
+    String nombre;
+    nombre = nombrePila + " " + apellido;
+    print(nombre);
+
+Pero en Ceylon tambien nos permite hacerlo con `fat arrow`:
+
+.. note: Milestone 5
+
+Debido a un bug en M5, el siguiente ejemplo actualmente no es complatiable para la JVM.
+
+.. code-block:: ceylon
+    
+    String nombre;
+    nombre => nombrePila + " " + apellido;
+    print(nombre);
+
+e incluso con funciones:
+
+.. code-block:: ceylon
+
+    Float sqr(Float x);
+    sqr(Float x) => x*x;
+    print(sqr(0.01));
+
+    void hola();
+    hola() => print("hola mundo");
+    hola();
+
+El compilador se asegura de no evaluar un valor o invocar a una funcion
+antes de asignarle un valor o especificar su implentación, como veremos
+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
+resuelven complicadas cosas con numeros. Ceylon no tiene ninguna tipo primitivo, asi
+que los numero son usualmente representados por las clases `Integer` y `Float`,
+volveremos mas tarde sobre este concepto.
+
+las literales Float, son escritas con punto decimaly los enteros sin el.
+
+.. code-block:: ceylon
+    
+    Integer uno = 1;
+    Float zero = 0.0;
+
+Incluso aunque son clases, puedes usarlos como tipicos literales numericos y 
+operadores con ellos.
+
+Por ejemplo, la siguiente funcion eficientemente determina si un `Integer` 
+representa un numero primo:
+
+
+.. code-block:: ceylon
+    
+   "Determine if `n` is a prime number."
+    throws (Exception, "if `n<2`")
+    Boolean prime(Integer n) {
+        if (n<2) {
+            throw Exception("illegal argument \``n``<2");
+        }
+        else if (n<=3) {
+            return true;
+        }
+        else if (n%2==0 || n%3==0) {
+            return false;
+        }
+        else if (n<25) {
+            return true;
+        }
+        else {
+            for (b in 1..((n.float^0.5+1)/6).integer) {
+                if (n%(6*b-1)==0 || n%(6*b+1)==0) {
+                    return false;
+                }
+            }   
+            else {
+                return true;
+            }
+        }
+    }
+
+
+Intentalo corriendo la siguiente funcion:
+
+.. code-block:: ceylon
+
+    "Muestra una lista de todos los numeros de dos digitos primos"
+    void EncuentraPrimos() {
+        print([ for (i in 2.99) if (prime(i)) i ]);
+    }
+    
+Este fue solo un pequeño rompecabezas para mantener tu interes, Explicaremos
+la sintaxis que usamos aqui mas adelante.
+
+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 
+las `clases <http://ceylon-lang.org/>`_ justo ahora, antes de volver a 
+`mas conceptos basicos <http://ceylon.org>`_.
+==================
+Un tour por Ceylon
+==================
+
+..  toctree::
+    :maxdepth: 3
+
+    introducción
+    basico