Skip to content

dart

zx-dart

He desarrollado un emulador de ZX Spectrum en Dart. ZX Spectrum fue uno de los ordenadores más populares durante la década de los ochenta, y este año se cumplieron treinta desde su creación. Dart es un nuevo lenguaje de programación que está desarrollando Google. He llamado zx-dart al proyecto y lo he liberado como código abierto.

zx-dart

La versión de código nativo en Dart se puede ejecutar en Dartium, que es una versión de Chrome que incluye la máquina virtual de Dart. Aunque el rendimiento es pésimo, no alcanza ni un frame por segundo. Hay que tener en cuenta que Dart todavía está en desarrollo, las mejoras tienen que ir llegando poco a poco, además de que la especificación oficial del lenguaje cambia cada pocas semanas, por lo que el código escrito hoy puede que no funcione mañana.

Dart viene acompañado de una herramienta llamada (actualmente) dart2js que convierte el código Dart a JavaScript, de forma que se pueda ejecutar directamente en Chrome sin necesidad de la máquina virtual de Dart. Afortunadamente esta versión alcanza los 20 FPS en mi máquina y el emulador se deja probar, aunque para una simulación realista de un Spectrum debería alcanzar al menos 50 FPS.

Demo online: /files/zxdart/index.html

El emulador que he implementado está basado en JSpeccy. Realiza una emulación básica de un Spectrum 48K, con carga de ROM y ejecución de BASIC. Le faltan muchas características básicas, como la generación de sonido o la posibilidad de cargar snapshots por ejemplo. Pero hoy en día hay muchos emuladores bastante completos para casi cualquier plataforma, por lo que no merece la pena complicar el desarrollo para reinventar la rueda. Quizás un port a Dart de algún emulador ya existente escrito en JavaScript podría ser una mejor opción.

Ha sido emocionante el primer arranque, después de múltiples fallos, y ver el famoso mensaje de copyright.

Algo viejo, algo nuevo

DartAndo otra vez trasteando con Dart, el nuevo lenguaje de programación de Google para la web. Aunque ellos en vez de “lenguaje” lo llaman “plataforma”. He cogido un proyecto viejo y lo estoy adaptando al nuevo lenguaje, sobre todo para probar la nueva versión del IDE, de Dartium, que es un build especial de Chrome que lleva incluida la máquina virtual de Dart, y dart2js, que es el tercer conversor de Dart a JavaScript que liberan.

Dart está todavía en desarrollo, lo que quiere decir que ahora mismo lo único que se puede hacer es trabajar sobre la versión alpha. Todavía le queda mucho camino por recorrer, pero las primeras sensaciones es que es mucho mejor que JavaScript para proyectos grandes que requieran un mínimo de organización. Tiene más de “Java” que de “Script”.

En el IDE han añadido algunas cosas básicas que las primeras versiones que liberaron no tenían. ¡Ya se puede renombrar ficheros! Aunque lo más importante es que han añadido un pequeño depurador. Desgraciadamente está muy verde. La depuración paso a paso no está muy fina todavía, por ejemplo en los switch/case obliga a pasar por cada case en vez de ir directamente al que cumple la condición como es lo habitual. Aunque lo peor es que no se pueden añadir watches, por lo que al final se acaba depurando a la antigua usanza, tirando mensajes por consola, convirtiendo los desarrollos actuales en toda una heroicidad.

Por lo que respecta al lenguaje en sí, poco que decir, es parecido a Java por ejemplo, con sus clases, interfaces y demás. Aunque me preocupa un poco la diferencia de tipos con JavaScript, en particular de los enteros. En Dart los enteros no tienen un tamaño fijo predeterminado, a diferencia de JavaScript que son de 64 bits. Esto hace que las operaciones de manipulación de bits se comporten de forma distinta en un lenguaje y otro. Sobre todo porque en JavaScript además este tipo de operaciones se truncan a 32 bits. Muchas aplicaciones no utilizan este tipo de operaciones, pero curiosamente en el tipo de desarrollos que yo suelo hacer son bastante habituales, ya que manipulo grandes cantidades de información a nivel binario.

