Lanzamiento del lenguaje de programación Julia 1.8

Está disponible el lanzamiento del lenguaje de programación Julia 1.8, 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.8:

  • Nuevas funciones de idioma
    • Los campos de una estructura mutable ahora se pueden anotar como constantes para evitar que se modifiquen y permitir la optimización.
    • Se pueden agregar anotaciones de tipo a las variables globales.
    • Se pueden crear matrices vacías de n dimensiones utilizando varios puntos y coma dentro de corchetes, por ejemplo, "[;;;]" crea una matriz 0x0x0.
    • Los bloques de prueba ahora pueden tener opcionalmente un bloque else, que se ejecuta inmediatamente después del cuerpo principal si no se arrojaron errores.
    • @inline y @noinline se pueden colocar dentro del cuerpo de una función, lo que le permite anotar una función anónima.
    • @inline y @noinline ahora se pueden aplicar a una función en un sitio o bloque de llamadas para forzar que se incluyan (o no se incluyan) las llamadas a funciones correspondientes.
    • ∀, ∃ y ∄ se permiten como caracteres identificadores.
    • Se agregó soporte para la especificación Unicode 14.0.0.
    • El método Module(:name, false, false) se puede utilizar para crear un módulo que no contenga nombres, no importe Base o Core y no contenga una referencia a sí mismo.
  • Cambios en el idioma
    • Los objetos de tarea recién creados (@spawn, @async, etc.) ahora tienen world_age para los métodos de la tarea principal cuando se crean, lo que permite una ejecución optimizada. La opción de activación anterior está disponible mediante el método Base.invokelatest.
    • Las directivas de formato bidireccional desequilibrado Unicode ahora están prohibidas en cadenas y comentarios para evitar inyecciones.
    • Base.ifelse ahora se define como una función genérica en lugar de una función incorporada, lo que permite que los paquetes amplíen su definición.
    • Cada asignación a una variable global ahora pasa primero por una llamada a convert(Any, x) o convert(T, x) si la variable global fue declarada como de tipo T. Antes de usar variables globales, asegúrese de que el invariante convert(Any , x) === x siempre es cierto; de lo contrario, puede provocar un comportamiento inesperado.
    • Las funciones integradas ahora son similares a las funciones genéricas y se pueden enumerar mediante programación mediante métodos.
  • Mejoras en el compilador/tiempo de ejecución
    • El tiempo de arranque se redujo en aproximadamente un 25 %.
    • El compilador basado en LLVM se ha separado de la biblioteca en tiempo de ejecución en una nueva biblioteca, libjulia-codegen. Se carga de forma predeterminada, por lo que no debería haber cambios durante el uso normal. En implementaciones que no necesitan un compilador (por ejemplo, imágenes del sistema en las que todo el código necesario está precompilado), esta biblioteca (y su dependencia LLVM) puede simplemente omitirse.
    • La inferencia de tipos condicionales ahora es posible pasando un argumento a un método. Por ejemplo, para Base.ifelse(isa(x, Int), x, 0) devuelve ::Int incluso si se desconoce el tipo de x.
    • Se ha mejorado SROA (Reemplazo escalar de agregados): elimina llamadas getfield con campos globales persistentes, elimina estructuras mutables con campos no inicializados, mejora el rendimiento y el manejo de llamadas getfield anidadas.
    • La inferencia de tipos rastrea varios efectos: efectos secundarios y no caída. Se tiene en cuenta la propagación constante, lo que mejora significativamente el rendimiento en tiempo de compilación. En algunos casos, por ejemplo, las llamadas a funciones que no se pueden insertar pero que no afectan el resultado se descartarán en tiempo de ejecución. Las reglas para los efectos se pueden sobrescribir manualmente usando la macro Base.@assume_effects.
    • La precompilación (con directivas de precompilación explícitas o cargas de trabajo específicas) ahora guarda más código de tipo definido, lo que resulta en una ejecución más rápida por primera vez. Cualquier nueva combinación de método/tipo que necesite su paquete, independientemente de dónde se definieron esos métodos, ahora se puede almacenar en caché en el archivo de precompilación si es llamada por un método que pertenece a su paquete.
  • Cambios en las opciones de la línea de comando
    • El comportamiento predeterminado para monitorear declaraciones @inbounds ahora es la opción automática en "--check-bounds=yes|no|auto".
    • Nueva opción "--strip-metadata" para eliminar cadenas de documentos, información de ubicación de origen y nombres de variables locales al crear una imagen del sistema.
    • Nueva opción "--strip-ir" para permitir que el compilador elimine la representación del código fuente intermedio al crear la imagen del sistema. La imagen resultante solo funcionará si se usa "--compile=all" o si todo el código requerido está precompilado.
    • Si se especifica el carácter "-" en lugar del nombre del archivo, entonces el código ejecutable se lee del flujo de entrada estándar.
  • Cambios en el soporte de subprocesos múltiples
    • Threads.@threads utiliza de forma predeterminada la nueva opción de programación: dinámica, que difiere del modo anterior en que las iteraciones se programarán dinámicamente entre los subprocesos de trabajo disponibles en lugar de asignarse a cada subproceso. Este modo permite una mejor distribución de bucles anidados con @spawn y @threads.
  • Nuevas funciones de biblioteca
    • eachsplit(str) para ejecutar split(str) varias veces.
    • allequal(itr) para comprobar si todos los elementos de un iterador son iguales.
    • hardlink(src, dst) se puede utilizar para crear enlaces físicos.
    • setcpuaffinity(cmd, cpus) para establecer la afinidad del núcleo del procesador con los procesos iniciados.
    • diskstat(path=pwd()) para obtener estadísticas del disco.
    • Nueva macro @showtime para mostrar tanto la línea que se está evaluando como el informe @time.
    • Se han agregado la macro LazyString y lazy"str" ​​​​para admitir la construcción diferida de mensajes de error en rutas de error.
    • Se solucionó un problema de concurrencia en Dict y otros objetos derivados como claves (::Dict), valores (::Dict) y Set. Ahora se pueden invocar métodos de iteración en un diccionario o conjunto, siempre que no haya llamadas que modifiquen el diccionario o conjunto.
    • @time y @timev ahora tienen una descripción opcional, lo que le permite anotar la fuente de los informes de tiempo, por ejemplo. @time "Evaluando foo" foo().
    • range toma parada o longitud como único argumento de palabra clave.
    • precision y setprecision ahora aceptan base como palabra clave
    • Los objetos de socket TCP ahora proporcionan un método de escritura cerrada y admiten el uso del modo medio abierto.
    • extrema ahora acepta un argumento init.
    • Iterators.countfrom ahora acepta cualquier tipo que defina un método +.
    • @time ahora asigna el porcentaje de tiempo dedicado a recompilar métodos con tipos modificados.
  • Cambios de biblioteca estándar
    • Las claves con valor Nothing ahora se eliminan del entorno en addenv.
    • Iterators.reverse (y por lo tanto último) admite cada línea.
    • La función de longitud para rangos de ciertos tipos ya no verifica el desbordamiento de enteros. Está disponible una nueva función, longitud_comprobada, que contiene lógica de control de transferencia de bits. Si es necesario, utilice SaferIntegers.jl para construir el tipo de rango.
    • El iterador Iterators.Reverse implementa cada inversión de índice si es posible.
  • Gerente de empaquetación
    • Nuevos indicadores ⌃ y ⌅ junto a los paquetes en el estado “pkg>” para los cuales hay nuevas versiones disponibles. ⌅ indica que no se pueden instalar nuevas versiones.
    • Nuevo argumento obsoleto::Bool para Pkg.status (--outdated o -o en modo REPL) para mostrar información sobre paquetes de versiones anteriores.
    • Nuevo argumento compat::Bool para Pkg.status (--compat o -c en modo REPL) para mostrar cualquier entrada [compat] en Project.toml.
    • Nuevo modo "pkg>compat" (y Pkg.compat) para configurar entradas de compatibilidad de proyectos. Proporciona un editor interactivo a través de "pkg>compat" o control directo de registros a través de "pkg>Foo 0.4,0.5", que puede cargar registros actuales completando tabulaciones. Es decir, "paquete> compat Fo " se actualiza automáticamente a "pkg>Foo 0.4,0.5" para permitir la edición de una entrada existente.
    • Pkg ahora solo intenta descargar paquetes desde un servidor de paquetes si el servidor está monitoreando el registro que contiene el paquete.
    • Pkg.instantiate ahora emitirá una advertencia cuando Project.toml no esté sincronizado con Manifest.toml. Lo hace basándose en un hash de los registros de compatibilidad y departamentos del proyecto (otros campos se ignoran) en el manifiesto al resolverlo, de modo que cualquier cambio en los registros de compatibilidad o departamentos de Project.toml se pueda detectar sin volver a resolver.
    • Si "pkg>add" no puede encontrar un paquete con el nombre dado, ahora sugerirá paquetes con nombres similares que se pueden agregar.
    • La versión de julia almacenada en el manifiesto ya no incluye el número de compilación, lo que significa que master ahora se escribirá como 1.9.0-DEV.
    • La cancelación de prueba "pkg>" ahora se detectará de manera más consistente y se devolverá correctamente al REPL.
  • Utilidades interactivas
    • Nueva macro @time_imports para informar el tiempo dedicado a importar paquetes y sus dependencias, destacando el tiempo de compilación y recompilación como porcentaje de las importaciones.
  • Álgebra lineal
    • El submódulo BLAS ahora admite funciones BLAS spr! de nivel 2.
    • La biblioteca estándar LinearAlgebra.jl ahora es completamente independiente de SparseArrays.jl, tanto desde la perspectiva del código fuente como de las pruebas unitarias. Como consecuencia, los métodos de LinearAlgebra aplicados a objetos Base o LinearAlgebra ya no devuelven (implícitamente) matrices dispersas. En particular, esto conduce a los siguientes cambios importantes:
      • Las concatenaciones que utilizan matrices especiales "escasas" (por ejemplo, diagonales) ahora devuelven matrices densas; Como consecuencia, los campos D1 y D2 de los objetos SVD creados por llamadas getproperty ahora son matrices densas.
      • El método similar(::SpecialSparseMatrix, ::Type, ::Dims) devuelve una matriz nula densa. Como consecuencia, los productos de matrices de dos, tres y tridiagonales simétricas entre sí conducen a la generación de una matriz densa. Además, la construcción de matrices similares con tres argumentos a partir de matrices especiales "escasas" a partir de matrices (no estáticas) ahora falla debido a "zero(::Type{Matrix{T}})".
  • printf
    • %s y %c ahora usan el argumento ancho de texto para formatear el ancho.
  • Mi Perfil
    • El perfil de carga de CPU ahora registra metadatos, incluidos subprocesos y tareas. Profile.print() tiene un nuevo argumento groupby que le permite agrupar subprocesos, tareas o subprocesos/tareas, tareas/subprocesos y argumentos de subprocesos y tareas para proporcionar filtrado. Además, el porcentaje de utilización ahora se informa como general o por subproceso, dependiendo de si el subproceso está inactivo o no en cada muestra. Profile.fetch() incluye los nuevos metadatos de forma predeterminada. Para lograr compatibilidad con consumidores externos de datos de perfiles, se puede excluir pasando include_meta=false.
    • El nuevo módulo Profile.Allocs le permite perfilar las asignaciones de memoria. Se registra un seguimiento de la pila del tipo y tamaño de cada asignación de memoria, y el argumento sample_rate permite omitir una cantidad configurable de asignaciones, lo que reduce la sobrecarga de rendimiento.
    • El usuario ahora puede ejecutar la creación de perfiles de CPU de duración fija mientras se ejecutan las tareas sin cargar primero el perfil, y el informe se mostrará mientras se ejecuta. En MacOS y FreeBSD, presione ctrl-t o llame a SIGINFO. Para otras plataformas, active SIGUSR1, es decir. % matar -USR1 $julia_pid. Esto no está disponible en Windows.
  • REEMPLAZAR
    • RadioMenu ahora admite atajos de teclado adicionales para la selección directa de opciones.
    • La secuencia "?(x, y" seguida de presionar TAB muestra todos los métodos que se pueden llamar con argumentos x, y, .... (Un espacio al principio le impide ingresar al modo de ayuda). "MyModule.?(x, y " restringe la búsqueda a "MiMódulo". Al presionar TAB se requiere que al menos un argumento sea de un tipo más específico que Cualquiera. O use SHIFT-TAB en lugar de TAB para permitir cualquier método compatible.
    • La nueva variable global err le permite obtener la última excepción, similar al comportamiento de ans con la última respuesta. Al ingresar err se reimprime la información de la excepción.
  • Arreglos dispersos
    • Se movió el código SparseArrays del repositorio de Julia al repositorio externo SparseArrays.jl.
    • Las nuevas funciones de concatenación sparse_hcat, sparse_vcat y sparse_hvcat devuelven un tipo SparseMatrixCSC independientemente de los tipos de argumentos de entrada. Esto se hizo necesario para unificar el mecanismo para pegar matrices después de separar el código LinearAlgebra.jl y SparseArrays.jl.
  • Inicio de sesión
    • Los niveles de registro estándar BelowMinLevel, Debug, Info, Warn, Error y AboveMaxLevel ahora se exportan desde la biblioteca de registro estándar.
  • Unicode
    • Se agregó la función isequal_normalized para verificar la equivalencia Unicode sin construir explícitamente cadenas normalizadas.
    • La función Unicode.normalize ahora acepta la palabra clave charttransform, que se puede usar para proporcionar asignaciones de caracteres personalizadas, y la función Unicode.julia_chartransform también se proporciona para reproducir la asignación utilizada cuando el analizador Julia normaliza los identificadores.
  • Probar
    • '@test_throws "algún mensaje" triggers_error()' ahora se puede utilizar para probar si el texto de error mostrado contiene un error de "algún mensaje", independientemente del tipo de excepción específico. También se admiten expresiones regulares, listas de cadenas y funciones de coincidencia.
    • @testset foo() ahora se puede utilizar para crear un conjunto de pruebas a partir de una función determinada. El nombre del caso de prueba es el nombre de la función que se llama. La función llamada puede contener @test y otras definiciones @testset, incluso para llamadas a otras funciones, mientras registra todos los resultados de las pruebas intermedias.
    • TestLogger y LogRecord ahora se exportan desde la biblioteca de pruebas estándar.
  • Repartido
    • SSHManager ahora admite subprocesos de trabajo con un contenedor csh/tcsh a través del método addprocs() y el parámetro shell=:csh.
  • Otros cambios
    • GC.enable_logging(true) se puede utilizar para registrar cada operación de recolección de basura con el tiempo y la cantidad de memoria recolectada.

Fuente: opennet.ru

Añadir un comentario