Informe de estado de oto帽o de Haxe

El 26 de octubre, Linz am Rhein (Alemania) organiz贸 la mini conferencia HaxeUp Sessions 2019 dedicada a Haxe y tecnolog铆as relacionadas. Y su evento m谩s significativo fue, por supuesto, el lanzamiento final de Haxe 4.0.0 (en el momento de la publicaci贸n, es decir, despu茅s de aproximadamente una semana, se lanz贸 la actualizaci贸n 4.0.1 ). En este art铆culo, me gustar铆a presentarle una traducci贸n del primer informe de la conferencia: un informe sobre el trabajo realizado por el equipo de Haxe para 2019.


imagen


Un poco sobre el autor del informe:


Simon ha estado trabajando con Haxe desde 2010, cuando todav铆a era estudiante y escribi贸 un trabajo sobre simulaciones fluidas en Flash. La implementaci贸n de tal simulaci贸n requiri贸 acceso constante a los datos que describen el estado de las part铆culas (en cada paso se realizaron m谩s de 100 consultas a conjuntos de datos sobre el estado de cada celda en la simulaci贸n), mientras que trabajar con conjuntos en ActionScript 3 no es tan r谩pido. Por lo tanto, la implementaci贸n inicial fue simplemente inoperante y necesaria para encontrar una soluci贸n a este problema. En su b煤squeda, Simon se encontr贸 con un art铆culo de Nicolas Kannass (creador de Haxe) sobre los c贸digos de operaci贸n de Alchemy que no estaban documentados y que no estaban disponibles con ActionScript, pero Haxe permiti贸 que se usaran. 隆Reescribiendo la simulaci贸n en Haxe usando c贸digos de operaci贸n, Simon obtuvo una simulaci贸n que funciona! Y as铆, gracias a las matrices lentas en ActionScript, Simon aprendi贸 sobre Haxe.


Desde 2011, Simon se uni贸 al desarrollo de Haxe, comenz贸 a estudiar OCaml (en el que est谩 escrito el compilador) y a hacer varias correcciones al compilador.


Y desde 2012, se convirti贸 en el principal desarrollador de compiladores. En el mismo a帽o, se cre贸 la Fundaci贸n Haxe (una organizaci贸n cuyos objetivos principales son desarrollar y mantener el ecosistema Haxe, ayudar a la comunidad a organizar conferencias y servicios de consultor铆a), y Simon se convirti贸 en uno de sus cofundadores.


imagen


En 2014-2015, Simon invit贸 a Josephine Pertosa a la Fundaci贸n Haxe, que con el tiempo se hizo responsable de organizar conferencias y relaciones con la comunidad.


En 2016, Simon hizo su primera presentaci贸n sobre Haxe , y en 2018 organiz贸 las primeras Sesiones HaxeUp .


imagen


Entonces, 驴qu茅 pas贸 en el mundo de Haxe durante el pasado 2019?


En febrero y marzo, salieron 2 candidatos de lanzamiento (4.0.0-rc1 y 4.0.0-rc2)
En abril, Aurel Bili (como pasante) y Alexander Kuzmenko (como desarrollador del compilador) se unieron al equipo de la Fundaci贸n Haxe.


En mayo, se celebr贸 la Haxe US Summit 2019 .
En junio, se lanz贸 Haxe 4.0.0-rc3. Y en septiembre: Haxe 4.0.0-rc4 y Haxe 4.0.0-rc5.


imagen


Haxe no solo es un compilador, sino tambi茅n un conjunto completo de varias herramientas, y durante todo el a帽o tambi茅n se trabaj贸 constantemente en ellas:
Gracias a los esfuerzos de Andy Lee, Haxe ahora usa Azure Pipelines en lugar de Travis CI y AppVeyor. Esto significa que el ensamblaje y las pruebas automatizadas ahora son mucho m谩s r谩pidas.
Hugh Sanderson contin煤a trabajando en hxcpp (una biblioteca para soportar C ++ en Haxe).
De repente, los usuarios de Github terurou y takashiski se unieron al trabajo en exteriores para Node.js.
Rudy Ges trabaj贸 en soluciones y mejoras para soportar el objetivo de C #.
George Corney contin煤a apoyando el generador externo HTML.
Jens Fisher est谩 trabajando en vshaxe (una extensi贸n para VS Code para trabajar con Haxe) y en muchos otros proyectos relacionados con Haxe.