El API está evolucionando bastante rápido, aunque eso implica que es normal encontrar algunas discrepancias entre la documentación y la implementación. Por ejemplo, el generador de números aleatorios es una función de la clase Math, aunque la documentación indica que se encuentra en una clase aparte Random. En realidad no tiene mucha importancia, y si me he dado cuenta es porque el generador no funciona bien, siempre genera la misma secuencia de números, y tratando de resolverlo estuve estudiando un poco más a fondo la documentación.

Por último, un tema importante a tener en cuenta es que las aplicaciones en Dart están pensadas para ejecutarse desde línea de comandos o desde un navegador, pero la única forma de tener una interface gráfica hoy en día es ejecutarlas desde un navegador. Tengo curiosidad por saber como evolucionará esto, sobre todo porque tener que implementar una aplicación típica de escritorio es un requerimiento normal. Quizás la solución sea desarrollar bindings con algunas librerías ya existentes. De hecho, desde Dart se pueden realizar llamadas a código C/C++, a la manera de los métodos native de Java por ejemplo. Es una vía interesante a estudiar.

Dart: Algunos apuntes sueltos

Algunos apuntes sueltos sobre Dart, el lenguaje de programación para la web que está desarrollando Google.

 

Programación estructurada
Proporciona librerías, clases, interfaces, herencia simple, getters y setters, métodos estáticos, genéricos, sobrecarga de operadores, … pero como contrapartida también permite omitir los tipos en las declaraciones.

 

Constructores con nombre

No permite sobrecargar los métodos, pero ofrece una solución para sobrecargar los constructores mediante generative constructors (¿constructores generativos?) utilizando una notación de punto. Útil para los contructores de conversión.

 

Privacidad

Los métodos y variables de instancia privados se denotan anteponiendo un guión bajo (“_”) al nombre. De esta forma no hace falta consultar las declaraciones para averiguar el ámbito de aplicación. La privacidad es a nivel de librería, no de clase.

 

Inicialización de variables de instancia
Permite inicializar las variables de instancia directamente en la lista de parámetros de los constructores utilizando “this.”.

 

Notación abreviada
El cuerpo de los constructores vacíos se puede omitir. De igual forma, las funciones se pueden escribir de forma abreviada utilizando la notación “=>”. Esto reduce la cantidad de código a escribir y mantener.

 

Parámetros opcionales

Soporta parámetros opcionales, declarados mediante una notación con corchetes, y con un valor por defecto si se quiere. En las invocaciones se pueden referenciar por su nombre e incluso reordenar.

 

Interpolación de String

Aunque las cadenas de texto son constantes y no se pueden modificar en tiempo de ejecución, en el momento de su declaración se evalúa su contenido y se puede incluir en ellas referencias a variables e incluso bloques de código completo mediante el uso del carácter dolar y llaves.

 

Operador parte entera de la división

Tiene un operador “~/” que devuelve la parte entera de una división. Es un complemento al clásico operador módulo “%” que devuelve el resto de una división.

 

Enteros de tamaño arbitrario

Dart declara una interface num con dos clases que la implementan: double e int. El tipo double tiene un tamaño predefinido de 64 bits y se rige por el estándar IEEE 754. El tipo int no tiene ningún tamaño predefinido, sólo está restringido por la implementación y la memoria disponible en la máquina. Esto último es cuanto menos bastante curioso, y quiere decir que se le puede sumar 1 a un número entero de forma casi infinita, sin que se produzca overflow.

 

Relación con JavaScript
Dart se está presentando como la alternativa a JavaScript en lo referente a la programación de aplicaciones web de gran tamaño. Su objetivo no es sólo permitir desarrollar aplicaciones para su ejecución en los clientes desde un navegador, sino también en los servidores de forma independiente.

