Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

23
Tipos Estáticos y Ceylon Gavin King http://ceylon-lang.org

description

http://sg.com.mx/sgce/2013/sessions/c%C3%B3mo-minimizar-las-desventajas-del-tipado-est%C3%A1tico-y-capitalizar-sus-ventajas Esta será una conferencia técnica sobre lenguajes de programación donde Gavin King discutirá las ventajas y desventajas del tipado estático (static typing), mostrando cómo es que lenguajes modernos de programación como Ceylon ayudan a minimizar las desventajas al mismo tiempo que capitalizan las ventajas.

Transcript of Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Page 1: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Tipos Estáticos y Ceylon

Gavin King

http://ceylon-lang.org

Page 2: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Aprender Ceylon

Taller Ceylon

El sabado a las 9:30 AM

Goldsmith #40 Col. Polanco, entre Dickens y Emilio

Castelar

Con Gavin y Enrique

Page 3: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Acerca de Ceylon

• Nuevo lenguaje de programación

• Para máquinas virtuales– JVM y JavaScript (el entorno)

• Plataforma modular– “módulo del lenguaje” — mínimo, ligero

– otros módulos independientes del entorno

– módulos para un solo entorno (JVM, JavaScript)

Page 4: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Acerca de Ceylon

• Herramientas– Ceylon IDE y línea de comando

• Infraestructura para manejar y compartir los módulos– arquitectura de repositorios de módulos y dependencias

– Ceylon Herd (un repo central para la comunidad)

– entorno de módulos (JBoss Modules/CommonJS)

Page 5: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Expresividad

• Es muy fácil diseñar un lenguaje muy expresivo

• Por ejemplo, con los lenguajes “dinámicos” se siente como que se puede hacer casi lo que sea

• Pero con lenguajes así es muy difícil crear herramientas que nos ayuden como programadores a encontrar bugs, refactorizar y analizar el código– el compilador

– el IDE

– el compilador de documentación

Page 6: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Expresividad

• Para programas grandes las herramientas pueden mejorar mucho la productividad

• Por lo tanto necesitamos un lenguaje con reglas– Estas reglas nos estorban para expresarnos!

– Pero cuando están bien diseñadas frecuentemente nos ayudan a llegar a un diseño más elegante y más robusto

– Ademas, las herramientas y las reglas nos ayudan a comprender el código horrible que han hecho nuestros compañeros locos! (Gasto mucho mas tiempo en leer el código de otros que en escribir mi propio código)

Page 7: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Limites de expresividad

• Siempre podemos aumentar la expresividad de un lenguaje añadiendo características, introduciendo nuevas reglas especiales, nueva sintaxis

• Al final llegamos a tener un lenguaje tan complicado que el programador no sabe todas las reglas, ni puede reproducir el razonamiento del compilador, ni entiende el código de otros o de las bibliotecas que utiliza

• También hay limites básicos de decidibilidad que restringen el razonamiento del compilador

Page 8: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Objetos y tipos estáticos

• Un lenguaje orientado a objetos es un lenguaje con polimorfismo de subtipos

• Cuando combinamos subtipos con un sistema de tipos estáticos, llegamos muy rápido al problema de tipos contenedores (colecciones)

• Para modelar el contrato de un tipo contenedor hay que introducir polimorfismo paramétrico (generics)– Entonces encontramos las dos variedades de

polimorfismo en Java, C#, C++, Ceylon, Scala, ...

Page 9: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Objetos y tipos estáticos

• La mala noticia: un sistema de tipos con la combinación de los dos polimorfismos es necesariamente bastante complejo– Abandonamos objetos? Abandonamos tipos estáticos?

No! Al final vale la pena

• En cambio, buscamos cómo presentarlo de manera más digerible y eliminar la complejidad innecesaria– Qué ofrece la nueva generación de lenguajes con tipos

estáticos? Pues que son los puntos dolorosos?

Page 10: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Los puntos dolorosos

• Declarar tipos resulta en verbosidad

• Abstraer sobre tipos que no controlamos– por ejemplo, tipos definidos en otros módulos que no

tienen ningún supertipo en común

• Varianza con wildcards

• Tratar con funciones como valores y abstraer sobre tipos de funciones– para definir funciones genéricas de orden superior

• El valor null y la maldita NullPointerException

Page 11: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Verbosidad

• Poner el tipo como int, bool, char no cuesta mucho, pero ahora, con generics, tratamos con tipos como

Map<String,WeakRef<Object?>>String|{Character*}

• Inferencia de tipos (alcance local)value weakRefMap = Map { key1 -> WeakRef(val1),

key2 -> WeakRef(val2) };

• Aliases de tiposalias WeakRefMap => Map<String,WeakRef<Object?>>;alias Stringish => String|{Character*};

