Coffeescript Express: Aprende a programar en 20 minutos


¿Qué es Coffeescript?

Coffeescript es un lenguaje de programación de alto nivel con una sintaxis muy limpia (muy fácil de escribir y leer) que compila a Javascript ("se vuelve" javascript); Coffeescript es Javascript, pero es muchísimo más fácil de aprender y manejar que el segundo. Si no sabes qué es Javascript, la manera más fácil de explicarlo es:

Javascript es el lenguaje de programación del navegador, el lenguaje que potencia (en mayor medida) a la web actual.


¿Porqué Aprender Coffeescript?

Sencillo: Porque actualmente no hay lenguaje en más auge y necesidad de uso que Javascript. En un mundo que se rige por la web, no puedes permitirte no saber Javascript si quieres ser programador y Coffeescript es la mejor manera de manejarlo. Además, saber Coffeescript te dejará listo para entender y usar prácticamente cualquier lenguaje de alto nivel moderno, llámese Ruby, Python o cualquier otro que quieras añadir a la categoría.

¿Cómo instalar Coffeescript?

Primero instala NodeJS con npm. Una vez que tengas estos 2 en tu computadora, instalar Coffeescript es tan fácil como hacer:

npm install -g coffee-script

En terminal y listo (Usuarios de Linux, no olviden usar sudo, para Mac creo que igual es necesario).

Luego podrás acceder al intérprete de coffeescript en terminal usando el comando "coffee" que también te permitirá compilar tus archivos ".coffee" a ".js" rápidamente.

Lo básico de Coffeescript

Tipos de Datos

Comentarios

Se trata de pedazos de texto que no se ejecutan ni se toman en cuenta en un programa, sino que más bien sirven para explicar nuestro código dentro de un script. Un comentario en Coffeescript se ve así:

# Hola, soy un comentario

Variables

Se trata de "contenedores" para almacenar con un nombre fácil de recordar cualquier tipo de dato u objeto. una variable que guarde el nombre "Xenode Systems" se vería así:

empresa = "Xenode Systems"

Cabe destacar que las variables son dinámicas. esto quiere decir que si declaras una variable y después más abajo en tu programa la vuelves a declarar, esta cambia al segundo valor al llegar a esa parte en la ejecución del código y mantendrá el último valor asignado.

Strings

Son cadenas de texto. Todo tipo de texto que vayas a ocupar dentro de un programa de computadora debe ir como una string, es decir entrecomillado con comillas dobles. Veamos un ejemplo:

"Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

Es importante usar comillas dobles tanto como se pueda, en lugar de simples. Las comillas dobles nos permiten entre otras cosas, usar apóstrofes y comillas simples dentro de un texto sin cerrar la string, concatenarlas con la sintaxis de ruby (veremos eso más adelante) y demás cosas interesantes.

Integers

Se trata de números enteros (sin punto decimal) tales como 1, 2, 10, 60, 900

Floats

Se trata de números con punto decimal, tales como 1.2, 2.5, 10.3, 6.90, 3.1416

Arrays

Son un contenedor de cualquier tipo de objetos, cuya función es guardar cada uno de los objetos adentro en una lista ordenada por índices, un ejemplo sería:

["Pera", "Manzana", "Naranja"]

Ahí arriba tenemos un array que contiene 3 strings, y cada una de estas tiene un índice comenzando por el cero. Esto quiere decir que "Pera" es el "objeto 0" dentro del array, "Manzana" es el 1 y "Naranja" es el 2.

Ranges

Los ranges son rangos precisamente, y se trata de una forma más corta de escribir un array, (por decirlo de alguna manera); Por ejemplo, si yo quisiera hacer una serie de números del 1 al 100 dentro de un array la manera más sencilla de lograrlo sería con un rango, que se vería así:

serie = [1..100]

Esto compilaría a un array que contendría todos los números del 1 al 100 evitándonos el tedio de escribirlo a  mano.

Hashes

Los hashes son conocidos como "diccionarios" en otros lenguajes, y en lo que a javascript respecta son "objetos JSON". Sirven para guardar una relación del tipo "clave : valor" entre objetos y en Coffeescript escribirlos es tan sencillo como hacer uso de la indentación (hablaremos más adelante de esto último), veamos como:

empleados =

  decano:
    nombre: "Lisa Cuddy"
    edad: 40
  contador:
    nombre: "Edward Vogler"
    edad: 52