Dart trata de resolver los problemas que plantea JavaScript, como el uso de this por ejemplo. Y además de lo que es el lenguaje de programación en si mismo, también proporciona una serie de librerías completas, como hizo Java en su tiempo. Desde colecciones como arrays, listas, mapas y conjuntos, hasta soporte para realizar operaciones de entrada/salida con ficheros, uso de sockets, etc…

 

Ejecución
Actualmente las aplicaciones escritas en Dart se pueden ejecutar:
– Desde una línea de comandos invocando directamente la máquina virtual
– Mediante Dartium, un build específico de Chrome que incorpora la máquina virtual
– Generando una versión para JavaScript a partir del código original escrito en Dart

 

Errores
Dart es un lenguaje que está en desarrollo, lo que hay disponible actualmente es una versión alpha basada en una especificación que aún dista mucho de estar cerrada.

El entorno de desarrollo es prácticamente un editor, basado en Eclipse, que apenas permite realizar las operaciones más básicas con los proyectos. Un ejemplo de esto es que ni siquiera se le puede cambiar el nombre a un fichero, ni borrarlo para crear uno nuevo con el nombre corregido. Pero lo peor sin duda es que aún no se puede depurar. Lógicamente están trabajando para añadir todas estas características.

Durante mis pruebas he encontrado varios errores. He abierto las incidencias correspondientes en dartbug.com y todas las han aceptado como errores, e incluso alguno ya está corregido en el último build nocturno. Aunque creo que hay alguno que les va a llevar un poco más tiempo.

He encontrado un error que hace el código se comporte de forma distinta en función de como se escriba. ¡Me ha traído literalmente de cabeza!. Al final he decidido no continuar la migración que estaba haciendo a Dart de LZMA. El algoritmo que está implementado funciona bien cuando se genera código en JavaScript, pero nunca va a poder funcionar bien en Dart con la especificación actual del lenguaje. El motivo es que LZMA basa su funcionamiento en operaciones a nivel de bit con una aritmética de tamaño entero (32 ó 64 bits) y precisamente en Dart los enteros no tienen tamaño predefinido. Estoy por borrar el proyecto.

Nuevo proyecto: dart-lzma

DartHoy he liberado los fuentes de dart-lzma, una versión para Dart del algoritmo de compresión LZMA. Es un nuevo proyecto que he empezado para ver en que estado está el lenguaje y las posibilidades que ofrece. Y la verdad es que me he encontrado que está todo en general en estado absolutamente alpha, aunque ya es posible editar, compilar y ejecutar programas.

El uso de la librería es muy sencillo, basta con importarla y llamar a la función de descompresión:

Aunque Dart viene con librerías que incluyen varios tipos de streams, he decidido aislar un poco mi librería de los posibles cambios en la implementación y definir dos interfaces propias muy sencillas:

Llama la atención que en una interface haya definido un método get, pero parece que el lenguaje lo soporta.

He puesto un ejemplo completo en la página del proyecto, pero al final todo se reduce a instanciar dos objetos y llamar a una función:

La función de compresión está en desarrollo. He retrasado su desarrollo porque me ha desanimado bastante que el programa no funcione con la máquina virtual de Dart utilizando la línea de comandos. Eleva una excepción ".\vm\object.cc:7453: error: unimplemented code" por que hay código de la máquina virtual que aún no está desarrollado. La única forma de hacer las pruebas es realizando una compilación cruzada del código en Dart a JavaScript para poder llamarlo desde una página web en vez de ejecutarlo de forma nativa.

El entorno y el lenguaje tienen cosas curiosas, a ver si me animo a escribir un post con las cuatro cosas que he ido viendo.

Dart

DartDart es el nombre de un nuevo lenguaje de programación creado por Google que se plantea como una alternativa de futuro a JavaScript. Siempre he pensado que el atributo “type” de la etiqueta “script” estaba para algo más que tomar un valor por defecto, y parece que al fin alguien se lo ha tomado en serio.

