Lenguaje de programación Julia 1.9 disponible

Se ha publicado el lanzamiento del lenguaje de programación Julia 1.9, que combina cualidades como alto rendimiento, soporte para escritura dinámica y herramientas integradas para programación paralela. La sintaxis de Julia es cercana a MATLAB y toma prestados algunos elementos de Ruby y Lisp. El método de manipulación de cadenas recuerda a Perl. El código del proyecto se distribuye bajo la licencia MIT.

Características clave del idioma:

  • Alto rendimiento: uno de los objetivos clave del proyecto es lograr un rendimiento cercano al de los programas C. El compilador Julia se basa en el trabajo del proyecto LLVM y genera código de máquina nativo eficiente para muchas plataformas de destino;
  • Admite varios paradigmas de programación, incluidos elementos de programación funcional y orientada a objetos. La biblioteca estándar proporciona, entre otras cosas, funciones para E/S asíncrona, control de procesos, registro, creación de perfiles y gestión de paquetes;
  • Escritura dinámica: el lenguaje no requiere una definición explícita de tipos de variables, similar a los lenguajes de programación de scripts. Modo interactivo compatible;
  • Capacidad opcional para especificar tipos explícitamente;
  • Una sintaxis ideal para computación numérica, computación científica, aprendizaje automático y visualización de datos. Soporte para muchos tipos de datos numéricos y herramientas para paralelización de cálculos.
  • La capacidad de llamar directamente funciones desde bibliotecas C sin capas adicionales.