imagen


Y el evento principal del a帽o, por supuesto, fue el esperado lanzamiento de Haxe 4.0.0 (as铆 como neko 2.3.0), que coincidi贸 accidentalmente con el HaxeUp 2019 Linz :)


imagen


Simon dedic贸 la mayor parte del informe a las nuevas caracter铆sticas en Haxe 4.0.0 (tambi茅n puede aprender sobre ellas a partir del informe de Alexander Kuzmenko de la 煤ltima Cumbre de Estados Unidos Haxe 2019).


imagen


El nuevo int茅rprete de macros eval es varias veces m谩s r谩pido que el anterior. Simon habl贸 de 茅l en detalle en su discurso en la Haxe Summit EU 2017 . Pero desde entonces ha mejorado las capacidades de depuraci贸n del c贸digo, corrigi贸 muchos errores, redise帽贸 la implementaci贸n de cadenas.


imagen


Haxe 4 presenta soporte Unicode para todas las plataformas (excepto Neko). Simon describi贸 esto en detalle en su discurso del a帽o pasado . Para el usuario final del compilador, esto significa que la expresi贸n "Haxe銇渶楂樸仩銇烇紒".length para todas las plataformas siempre devolver谩 10 (de nuevo, excepto Neko).


La codificaci贸n UCS-2 es m铆nimamente compatible (se utiliza una codificaci贸n nativa para cada plataforma / idioma; ser铆a poco pr谩ctico tratar de admitir la misma codificaci贸n en todas partes):


  • JavaScript, Flash, HashLink y C ++ usan codificaci贸n UCS-2
  • para eval, PHP, lua - UTF-8
  • para Java y C # - UTF-16
  • para Python - UTF-32

Todos los caracteres que est谩n fuera del plano multiling眉e principal (incluidos los emoji) se representan como "pares sustitutos"; dichos caracteres se representan con dos bytes. Por ejemplo, si en Java / C # / JavaScript (es decir, para cadenas en codificaciones UTF-16 y UCS-2) solicita la longitud de una cadena que consta de un emoji, el resultado ser谩 "2". Este hecho debe tenerse en cuenta al trabajar con tales cadenas en estas plataformas.


Haxe 4 presenta un nuevo tipo de iterador: clave-valor:


imagen


Funciona con contenedores de tipo Map (diccionarios) y cadenas (usando la clase StringTools), el soporte para matrices a煤n no se ha implementado. Tambi茅n es posible implementar dicho iterador para clases personalizadas, para esto es suficiente implementar el m茅todo keyValueIterator():KeyValueIterator<K, V> para ellos keyValueIterator():KeyValueIterator<K, V> .


La nueva metaetiqueta @:using permite asociar extensiones est谩ticas con tipos en el lugar de su declaraci贸n.


En el ejemplo que se muestra en la diapositiva siguiente, la enumeraci贸n MyOption asociada con MyOptionTools , por lo que expandimos est谩ticamente esta enumeraci贸n (que es imposible en la situaci贸n habitual) y tenemos la oportunidad de llamar al m茅todo get() , refiri茅ndolo como un m茅todo de objeto.


imagen


En este ejemplo, el m茅todo get() est谩 en l铆nea, lo que tambi茅n permite que el compilador optimice a煤n m谩s el c贸digo: en lugar de llamar al MyOptionTools.get(myOption) , el compilador sustituir谩 el valor almacenado, es decir, 12 .


Si el m茅todo no se declara como incrustable, entonces otra herramienta de optimizaci贸n disponible para el programador es incrustar las funciones en el lugar de su llamada (l铆nea del sitio de la llamada). Para hacer esto, al llamar a la funci贸n, debe usar adicionalmente la inline :


imagen


Gracias al trabajo de Daniil Korostelev , Haxe ahora tiene la oportunidad de generar clases de ES6 para JavaScript. Todo lo que necesita hacer es agregar el indicador de compilaci贸n -D js-es=6 .


Actualmente, el compilador genera un archivo js para todo el proyecto (puede ser posible en el futuro generar archivos js separados para cada una de las clases, pero hasta ahora esto solo se puede hacer usando herramientas adicionales ).


imagen


Para enumeraciones abstractas, los valores ahora se generan autom谩ticamente.