¿Pero realmente necesitamos un nuevo lenguaje de programación? Pues como siempre la respuesta depende de como le duela a cada uno. Para validar formularios, realizar efectos o hacer alguna que otra librería independiente tenemos más que suficiente con JavaScript. Pero para desarrollos que impliquen una mayor complejidad, y sobre bastante miles de líneas de código, entonces estamos necesitando claramente otro lenguaje. En particular con las características deseables de un lenguaje orientado a objetos, en vez de estar siempre tratando de emular estas características en JavaScript. Y todo esto naturalmente partiendo de la base de que a futuro sigamos queriendo ejecutar (mucho) código en el cliente.

Cuestiones filosóficas aparte, siendo muy simplista, la idea es que Dart recupera para la web las palabras reservadas interface y class, con sus constructores, métodos y variables de instancia. Pero eso es sólo una pequeña parte, claro. También proporciona un punto de entrada a las aplicaciones a través de una clásica función main, la posibilidad de importar librerías con #import, incluir código con source, y colecciones que pueden tiparse como los templates de C++ o los generics de Java. Suena todo bastante familiar, ¿no?

Dart es un lenguaje orientado a objetos basado en clases que soporta herencia simple, no múltiple, y que encapsula el código de forma modular en unidades a las que llama librerías. Proporciona mecanismos para declarar elementos públicos y privados, aunque curiosamente distinguidos por la nomenclatura de su nombre, no por un atributo modificador. Si empieza por “_” entonces es privado. Además soporta la concurrencia mediante un mecanismo propio de ejecución aislada (isolation) con intercambio de mensajes, sin memoria compartida. Y permite realizar una programación mixta en cuanto a comprobación de tipos se refiere. Pudiendo realizarse una versión inicial débilmente tipada e ir haciéndola más fuerte a medida que avanza el desarrollo. Pueden consultarse todos los detalles en el borrador actual que contiene las especificaciones del lenguaje.

Para probar Dart a día de hoy hay dos formas:

1) Utilizar el Dartboard, una pequeña aplicación web con un cuadro de texto donde se puede introducir código, compilarlo y ejecutarlo. Evidentemente el código se compila y ejecuta en un servidor remoto.

2) Utilizar el Dart Editor, una aplicación de escritorio basada en Eclipse que incorpora todas las características propias de este conocido entorno de desarrollo. En este caso el código se compila a JavaScript y se puede ejecutar desde una página HTML ordinaria directamente desde el navegador. Esta opción es similar a GWT, que acepta código en Java y genera JavaScript.

Por su parte, a futuro Dart se podrá ejecutar de dos formas:

1) Mediante un nuevo tipo MIME “application/dart” que se ejecutará de forma nativa en el navegador, de forma similar a como actualmente se ejecuta el código “application/javascript”.

2) Mediante una máquina virtual en un PC local. Algo que en realidad ya puede hacerse hoy en día gracias a las herramientas de líneas de comandos ya disponibles.

Naturalmente hoy en día un lenguaje no es nada si no viene acompañado de unas buenas librerías, máxime si su ejecución ha de realizarse en un navegador donde se dispone de APIs ya establecidos. Dart en ese aspecto apenas tiene dos librerías básicas, una core y otra dom. La librería de acceso a DOM está lo suficientemente desarrollada para manipular una página web de forma dinámica, permitiendo ya actualmente acceso a los objetos de tipo canvas por ejemplo.

He estado probando el Dart Editor y compilando los ejemplos. Iba a subir uno de ellos a la web, pero finalmente he desistido porque la versión actual genera como resultado de la compilación ficheros JavaScript de varios megas, y no merece la pena.

¿Sobrevivirá este lenguaje y se popularizará? Pues no tengo ni idea. A priori resulta difícil aceptar que el resto de navegadores vaya a adoptar una especificación muy concreta de Google, y mucho menos hacer un desarrollo propio para soportarlo, pero peores cosas se han visto. La gran ventaja con la que cuenta Google en este sentido es que Dart es un proyecto de código abierto. En cualquier caso no es el primer intento por parte de Google de crear un nuevo lenguaje de programación, ahí está Go por ejemplo, cuya primera versión definitiva está prevista que aparezca el año que viene. El tiempo dirá.