Cambios importantes en Julia 1.9:

  • Nuevas funciones de idioma
    • Permitir que se realicen asignaciones en otro módulo usando "setproperty!(::Module, ::Symbol, x)".
    • Se permiten asignaciones múltiples que no estén en la posición final. Por ejemplo, la cadena “a, b…, c = 1, 2, 3, 4” se procesará como “a = 1; segundo…, = 2, 3; c = 4". Esto se maneja a través de Base.split_rest.
    • Los literales de un solo carácter ahora admiten la misma sintaxis que los literales de cadena; aquellos. La sintaxis puede representar secuencias UTF-8 no válidas, según lo permite el tipo Char.
    • Se agregó soporte para la especificación Unicode 15.
    • Ahora se pueden utilizar combinaciones anidadas de tuplas y tuplas de caracteres con nombre como parámetros de tipo.
    • Nuevas funciones integradas "getglobal(::Module, ::Symbol[, order])" y "setglobal!(::Module, ::Symbol, x[, order])" para leer y escribir exclusivamente en variables globales. Ahora debería preferirse el método getglobal al método getfield para acceder a variables globales.
  • Cambios en el idioma
    • La macro "@invoke" introducida en la versión 1.7 ahora está exportada y disponible para su uso. Además, ahora utiliza el método "Core.Typeof(x)" en lugar de "Any" en el caso en que se omite la anotación de tipo para el argumento "x". Esto es necesario para garantizar que los tipos pasados ​​como argumentos se procesen correctamente.
    • Se habilitó la exportación de la función “invokelatest” y la macro “@invokelatest”, introducida en la versión 1.7.
  • Mejoras en el compilador/tiempo de ejecución
    • Tiempo significativamente reducido hasta la primera ejecución (TTFX - Tiempo hasta la primera ejecución). La precompilación de un paquete ahora almacena el código nativo en "pkgimage", lo que significa que no será necesario volver a compilar el código generado por el proceso de precompilación después de cargar el paquete. El uso del modo pkgimages se puede desactivar usando la opción "--pkgimages=no".
    • Se ha solucionado el conocido problema de complejidad cuadrática de la inferencia de tipos y la inferencia utiliza menos memoria en general. Algunos casos extremos con funciones largas generadas automáticamente (como ModelingToolkit.jl con ecuaciones diferenciales parciales y modelos causales grandes) se compilan mucho más rápido.
    • Las llamadas con argumentos sin tipos concretos ahora se pueden optimizar mediante división de unión para inyección o resolución estática, incluso si hay varios candidatos de diferentes tipos para su envío. Esto puede mejorar el rendimiento en determinadas situaciones en las que los tipos de objetos no se resuelven completamente de forma estática, resolviendo estáticamente los sitios de llamadas "@nospecialize-d" y evitando la recompilación.
    • Todos los usos de la macro @pure en el módulo Base han sido reemplazados por Base.@assume_effects.
    • Las llamadas a invoke(f, invokesig, args...) con tipos menos específicos que los utilizados normalmente para f(args...) ya no hacen que el paquete se vuelva a compilar.
  • Cambios en las opciones de la línea de comando
    • En Linux y Windows, la opción "--threads=auto" ahora intenta determinar la cantidad de procesadores disponibles en función de la afinidad de la CPU, una máscara que generalmente se establece en entornos HPC y de nube.
    • El parámetro “--math-mode=fast” está deshabilitado, en lugar del cual se recomienda utilizar la macro “@fastmath”, que tiene una semántica claramente definida.
    • La opción "--threads" ahora tiene el formato "auto | N[,auto|M]", donde M indica el número de hilos interactivos a crear (actualmente auto significa 1).
    • Opción agregada “—heap-size-hint=" ", que establece el umbral después del cual comienza la recolección activa de basura. El tamaño se puede especificar en bytes, kilobytes (1000 KB), megabytes (300 MB) o gigabytes (1,5 GB).
  • Cambios en subprocesos múltiples
    • "Threads.@spawn" ahora tiene un primer argumento opcional con el valor ":default" o ":interactive". Una tarea interactiva requiere una latencia de respuesta baja y está diseñada para ser breve o realizarse con frecuencia. Las tareas interactivas se ejecutarán en subprocesos interactivos si se especifican al iniciar Julia.
    • Los subprocesos que se ejecutan fuera del tiempo de ejecución de Julia (como desde C o Java) ahora pueden llamar al código de Julia usando "jl_adopt_thread". Esto sucede automáticamente al ingresar el código Julia a través de "cfunction" o el punto de entrada "@ccallable". Como consecuencia, el número de subprocesos ahora puede cambiar durante la ejecución.
  • Nuevas funciones de biblioteca
    • Nueva función "Iterators.flatmap".
    • Nueva función "pkgversion(m::Module)" para obtener la versión del paquete que cargó un módulo determinado, similar a "pkgdir(m::Module)".
    • Nueva función "stack(x)" que generaliza "reduce(hcat, x::Vector{<:Vector})" a cualquier dimensión y permite cualquier iterador de iteradores. El método "stack(f, x)" generaliza "mapreduce(f, hcat, x)" y es más eficiente.
    • Nueva macro para analizar la memoria asignada "@allocations", similar a "@allocated", excepto que devuelve el número de asignaciones de memoria, en lugar del tamaño total de la memoria asignada.
  • Nuevas funciones de la biblioteca
    • "RoundFromZero" ahora funciona para tipos distintos de "BigFloat".
    • "Dict" ahora se puede reducir manualmente usando "sizehint!"
    • "@time" ahora especifica por separado el porcentaje de tiempo dedicado a recompilar métodos no válidos.
  • Cambios en la biblioteca estándar.
    • Se solucionó un problema de concurrencia en los métodos de iteración para Dict y otros objetos derivados como claves(::Dict), valores(::Dict) y Set. Estos métodos de iteración ahora se pueden llamar en un Dict o Set en paralelo para un número ilimitado de subprocesos, siempre que no haya acciones que modifiquen el diccionario o el conjunto.
    • Negar una función de predicado "!f" ahora devuelve una función compuesta "(!) ∘ f" en lugar de una función anónima.
    • Las funciones de división de dimensiones ahora funcionan en múltiples dimensiones: "eachslice", "eachrow" y "eachcol" devuelven un objeto "Slices" que permite el envío para proporcionar métodos más eficientes.
    • Se agregó la macro "@kwdef" a la API pública.
    • Se solucionó un problema con el orden de las operaciones en "fld1".
    • La clasificación ahora es siempre estable en el tiempo (se ha rediseñado QuickSort).
    • "Base.splat" ahora está exportado. El valor de retorno es del tipo "Base.Splat" en lugar de una función anónima, lo que permite que se genere bien.
  • Gerente de empaquetación
    • "Extensiones de paquete": soporte para cargar un fragmento de código de otros paquetes cargados en una sesión de Julia. La aplicación es similar al paquete "Requires.jl", pero se admite la precompilación y la compatibilidad de configuración.
  • Biblioteca de álgebra lineal
    • Debido al riesgo de confusión con la división por elementos, se eliminaron los métodos "a/b" y "b\a" con el escalar "a" y el vector "b", que eran equivalentes a "a * pinv(b)".
    • Llamar a BLAS y LAPACK ahora utiliza "libblastrampoline (LBT)". OpenBLAS se proporciona de forma predeterminada, pero no se admite la creación de la imagen del sistema con otras bibliotecas BLAS/LAPACK. En su lugar, se recomienda utilizar el mecanismo LBT para reemplazar BLAS/LAPACK con otro conjunto de bibliotecas existente.
    • "lu" admite una nueva estrategia de rotación de matrices, "RowNonZero()", que selecciona el primer elemento de rotación distinto de cero para usarlo con nuevos tipos aritméticos y con fines de capacitación.
    • "normalize(x, p=2)" ahora admite cualquier espacio vectorial normalizado "x", incluidos los escalares.
    • La cantidad predeterminada de subprocesos BLAS ahora es igual a la cantidad de subprocesos de CPU en arquitecturas ARM y la mitad de la cantidad de subprocesos de CPU en otras arquitecturas.
  • Printf: mensajes de error reelaborados para cadenas con formato incorrecto para una mejor legibilidad.
  • Perfil: Nueva función "Profile.take_heap_snapshot(file)", que escribe un archivo en el formato ".heapsnapshot" basado en JSON compatible con Chrome.
  • Aleatorio: randn y randexp ahora funcionan para cualquier tipo de AbstractFloat que defina rand.
  • REEMPLAZAR
    • Al presionar la combinación de teclas "Alt-e" ahora se abre la entrada actual en el editor. El contenido (si se modifica) se ejecutará cuando salga del editor.
    • El contexto del módulo actual activo en REPL se puede cambiar (Principal por defecto) usando la función "REPL.activate(::Module)" o ingresando el módulo en REPL y presionando la combinación de teclas "Alt-m".
    • El modo "solicitud numerada", que imprime números para cada entrada y salida y almacena los resultados puntuados en Salida, se puede activar usando "REPL.numbered_prompt!()".
    • La finalización con tabulación muestra los argumentos de palabras clave disponibles.
  • SuiteSparse: se movió el código del solucionador "SuiteSparse" a "SparseArrays.jl". Los solucionadores ahora se reexportan mediante "SuiteSparse.jl".
  • Arreglos dispersos
    • Los solucionadores "SuiteSparse" ahora están disponibles como submódulos "SparseArrays".
    • Los modos de protección de subprocesos UMFPACK y CHOLMOD se han mejorado eliminando variables globales y utilizando bloqueos. "ldiv!" de subprocesos múltiples Los objetos UMFPACK ahora se pueden ejecutar de forma segura.
    • La función experimental "SparseArrays.allowscalar(::Bool)" le permite deshabilitar o habilitar la indexación escalar de matrices dispersas. Esta función está diseñada para detectar indexación escalar aleatoria de objetos "SparseMatrixCSC", que es una fuente común de problemas de rendimiento.
  • Nuevo modo a prueba de fallos para conjuntos de pruebas que finaliza una ejecución de prueba antes de tiempo en caso de falla o error. Establezca a través de “@testset kwarg failfast=true” o “export JULIA_TEST_FAILFAST=true”. A veces, esto es necesario en las ejecuciones de CI para recibir mensajes de error con anticipación.
  • Fechas: las cadenas vacías ya no se analizan incorrectamente como valores válidos de "DateTime", "Dates" o "Times" y, en su lugar, arrojan un "ArgumentError" en los constructores y el análisis, mientras que "tryparse" no devuelve nada.
  • Paquete distribuido
    • La configuración del paquete (proyecto activo, "LOAD_PATH", "DEPOT_PATH") ahora se propaga al agregar procesos de trabajo locales (por ejemplo, usando "addprocs(N::Int)" o usando el indicador de línea de comando "--procs=N").
    • "addprocs" para procesos de trabajo locales ahora acepta un argumento llamado "env" para pasar variables de entorno a los procesos de trabajo.
  • Unicode: "grafemas(s, m:n)" devuelve la subcadena del enésimo al enésimo grafema en "s".
  • El paquete DelimitedFiles se eliminó de las bibliotecas del sistema y ahora se distribuye como un paquete separado que debe instalarse explícitamente para poder usarse.
  • Dependencias externas
    • En Linux, la versión de la biblioteca del sistema libstdc++ se detecta automáticamente y, si es más nueva, se carga. El antiguo comportamiento de carga integrado de libstdc++, independientemente de la versión del sistema, se puede restaurar configurando la variable de entorno "JULIA_PROBE_LIBSTDCXX=0".
    • Se eliminó "RPATH" del binario julia, que puede dañar las bibliotecas en Linux que no definen la variable "RUNPATH".
    • Mejoras en la herramienta: la salida de "MethodError" y los métodos (por ejemplo, de "methods(my_func)") ahora está formateada y coloreada de acuerdo con el principio de salida de métodos en un seguimiento de pila.

    Fuente: opennet.ru

Añadir un comentario