En Haxe 3, era necesario establecer valores manualmente para cada constructor. En Haxe 4, las enumeraciones abstractas creadas encima de Int comportan de acuerdo con las mismas reglas que en C. Las enumeraciones abstractas creadas encima de las cadenas se comportan de manera similar; para ellos, los valores generados coincidir谩n con los nombres de los constructores.


imagen


Tambi茅n vale la pena mencionar algunas mejoras de sintaxis:


  • Las enumeraciones abstractas y las funciones externas se han convertido en miembros completos de Haxe y ahora no necesita usar las metaetiquetas @:enum y @:extern para declararlas.
  • 4th Haxe utiliza un nuevo tipo de sintaxis de intersecci贸n que refleja mejor la esencia de las estructuras en expansi贸n. Dichas construcciones son m谩s 煤tiles cuando se declaran estructuras de datos: la expresi贸n typedef T = A & B significa que la estructura T tiene todos los campos que est谩n en los tipos A y B
  • de manera similar, las cuatro restricciones del par谩metro de tipo de declaraci贸n: la entrada <T:A & B> indica que el tipo de par谩metro T debe ser tanto A como B
  • la sintaxis anterior funcionar谩 (excepto la sintaxis para restricciones de tipo, porque entrar谩 en conflicto con la nueva sintaxis para describir los tipos de funci贸n)

imagen


La nueva sintaxis para describir los tipos de funci贸n (sintaxis de tipo de funci贸n) es m谩s l贸gica: usar par茅ntesis alrededor de los tipos de argumentos de funci贸n es visualmente m谩s f谩cil de leer. Adem谩s, la nueva sintaxis le permite definir nombres de argumentos, que se pueden usar como parte de la documentaci贸n del c贸digo (aunque no afecta la escritura en s铆).


imagen


En este caso, la sintaxis anterior sigue siendo compatible y no est谩 en desuso, ya que de lo contrario, requerir铆a demasiados cambios en el c贸digo existente (Simon mismo constantemente se encuentra fuera de h谩bito y contin煤a usando la sintaxis anterior).


隆Haxe 4 finalmente tiene funciones de flecha (o expresiones lambda)!


imagen


Las caracter铆sticas de las funciones de flecha en Haxe son:


  • return impl铆cito Si el cuerpo de la funci贸n consta de una expresi贸n, esta funci贸n devuelve impl铆citamente el valor de esta expresi贸n
  • Es posible establecer los tipos de argumentos de funci贸n, porque el compilador no siempre puede determinar el tipo requerido (por ejemplo, Float o Int )
  • si el cuerpo de la funci贸n consta de varias expresiones, entonces necesita rodearlo con llaves
  • pero no hay forma de establecer expl铆citamente el tipo de retorno de la funci贸n

En general, la sintaxis de las funciones de flecha es muy similar a la utilizada en Java 8 (aunque funciona de manera algo diferente).


Y como mencionamos Java, deber铆a decirse que en Haxe 4 se hizo posible generar bytecode JVM directamente. Para hacer esto, al compilar un proyecto en Java, simplemente agregue el indicador -D jvm .


Generar un c贸digo de bytes JVM significa que no hay necesidad de usar un compilador Java, y el proceso de compilaci贸n es mucho m谩s r谩pido.


imagen


Hasta ahora, el objetivo JVM tiene un estado experimental por las siguientes razones:


  • en algunos casos, el c贸digo de bytes es un poco m谩s lento que el resultado de traducir Haxe en Java y luego compilarlo con javac. Pero el equipo compilador es consciente del problema y sabe c贸mo solucionarlo, solo requiere trabajo adicional.
  • Hay problemas con MethodHandle en Android, que tambi茅n requiere trabajo adicional (Simon se alegrar谩 si se le ayuda a resolver estos problemas).

imagen