Eso de allá arriba nos crearía un hash llamado "empleados" donde tendríamos a los empleados ordenados por función y de cada uno tendríamos acceso a los valores "nombre" y "edad" para trabajar en nuestro código. Nótese que indentamos con 2 espacios para las funciones y con otros 2 espacios para los datos de nombre y edad, creando una especie de nesting acomodado. Esto es vital cuando escribimos hashes (el nesting), de otra manera no funcionarán. En el caso de arriba, nuestras claves son las funciones de cada empleado y su valor es otro hash que incluye los datos "nombre" y "edad" respectivamente para c/u.

Booleans

Simplemente hay 2: true y false, cada uno representando a cierto y falso respectivamente dentro de un programa.

Operadores Matemáticos

+ más: suma 1 + 2 = 3
- menos: resta 5 - 3 = 2
* por: multiplicación 2 * 3 = 6
/ entre: división 9 / 3 = 3
= igual: igualdad 0 = 0
% módulo: devuelve el residuo de una división 20 % 3 = 2

Métodos/Funciones:

Los métodos o funciones en programación son bloques de código que se ocupan para un fin, más que nada para automatizar cosas. Un ejemplo de una función Coffeescript:

sum = (number1, number2) ->
  result = number1 + number2
  console.log(result)

Primero tenemos una variable que guarda la función, esto le da un nombre a la misma. Luego tenemos los argumentos de esa función, esto quiere decir, los datos que manejará expresados como variables. Más tarde tenemos el símbolo de función que hace que precisamente se defina la función y finalmente tenemos el código de la función o lo que queremos que haga.

La función de arriba está pensada para correr en consola y lo que hace es sumar 2 números cualquiera y devolvernos el resultado en la consola.

Para correr una función (la del ejemplo específicamente) en nuestro código colocaríamos una línea como esta:

sum(10, 63)

Primero "llamamos" el nombre de la función y le pasamos los argumentos que queremos que maneje al correr; de manera que esos usará para cumplir con lo que su código del interior le dicte.

El código de este pequeño script se vería así:


Como podrán ver allá arriba, al correr el script con el comando "coffee" en terminal nos devuelve el resultado esperado.

Loops:

Un loop es una "secuencia de código" que se corre por cada uno de los elementos dentro de una colección de objetos (un array generalmente). Un ejemplo sería:

array = [1, 2, 3, 4, 5]

for n in array
  console.log(n * 2)

Este loop de arriba lo que hace es tomar los elementos de un array y multiplicarlos por 2, dándonos el resultado en consola. El output es el siguiente:


Los loops empiezan con un for, luego toman una variable cualquiera (elegida por nosotros) que representa a c/u de los objetos dentro de un array/colección y luego sigue la palabra in, seguida del nombre de la colección o array. Luego de definirlo, ponemos abajo e indentado (con un whitespace de 2 espacios) el código que deberá correr el loop. En español, entenderíamos la definición de un loop (el de arriba por ejemplo) como:

por cada número en array haz lo siguiente
Hay otros tipos de loops, un ejemplo es el loop que se crea con la palabra "while" en lugar de for... Pero no veo necesario explicarlo, estudiar eso corre por tu cuenta, (si es que alguna vez lo necesitas).

Splats

Los splats son otro tipo de dato que se puede utilizar en Coffeescript. Se trata de "contenedores" que nos sirven para pasar múltiples valores/variables como argumentos para un método. Un ejemplo práctico sería un programa de una tómbola arreglada. Supongamos que tenemos una tómbola con varios participantes y decimos que quienes saquen los números 42 y 64 son los ganadores indiscutibles de los premios del concurso... Para esto queremos que nuestros amigos Juan y Pedro sean los ganadores sin importar los demás participantes... Veamos entonces cómo programaríamos esto en Coffeescript:



Vamos por partes aquí:

Primero definimos la función de tómbola (rifa_arreglada) que tomará como argumentos al primer y segundo participantes además de los demás (nótese el splat "otros..." en los argumentos). Luego lo que hará esta función será correr la subfunción resultados una vez por el primer participante, (asignándole a propósito el número 42) otra por el segundo (asignándole a propósito el número 64) y finalmente una más por cada uno de los restantes, asignando un número aleatorio a c/u de ellos; (Nótese el "loop" de "for persona in otros" allá arriba).

El loop lo que hace es agarrar y por cada persona dentro de el splat "otros..."  asigna un número aleatorio que saca corriendo el código de las líneas 7 y 8, finalmente corre la subfunción resultados para soltar el número asignado en consola una vez por c/u de los otros también.

La subfunción resultados lo que hace es tomar 2 argumentos: persona y number y lo que hace es soltar un string que dice "tal persona se queda con tal número" en la consola.

