Commits

Miguel Gordian committed 37bc80b Merge

merge: Tema de argumentos con nombre

Comments (0)

Files changed (2)

source/ArgumentosConNombre.rst

+=====================
+Argumentos con nombre
+=====================
+
+Esta es la duodécima parada del tour de Ceylon. En la parada anterior aprendimos
+acerca de funciones. Esta parte se enfoca en cubrir el soporte de Ceylon para
+usar argumentos con nombre.
+
+---------------------
+Argumentos con nombre
+---------------------
+
+Considere la siguiente función:
+
+.. code-block:: ceylon
+    
+    void printf(Writer to, String format, {Object*} values) {
+        //...
+    }
+
+
+Hemos visto cientos de ejemplos de invocar una función o instanciar
+una clase usando una sintaxis similar a C, donde los argumentos son
+delimitados por paréntesis y separados por coma. Argumentos son
+asignados a parámetros por su posición en la lista. Veamos un
+ejemplo más:
+
+.. code-block:: ceylon
+    
+    printf(writer,
+           "Thanks, %s. You have been charged %.2f.
+            Your confirmation numbers is %d.",
+           { user.name, order.total, order.confirmationNumber });
+
+Esto trabaja bien. Sin embargo, Ceylon ofrece un alternativo
+protocolo de invocación de una función que es usual mente 
+fácil de leer cuando hay más de uno o dos argumentos:
+
+.. code-block:: ceylon
+    
+    printf {
+        to = writer;
+        format = "Thanks, %s. You have been charged %.2f.
+                  Your confirmation number is %d.",
+        { user.name, order.total, order.confirmationNumber }
+    };
+
+Esta invocación es llamada **lista de argumentos con nombre**.
+Podemos reconocer una lista de argumentos con nombre por que
+utiliza llaves en ves de paréntesis. Note que los argumentos
+son separados por punto y coma. Hemos especificado el nombre
+de cada parámetro.
+
+Usual mente le damos un formato en múltiples lineas a la invocación
+de argumentos con nombre.
+
+--------------------
+Argumentos iterables
+--------------------
+
+Desde que el parámetro ``values`` es de tipo ``Iterable``, se
+nos esta permitido abreviarlo, dejando fuera el nombre del
+parámetro y las llaves que encierran a la expresión iterable.
+
+.. code-block:: ceylon
+    
+    printf { 
+        to = writer;
+        format = "Thanks, %s. You have been charged %.2f.
+                  Your confirmation number is %d.";
+        user.name, order.total, order.confirmationNumber
+    }
+
+De hecho, podemos dejar fuera los nombres de los parámetros 
+completamente.
+
+
+-------------------------------------------
+Dejando fuera los nombres de los parámetros
+-------------------------------------------
+
+Contraria a la descripción de la característica "lista de
+argumentos con nombre", podemos actualmente dejar fuera los
+nombres de el parámetro si escribimos los argumentos 
+descendente mente en el orden correcto:
+
+.. code-block:: ceylon
+    
+    printf {
+        writer;
+        "Thanks, %s. You have been charged %.2f.
+         Your confirmation number is %d.";
+        user.name, order.total, order.confirmationNumber
+    }
+
+Si, existe una muy buena razón para esto, ¡estamos a punto de verla!
+
+--------------------------------------------
+Sintaxis declarativa para instanciar objetos
+--------------------------------------------
+
+Las siguientes clases definen una estructura de datos para definir
+tablas:
+
+.. code-block:: ceylon
+    
+    class Table(String title, Integer rows, Border border,
+                    {Column*} columns) {}
+
+    class Column(String heading, Integer width,
+                    String content(Integer row) {}
+
+    class Border(Integer padding, Integer weight) {}
+
+Por supuesto, podemos construir una ``Table`` usando una lista 
+de argumentos posicionales y funciones anónimas:
+
+.. code-block:: ceylon
+    
+    Table table = Table("Squares", 5, Border(2,1),
+                       { Column("x",10, (Integer row) => row.string),
+                         Column("x^2",12,(Integer row) => (row^2).string) });
+
+Sin embargo, es mucho mas común usar una lista de parámetros con
+nombre para construir un complejo gráfico de objetos. En esta sección
+vamos a conocer algunas nuevas características de la lista de argumentos
+con nombre, que hacen especialmente conveniente construir gráficos
+de objetos.
+
+Primero, note que la sintaxis que ya hemos usado para especificar
+el valor de un argumento con nombre se ve exactamente como la sintaxis 
+para refinar un atributo ``formal``. Si tu lo piensas así, teniendo
+en cuenta que un parámetro de una función puede aceptar referencia a 
+otras funciones, todo el problema de especificar valores para 
+argumentos con nombre comienza a parecerse mucho como el problema
+de refinar miembros abstractos. Entonces, Ceylon deberá permitirnos
+reusar mucha sintaxis de la declaración de los miembros dentro 
+de una lista de argumentos con nombre.
+
+Es completamente legal incluir las siguientes construcciones en
+una lista de argumentos con nombre:
+
+- Declaración de funciones - especifica el argumentos de un parámetro que
+  acepte una función.
+- declaración de object(clase anónima) - son útiles para especificar
+  el valor de un argumento con nombre donde el tipo es una interfaz o
+  una clase abstracta, y
+- Declaración de getter - nos permite computar el valor de un argumento.
+
+Esto ayuda a explicar por que listas de argumentos con nombre son delimitadas
+por llaves: La sintaxis general para una lista de argumentos es muy muy 
+cercana a la sintaxis para el cuerpo de una clase, función o atributo.
+Note, otra vez, cuanta flexibilidad deriva de un lenguaje regular.
+
+Así podemos escribir un código que construye una ``Table`` como sigue:
+
+.. code-block:: ceylon
+    
+    Table table = Table {
+        title="Squares";
+        rows=5;
+        border = Border {
+            padding=2;
+            weight=1;
+        };
+        Column{
+            heading="x";
+            width=10;
+            function content(Integer row)
+                => row.string;
+        }
+        Column {
+            heading="x^2";
+            width=12;
+            function content(Integer row)
+                => (row^2).string;
+        }
+    }
+
+
+Note que especificamos el valor de el parámetro con nombre ``content``, 
+usando la sintaxis usual para declarar una función.
+
+Aun mejor, usando el atajo que hemos visto antes, nuestro ejemplo puede
+ser un poco mas abreviado como este:
+
+.. code-block:: ceylon
+    
+    Table table = Table {
+        title="Squares";
+        rows=5;
+        Border {
+            padding=2;
+            weight=1;
+        };
+        Column{
+            heading="x";
+            width=10;
+            content(Integer row)
+                => row.string;
+        }
+        Column {
+            heading="x^2";
+            width=12;
+            content(Integer row)
+                => (row^2).string;
+        }
+    }
+
+Note como hemos transformado el código desde una forma que enfatiza
+invocación a una forma que enfatiza declaración de una estructura
+jerárquica. Semántica mente, las dos formas son equivalentes. Pero
+en términos de legibilidad, son un poco diferentes.
+
+Podemos poner el código anterior totalmente declarativo en su propio
+archivo y deberá verse como un tipo de "mini-lenguaje" para definir 
+tablas. De hecho, su óodigo ejecutable puede ser corregido sintáctica mente
+por el compilador de Ceylon y después compilado a bytecode de Java o de 
+Javascript. Aun mejor, el IDE de Ceylon deberá proveer soporte para nuestro
+mini-lenguaje. En un completo contraste a el soporte DSL en algunos
+lenguajes dinámicos, ¡cualquier DSL de Ceylon es completamente seguro en 
+cuanto a tipos! Puedes pensar en la definición de las clases ``Table``,
+``Column`` y ``Border`` como definiendo el "esquema" o la "gramática" de
+un mini-lenguaje. (De hecho, ellos realmente definen una sintaxis de árbol
+para el mini-lenguaje.)
+
+Ahora veamos un ejemplo de una lista de argumentos con nombre con
+una declaración getter:
+
+.. code-block:: ceylon
+    
+    shared class Payment(PaymentMethod method,
+                         Currency currency,
+                         Float amount) {}
+
+    Payment payment {
+        method = user.paymentMethod;
+        currency = order.currency;
+        value amount {
+            variable Float total = 0.0;
+            for (item in order.items) {
+                total += item.quantity * item.product.unitPrice;
+            }
+            return total;
+        }
+    }
+
+Finalmente, aquí hay un ejemplo de una lista de argumentos con nombre 
+con una declaración de ``object``:
+
+.. code-block:: ceylon
+    
+    shared interface Observable {
+        shared void addObserver(Observer<Nothing> observer) {
+            //...
+        }
+    }
+
+    shared interface Observer<in Event> {
+        shared formal void on(Event event);
+    }
+
+    observable.addObserver {
+        object observer 
+                satisfies  Observer<UpdateEvent> {
+            on(UpdateEvent e) => 
+                print("Update: " + e.string);
+        }
+    };
+
+(Note que ``Observer<T>`` es asignable a ``Observer<Nothing>`` para
+cualquier tipo ``T``, desde que ``Observer<T>`` es contra variante en su
+parámetro de tipo ``T``. Si esto no te es entendible, por favor lee 
+la sección de `generics` otra vez.)
+
+Por supuesto, como hemos visto en la parada anterior de funciones, una 
+mejor manera de resolver este problema puede ser eliminar la interfaz 
+``Observer`` y pasarle la función directamente:
+
+
+.. code-block:: ceylon
+    
+    shared interface Observable {
+        shared void addObserver<Event>(void on(Event event)) { ... }
+    }
+
+    observable.addObserver {
+        void on(UpdateEvent e) => 
+                print("Update: " + e.string);
+    };
+
+-------------------------------
+Definiendo intefaces de usuario
+-------------------------------
+
+Uno de los primeros módulos que vamos a crear para Ceylon deberá
+ser una librería para templates HTML en Ceylon. Un fragmento de HTML
+estático deberá lucir como esto:
+
+.. code-block:: ceylon
+    
+    Html {
+        Head {
+            title = "Hello world";
+            cssStyleSheet = "hello.css";
+        };
+        Body {
+            Div {
+                cssClass = "greeting";
+                "hello World"
+            },
+            Div {
+                cssClass = "footer";
+                "Powered by Ceylon";
+            }
+        };
+    }
+
+Incluso aunque parezca como un tipo de lenguaje de template,
+es solo una expresión ordinaria.
+
+.. important:: Nota de implementación - Milestone 5
+
+    Esta libreria aun no existe. Por que no te unes al 
+    desarrollo de la plataforma de Ceylon.
+
+-----------
+Aún hay más
+-----------
+
+Hay demasiadas aplicaciones de esta sintaxis del lado
+de la definición de interfaces de usuario. Por ejemplo, Ceylon 
+nos permite usar una lista de argumentos con nombre para 
+especificar los argumentos del elemento anotación de un programa.
+Pero tendremos que volver  a este temas de las anotaciones en una
+entrega futura.
+
+La siguiente sección aun introduce otra manera de especificar un
+argumento a una función: ``comprensión``.
+
     generics
     modulo
     funciones
+    ArgumentosConNombre
+
 Para alguna critica o sugerencia puedes contactarme a 
 `@ilcapitanozoek <https://twitter.com/ilcapitanozoek>`_ en twitter.