Una comparaci贸n general de generar bytecode directamente (genjvm) y compilar Haxe en c贸digo Java, que luego se compila en bytecode (genjava):


  • como ya se mencion贸, en t茅rminos de velocidad de compilaci贸n, genjvm es m谩s r谩pido que genjava
    en t茅rminos de velocidad de ejecuci贸n, bytecode genjvm sigue siendo inferior a genjava
  • hay algunos problemas al usar par谩metros de tipo y genjava
  • genJvm usa MethodHandle para referirse a funciones, y genjava usa las llamadas "funciones Waneck" (en honor a Kaui Vanek , gracias a las cuales Java y C # aparecieron en Haxe). Aunque el c贸digo obtenido usando las funciones Waneck no se ve hermoso, funciona y funciona lo suficientemente r谩pido.

Consejos generales para trabajar con Java en Haxe:


  • Debido al hecho de que el recolector de basura en Java es r谩pido, los problemas asociados con 茅l son raros. Por supuesto, crear objetos nuevos constantemente no es una buena idea, pero Java hace un buen trabajo al administrar la memoria y la necesidad de ocuparse constantemente de las asignaciones no es tan grave como en algunas otras plataformas compatibles con Haxe (por ejemplo, en HashLink)
  • Acceder a los campos de una clase en un destino jvm puede funcionar muy lentamente en el caso cuando esto se hace a trav茅s de una estructura ( typedef ), mientras que el compilador no puede optimizar dicho c贸digo
  • Se debe evitar el uso excesivo de la palabra clave en inline : el compilador JIT hace un trabajo bastante bueno
  • Evite usar Null<T> , especialmente cuando se trata de c谩lculos matem谩ticos complejos. De lo contrario, aparecer谩n muchas declaraciones condicionales en el c贸digo generado, lo que afectar谩 negativamente la velocidad de su c贸digo.

La nueva funci贸n Haxe 4, Seguridad nula, puede ayudar a evitar el uso de Null<T> . Alexander Kuzmenko habl贸 en detalle sobre ella en el HaxeUp del a帽o pasado .


imagen


En el ejemplo de la diapositiva anterior, el m茅todo static safe() tiene habilitado el modo Estricto para verificar la seguridad nula, y este m茅todo tiene un par谩metro arg opcional, que puede tener un valor nulo. Para que esta funci贸n se compile con 茅xito, el programador deber谩 agregar una verificaci贸n del valor del argumento arg (de lo contrario, el compilador mostrar谩 un mensaje sobre la imposibilidad de llamar al m茅todo charAt() en un objeto potencialmente nulo).


imagen


La seguridad nula se puede configurar tanto a nivel de paquete (usando una macro) como a tipos y campos individuales de objetos (usando la metaetiqueta @:nullSafety ).


Los modos en que funcionan las comprobaciones de seguridad nula son: estricto, suelto y desactivado. Globalmente, estas comprobaciones est谩n deshabilitadas (modo desactivado). Cuando est谩n activados, el modo Loose se usa de manera predeterminada (a menos que especifique expl铆citamente el modo). La diferencia clave entre los modos Loose y Strict es que el modo Loose ignora la posibilidad de cambiar los valores entre operaciones para acceder a estos valores. En el ejemplo de la diapositiva a continuaci贸n, vemos que se ha agregado una verificaci贸n null para la variable x . Sin embargo, en modo estricto, este c贸digo no se compila, porque antes de trabajar directamente con la variable x , se sideEffect() m茅todo sideEffect() , que potencialmente puede anular el valor de esta variable, por lo que deber谩 agregar otra verificaci贸n o copiar el valor de la variable a una variable local, con la que continuaremos trabajando.


imagen


Haxe 4 presenta una nueva palabra clave final , que tiene un significado diferente seg煤n el contexto:


  • si lo usa en lugar de la palabra clave var , al campo declarado de esta manera no se le puede asignar un nuevo valor. Solo puede configurarlo directamente al declarar (para campos est谩ticos) o en el constructor (para campos no est谩ticos)
  • si lo usa al declarar una clase, prohibir谩 la herencia de ella
  • si lo usa como modificador para acceder a la propiedad de un objeto, esto proh铆be la redefinici贸n de getter / setter en las clases herederas.

imagen


Te贸ricamente, el compilador, despu茅s de cumplir con la palabra clave final , puede intentar optimizar el c贸digo, suponiendo que el valor de este campo no cambia. Pero por ahora, esta posibilidad solo se est谩 considerando y no se implementa en el compilador.


imagen


Y un poco sobre el futuro de Haxe:


  • actualmente trabajando en API de E / S as铆ncrona
    El apoyo de rutina est谩 planeado, pero hasta ahora, el trabajo en ellos est谩 estancado en la etapa de planificaci贸n. Quiz谩s aparezcan en Haxe 4.1, y quiz谩s m谩s tarde.
  • la optimizaci贸n de la cola aparecer谩 en el compilador
  • y posiblemente las funciones disponibles a nivel de m贸dulo . Aunque la prioridad de esta funci贸n cambia constantemente

Source: https://habr.com/ru/post/474452/


All Articles