Page 12: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Uniones, intersecciones

• A veces encontramos casos como– print() que acepta un String, Integer, o Float

– readLine() que produce un String, EOF o Error

– send() que acepta algo que es Persistent y Serializable

• Malas soluciones: – usar Object

– sobrecargar print()

– crear una clase intermedia (algun tipo de wrapper)

– En un lenguaje dinámico no necesitamos nada así

Page 13: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Uniones, intersecciones

• Mejor solución con tipos unión e intersección– void print(String|Integer|Float line) { ... }

– String|EOF|Error readLine() { ... }

– void send(Persistent&Serializable message) { ... }

• De hecho, uniones e intersecciones nos ayudan mucho a simplificar el sistema de tipos y hacerlo más elegante y más completo– Les van a encantar, lo prometo

Page 14: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Varianza

• Covarianza: intuitivamente un Set<Integer> es un Set<Number>

– también tenemos contravarianza

• Mala solución: wildcards de Java– el Set<Integer> es un Set<? extends Number>

– casi nadie los entiende completamente

– resultan en errores muy confusos

– bastante verboso

Page 15: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Varianza

• Mejor solución con varianza de lado de declaración

• Declaramos la varianza del tipo donde lo definimos– covariante out, contravariante in

– interface Set<out T> { ... }

– el compilador verifica que el tipo sí es verdaderamente covariante o contravariante

• Cuando utilizamos el tipo, todo funciona como intuitivamente esperamos– ahora Set<Integer> sí es un Set<Number>

Page 16: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Null y Nothing

• Socavamos el sistema entero cuando ponemos hoyos para “conveniencia”– NullPointerException es una excepción de tipo en

tiempo de ejecución como tienes con los tipos dinámicos!

• El tipo bottom o Nothing es un subtipo de todo tipo– Corresponde al conjunto vacío en matemáticas

– Entonces el tipo bottom no tiene ningún valor

– Excepto en Java, C#, Scala ... donde tiene el valor null

– Oops.

Page 17: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Null y Nothing

• En Ceylon, el tipo Nothing no tiene ningún valor

• Tenemos una clase Null perfectamente ordinaria con un único valor null– Escribimos “un string o null” como String|Null

– O lo abreviamos como String?

• El compilador verifica que cada valor ha sido inicializado antes de ser utilizado– para no encontrar valores no inicializados en tiempo de

ejecución

• Ninguna NullPointerException ocurre jamás!

Page 18: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Acotamiento de tipos

• Cómo podemos obtener un String si tenemos un valor de tipo String?– un caso especial del problema de acotamiento

• El tipo de un valor puede cambiar con el flujo de código condicional

• Ya no necesitamos los casts inseguros de C

String? name = process.arguments[0];if (exists name) { //aquí, name es de tipo String print(“Hello, “ + name + “!”);}

Page 19: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Funciones y tuplas

• Cómo podemos representar el tipo de una tupla por ejemplo [0.0, 0.0, “origen”]

• Luego, cómo representar el tipo de una función– combina un tipo de tupla con otro tipo

• Definimos Tuple y Callable como clases ordinarias y proveemos azúcar sintáctica– tipo de tupla: [Float, Float, String]

– tipo de función: Point(Float, Float, String)

• Nos deja definir funciones de orden superior incluso funciones genéricas como compose()

Page 20: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

La mala noticia

• El sistema de inferencia de tipos funciona bien sin ambigüedades gracias al concepto de tipos principales– Cada expresión tiene su único tipo más específico, su

tipo principal (frecuentemente expresado con el uso de unión y intersección)

• Funciones sobrecargadas rompen el sistema de tipos principales– Una función sobrecargada no tiene ningún tipo principal

– Como los lenguajes dinámicos no tenemos overloading

Page 21: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Conclusión

• Se puede mejorar mucho el sistema de tipos, aliviando los puntos dolorosos

• Un punto clave es ajustar el punto de vista para pensar en tipos como conjuntos

• Así podemos tratar con tipos de una manera más sofisticada, formando expresiones con | y &, introduciendo aliases, infiriendo tipos complejos

• El problema de decidibilidad limita lo que podemos hacer

Page 22: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Conclusión

• La nueva generación de lenguajes de tipado estático es mucho más expresiva

• Puede ser tan expresivo y flexible como un lenguaje dinámico? No!– O, más bien, expresa cosas diferentes (tipos)

• Aún vale la pena — tipado estático tiene sus propias ventajas, facilita herramientas!

Page 23: Cómo minimizar las desventajas del tipado estático y capitalizar sus ventajas

Preguntas

http://ceylon-lang.org

Taller CeylonEl sabado a las 9:30 AM

Goldsmith #40 Col. Polanco, entre Dickens y Emilio Castelar