Luego necesitamos definir nuestra lista de personas, como se ve en el array de la línea 18. Dentro de este array ponemos a Juan y Pedro primero a propósito, pues queremos que ellos tengan los números ganadores.

Finalmente corremos la función de rifa arreglada (línea 22), pasándole como argumento el array/colección de personas. Esto se resuelve en el siguiente resultado/output:


Como veremos, Juan obtuvo el 42, Pedro, el 64 y los demás un número aleatorio no ganador. Si no entienden muy bien esto de los splats déjenme un comment con sus dudas y les explico como sea necesario para que lo entiendan.

Interpolación de Variables

Nótese que en la línea 14 de nuestro programa de tómbola arreglada tenemos un código que luce así:

console.log("#{persona} se queda con el #{number}")

Mismo que está haciendo uso de una técnica llamada "Interpolación de variables" que nos permite añadir/concatenar variables al interior de una string; Por ejemplo si yo tuviera las variables nombre y edad dentro de un programa y las quisiera mostrar como parte de un mensaje en consola, haría un código como este:



Nótese el #{} que encierra a las variables dentro del mensaje que soltamos a la consola, así es como interpolamos en Coffeescript. Adentro del #{} Puede ir cualquier expresión de coffeescript que queramos, y esta se unirá como parte de la string elegida (o bueno, su resultado más bien). Vean el output de la terminal en la imagen de arriba para dejarlo más claro.

Condicionales

Los condicionales son los que permiten el control de flujo dentro de un programa y básicamente son aquellos pedazos de código que corren si determinada condición se cumple. Veamos un ejemplo:

number_of_life = 42

if number_of_life is 42
  console.log("The number of life is 42 indeed")
else
  console.log("That's not the number of life")

Este es un ejemplo súper sencillo, pero logra su objetivo. Básicamente el código de arriba declara la variable "number_of_life" y un condicional que dice: si (if) el number_of_life es 42, entonces pon en consola "El número de la vida es 42 precisamente", de otra manera (else) pon "Ese no es el número de la vida". El snippet de arriba nos soltaría (obviamente) el primer mensaje. Otro tipo de condicional que no veremos aquí es unless, pero te toca estudiarlo (si es que alguna vez lo llegas a ver u ocupar).

Whitespace (Indentación)

Como verán en los scripts/snippets de Coffeescript que hemos visto hasta ahora, estos tienen un formato de escritura específico, hay ciertas cosas con "sangría". Esta "sangría" en realidad se llama indentación y define varias cosas, como por ejemplo:
  • El cuerpo de una función
  • El código a correr en un loop
  • El cuerpo de un condicional
etcétera. No hay mucho que decir acerca de esto, excepto que si vas a escribir una función todo su "contenido" debe ir "indentado" con dos espacios (se pueden usar espacios o tabuladores para indentar, pero NUNCA combinados) con respecto a la línea de definición, un ejemplo:

sum = (number1, number2) ->
  result = number1 + number2
  console.log(result)

Lo mismo para el cuerpo/código de un loop:

for n in array
  console.log(n * 2)

Y también para el "contenido" de un condicional:

weather = "Sunny"

if weather is "Sunny"
 console.log("Yay!")weather = "Sunny"

if weather is "Sunny"
 console.log("Yay!")

Cuando escribes un programa completo, "indentas y desindentas" según se requiera. Por ejemplo, cuando una línea de código ya no pertenezca a tu función/loop/condicional en cuestión quitas la indentación y si vuelves a hacer otro la abres de nuevo con relación a este segundo. Ejemplo:


Las indentaciones o "whitespace" son necesarias (y obligatorias) en Coffeescript porque de otra manera, los programas no funcionarían y soltarían errores al compilar.

Syntactic Sugar

Esta es una expresión que en español comprenderíamos como "Dulce Sintaxis" y se refiere a ciertas keywords de Coffeescript que podemos utilizar para escribir código que se parece mucho más al inglés escrito que al código de un programa de computadora. éstas son:

is que compila a === (igualdad estricta)
isnt que compila a !== (desigualdad estricta)
and que compila a && (se refiere al término "y", como en la oración "puedes comprar nachos y gomitas")
or que compila a || (se refiere al término "o", como en la oración "puedes comprar chocolates o palomitas")
not que compila a ! (se refiere al término "no" como en la oración "el cielo no es verde")

Cada una de estas keywords hace lo que te imaginarías dentro de un programa, pero para evitar dudas, les dejaré un snippet comentado con ejemplos y el output que suelta cada uno para que se den una idea de cómo es que funcionan a continuación:



Otros ejemplos de dulce sintaxis serían las keywords on y off que representan a los booleanos true y false respectivamente o la palabra of que representa a la palabra in que usamos en los loops. Una tablita de syntactic sugar a continuación:



Operador existencial

Se trata del símbolo ? y lo que hace es verificar si algo existe dentro del programa o no, si bien no se trata de un ejemplo de "dulce sintaxis" específicamente, va de la mano con esta de algún modo. Ejemplos de uso:



OOP (Programación Orientada a Objetos)

Actualmente el paradigma de programación más usado es el de la OOP (object oriented programming) y entenderlo es bastante sencillo gracias a Coffeescript. Antes que nada, debemos explicar que la OOP se centra en una filosofía de que, (al igual que en el mundo real) Todo es un objeto dentro de un programa de computadora. En un escenario simple, un "empleado" es un objeto del ente "Persona" que puede ser una subclase del ente "Empresa" dentro de un programa empresarial, ¿se entiende? Veamos entonces:

Supongamos que queremos escribir un programa para una tienda de mascotas. Uno de los "objetos" que existiría dentro de dicha tienda serían (obviamente) los animales. Para hacer nuestro programa con un paradigma de OOP, Tendríamos que definir a nuestro ente "Animal" por medio de una clase, y le podríamos poner subclases para cada uno de los animales que haya en la tienda.  Luego podríamos hacer métodos y demás cosas interesantes con ellos. En código, esto se ve así:


Vamos por partes:

Primero declaramos la superclase "Animal" (nótese que todas las clases empiezan con mayúscula). Una clase debe de (a fuerza) llevar un constructor, que es como una función pero que en lugar de un "=" lleva ":" en su declaración y sirve para precisamente construir objetos de una clase determinada, (crearlos). A esta "función especial" le pasaremos como "variables de instancia" (es decir, variables con un arroba enfrente) todos los datos que queremos que lleve un objeto de la clase, en este caso sólo estamos requiriendo el nombre del animal. Las variables de instancia no son más que variables con un @ enfrente y la peculiaridad que tienen es que se extienden (quiere decir, que están disponibles para) a todos los objetos de una clase, podemos agregar tantas como creamos necesarias a nuestro constructor.

Cabe destacar que, (como verán arriba) todas las funciones/métodos de todas las clases llevan ":" en lugar de "=" en su definición. Luego de declarar el constructor, podemos empezar a escribir métodos/funciones propias de esa clase como el "makeNoise" de allá arriba en Animal.

Una vez que tenemos toda una "clase madre" definida con su constructor y métodos deseados, podemos generar unas subclases que hereden todos los atributos de la clase madre (como por ejemplo sus métodos) disponibles pero que también puedan tener sus propias características, en este caso creamos 2 subclases: Dog y Cat, dándoles a cada una la característica de "extender la clase Animal" (osea tener todos sus métodos y características además de los suyos propios) y les definimos su propio método makeNoise que toma las características del makeNoise de la clase madre (gracias a la keyword super) y que aparte permite definir directamente el sonido propio de cada animal.

Luego inicializamos los objetos "dog" y "cat" (creamos objetos nuevos para una clase) asignándoles una variable y les pasamos como argumento (por eso del constructor de Animal) el nombre que queramos que el animal tenga.

Más tarde hacemos que nuestros objetos recién creados corran su método "makeNoise" y si nos damos cuenta lo que este método hace (línea 6) es poner un mensaje en consola que dice "Animal hace tal Sonido". El output del snippet de arriba es el resultado de toda nuestra construcción de clases y se puede ver en el screenshot de allá arriba.

Compilando Coffeescript a Javascript

Hay muchas maneras, y también está una opción para hacerlo en tiempo real, sin embargo yo siempre he encontrado el siguiente workflow muy cómodo:

Hacemos un directorio (carpeta) que se llame "coffee" y otro que se llame "js", Trabajamos todo en el directorio coffee en los diferentes archivos que vayamos a ocupar y luego los compilamos a sus contrapartes javascript para poderlos usar en nuestra app/web. Más tarde podemos mover el directorio de coffee fuera de la app/web si así lo deseamos. Para hacer este tipo de compilación (estando en consola dentro de la carpeta del proyecto que contiene tanto los directorios "coffee" como "js") usaríamos el comando:

coffee -o js/  -c coffee/

Y listo. eso compilaría todos los archivos coffeescript dentro del directorio "coffee" a sus contrapartes en javascript guardándolas en el directorio "js" mencionado anteriormente. Otra manera (la mejor para rendimiento) de hacer la compilación es compilar todos los archivos ".coffee" dentro de un directorio a un solo archivo javascript que será el que incluyamos en nuestra aplicación para evitar que el navegador haga varias requests cuando cargue nuestra app/web. Esto se logra con el comando:

coffee -j js/application.js -c coffee/*.coffee

Esto lo que haría sería compilar todos los archivos con extensión .coffee que estén dentro de nuestro previamente mencionado directorio "coffee" a un solo archivo llamado "application.js" que se guardará en nuestro directorio "js".

Diálogos Javascript

Una de las cosas que nos permite escribir programas más rápido y ver los resultados de nuestro aprendizaje interactivamente es escribir Coffeescript para correr en el navegador. Esto se hace como lo hemos visto, pero también podemos usar los métodos:

alert: Sirve para mostrarle un mensaje al usuario y éste debe confirmar que ya lo leyó para hacerlo desaparecer.

Ejemplo:

alert("Bienvenid@, por favor siéntete libre de disfrutar de nuestro sitio web.")

prompt: Sirve para pedirle algún dato (que se vuelve string) al usuario

Ejemplo:

nombre = prompt("¿Cuál es tu Nombre?")
alert("Tu Nombre es #{nombre}")

confirm: Sirve para obtener respuesta a una pregunta estilo "Sí/No" por parte del usuario con botones de "Aceptar" y "Cancelar" que evalúan a true y false respectivamente.

Ejemplo:

respuesta = confirm("¿Te Gustan los Chocolates?")

if respuesta is true
  alert("Yummy! a mí también!")
else
  alert("Qué lástima...!")

Práctica: Juego Jigsaw

¡Basta de teoría! Veamos en vivo cómo se aplican los conocimientos adquiridos aquí para hacer un programa en Coffeescript, video a continuación:




Tareas

Intencionalmente, dejé un tema fuera de este curso. Se trata del switchcase y es algo que se hace mucho en Javascript. Les queda de tarea buscar y estudiar qué es un switchcase y cómo implementarlo con Coffeescript, ¡Suerte!

Continuar tu aprendizaje

No hay mejor continuación a este mini-curso que nuestro tutorial de Aprendamos juntos Coffeescript. Si te interesó el tema, pásate para allá para continuar aprendiendo.

Datos interesantes, enlaces de interés

Js2Coffee

Se trata de una web donde puedes transformar "al vuelo" código javascript a coffeescript y viceversa, ¡Bastante útil!

Coffeescript Cookbook

Como su nombre lo indica, el libro de recetas de Coffeescript. Si algún día tienes una duda de cómo hacer algo en Coffeescript, lo más seguro es que la respuesta (o varias respuestas que te guiarán a la final) estén ahí.

Sitio web de Coffeescript

Aprende más sobre Coffeescript en su sitio web oficial y además, tienen un intérprete/ejecutor en tiempo real para el lenguaje, cosa que es muy divertida (Con lo que hicimos la práctica de Jigsaw).

Sujeto, Verbo, Adverbio

Hay una cosa de programación que me faltó explicar aquí y que considero muy útil. Se trata de mi concepto "Sujeto, Verbo, Adverbio" y básicamente es un concepto que explica las expresiones de programación como si de enunciados en español se tratase. Tomemos de ejemplo esta expresión de jQuery escrita en Coffeescript:

$("div#mydiv").slideToggle("slow")

No voy a explicar qué es jQuery ni mucho menos, sino el concepto como tal:

Ahí arriba tenemos una expresión de programación. Ésta consta de un Objeto a manipular/cambiar, un método que se encarga de hacer la modificación/acción y un argumento que dice cómo hacerlo. Básicamente es como una oración en español donde nuestro objeto a manipular es el Sujeto (qué manipular), el método que le pasemos para manipularlo sería como el verbo (qué hacerle al sujeto) y finalmente tenemos el argumento que es como un adverbio (cómo aplicar el verbo). Lo que hace la función de arriba es tomar la capa con id "mydiv" dentro de una página web y hacer que "aparezca deslizándose" poco a poco, de manera lenta para más impacto. Si entiendes este concepto, programar en cualquier lenguaje de alto nivel se te hará muy sencillo.

Y pues bueno, con esto llegamos al final de nuestro mini-curso "Coffeescript Express"; Y aunque es un tutorial que se aprende en 20 minutos escribirlo tomó varias horas, por lo que si te gustó o aprendiste algo, no te olvides de apoyarnos con un tweet antes de irte:

Aprendí a programar en 20 minutos con el tutorial "Coffeescript Express" de @xenodesystems http://bit.ly/134UMEl - Tweet!