È disponibile il rilascio del linguaggio di programmazione Julia 1.8, che unisce caratteristiche come alte prestazioni, supporto per la tipizzazione dinamica e strumenti integrati per la programmazione parallela. La sintassi di Julia è simile a MATLAB, con elementi presi in prestito da Ruby e Lisp. Il metodo di manipolazione delle stringhe ricorda Perl. Il codice del progetto è distribuito sotto licenza MIT.
Caratteristiche principali del linguaggio:
- Alte prestazioni: uno degli obiettivi chiave del progetto è raggiungere prestazioni simili a quelle dei programmi scritti in C. Il compilatore di Julia è basato sui risultati del progetto LLVM e genera codice macchina nativo efficiente per molte piattaforme mirate;
- Supporto per diverse paradigmi di programmazione, inclusi elementi di programmazione orientata agli oggetti e funzionale. La libreria standard fornisce anche funzioni per l'input/output asincrono, la gestione dei processi, la registrazione, il profiling e la gestione dei pacchetti;
- Tipizzazione dinamica: il linguaggio non richiede la definizione esplicita dei tipi per le variabili, simile ai linguaggi di scripting. È supportata la modalità interattiva.
- Possibilità opzionale di specificare esplicitamente i tipi;
- Una sintassi perfettamente adatta per calcoli numerici, studi scientifici, sistemi di apprendimento automatico e visualizzazione dei dati. Supporto per molti tipi di dati numerici e strumenti per il parallelismo nei calcoli.
- Possibilità di chiamare direttamente funzioni da librerie in linguaggio C senza strati aggiuntivi.
Principali novità di Julia 1.8:
- Nuove funzionalità del linguaggio
- I campi delle strutture mutabili (mutable struct) possono ora essere annotati come costanti per prevenire modifiche e consentire ottimizzazioni.
- Le annotazioni dei tipi possono essere aggiunte a variabili globali.
- È possibile creare array n-dimensionali vuoti utilizzando più punti e virgola all'interno delle parentesi quadre, ad esempio «[;;;]» crea un array 0×0×0.
- I blocchi try possono ora avere un blocco else aggiuntivo che viene eseguito subito dopo il corpo principale se non sono stati sollevati errori.
- @inline e @noinline possono essere utilizzati all'interno del corpo della funzione, consentendo di annotare una funzione anonima.
- @inline e @noinline possono ora essere applicati sia alla funzione nel sito di chiamata che nel blocco, per forzare l'inclusione (o l'esclusione) delle rispettive chiamate di funzione.
- ∀, ∃ e ∄ sono consentiti come simboli identificatori.
- Aggiunta del supporto per la specifica Unicode 14.0.0.
- Il metodo Module(:name, false, false) può essere utilizzato per creare un modulo che non contiene nomi, non importa Base o Core e non contiene riferimenti a se stesso.
- Modifiche al linguaggio
- Gli oggetti Task recentemente creati (@spawn, @async, ecc.) ora utilizzano world_age per i metodi del Task genitore al momento della creazione, consentendo di ottimizzare la loro esecuzione. La variante precedente di attivazione è disponibile tramite il metodo Base.invokelatest.
- Le direttive di formattazione bidirezionale Unicode non bilanciate sono ora vietate all'interno di stringhe e commenti per evitare iniezioni.
- Base.ifelse è ora definita come funzione generica invece che come incorporata, consentendo ai pacchetti di estendere la sua definizione.
- Ogni assegnazione di una variabile globale ora passa prima attraverso la chiamata convert(Any, x) o convert(T, x), se è stato dichiarato un tipo T per la variabile globale. Prima di utilizzare variabili globali, assicurati che l'invariante convert(Any, x) === x sia sempre vero, altrimenti possono verificarsi comportamenti imprevisti.
- Le funzioni incorporate ora assomigliano a funzioni generiche e possono essere elencate programmaticamente tramite metodi.
- Miglioramenti del compilatore / ambiente di esecuzione
- Il tempo di avvio iniziale è stato ridotto di circa il 25%.
- Il compilatore basato su LLVM è stato separato dalla libreria runtime in una nuova libreria libjulia-codegen. Essa viene caricata per impostazione predefinita, quindi non dovrebbero esserci modifiche durante l'uso normale. Nelle implementazioni che non necessitano di un compilatore (ad esempio, le immagini di sistema in cui tutto il codice necessario è stato precedentemente compilato), questa libreria (e la sua dipendenza da LLVM) possono semplicemente essere escluse.
- La restituzione di un tipo condizionale è ora possibile tramite il passaggio di un argomento al metodo. Ad esempio, per Base.ifelse(isa(x, Int), x, 0) restituisce ::Int, anche se il tipo di x è sconosciuto.
- SROA (Sostituzione Scalari di Aggregati) migliorato: esclude le chiamate getfield con campi globali costanti, esclude le strutture modificabili con campi non inizializzati, aumentando la performance e la gestione delle chiamate annidate a getfield.
- L'output dei tipi tiene traccia di vari effetti — modifiche collaterali e assenza di scarti. Tiene conto della propagazione delle costanti, il che migliora notevolmente le performance durante la compilazione. In alcuni casi, ad esempio, le chiamate a funzioni che non possono essere incorporate in luogo di chiamata, ma non influenzano il risultato, verranno scartate a runtime. Le regole per gli effetti possono essere sovrascritte manualmente con il macro Base.@assume_effects.
- La precompilazione (con direttive di precompilazione esplicite o carichi di lavoro definiti) ora conserva più codice definito dal tipo, riducendo i tempi di avvio iniziale. Qualsiasi nuova combinazione di metodi/tipi necessaria per il tuo pacchetto, indipendentemente da dove siano stati definiti, può ora essere memorizzata nella cache nel file di precompilazione se vengono invocati da un metodo appartenente al tuo pacchetto.
- Modifiche ai parametri della riga di comando
- Il comportamento predefinito per il monitoraggio delle dichiarazioni @inbounds è ora un'opzione auto in "—check-bounds=yes|no|auto".
- Nuova opzione "—strip-metadata" per rimuovere righe di documentazione, informazioni sulla posizione sorgente e nomi delle variabili locali durante la creazione dell'immagine del sistema.
- Nuova opzione "—strip-ir" per rimuovere la rappresentazione intermedia del codice sorgente durante la costruzione dell'immagine del sistema. L'immagine risultante funzionerà solo se si utilizza "—compile=all" o se tutto il codice necessario è stato precompilato.
- Se invece del nome del file è specificato il simbolo «-», il codice eseguibile verrà letto dallo standard input.
- Modifiche al supporto della multithreading
- Threads.@threads utilizza per impostazione predefinita un nuovo parametro di pianificazione :dynamic, che differisce dalla modalità precedente in quanto le iterazioni saranno pianificate dinamicamente per i thread di lavoro disponibili, piuttosto che essere assegnate a ciascun thread. Questa modalità consente di distribuire meglio i cicli nidificati con @spawn e @threads.
- Nuove funzioni di libreria
- eachsplit(str) per eseguire più volte split(str).
- allequal(itr) per verificare l'uguaglianza di tutti gli elementi in un iteratore.
- hardlink(src, dst) può essere utilizzato per creare collegamenti fisici.
- setcpuaffinity(cmd, cpus) per impostare la corrispondenza del core della CPU con i processi in esecuzione.
- diskstat(path=pwd()) per ottenere le statistiche sul disco.
- Nuovo macro @showtime per visualizzare sia la stringa valutata che il report @time.
- LazyString e macro lazy»str» aggiunti per supportare la costruzione ritardata dei messaggi di errore nei percorsi degli errori.
- Risolto il problema di accesso concorrente in Dict e in altri oggetti derivati, come keys(::Dict), values(::Dict) e Set. I metodi di iterazione possono ora essere chiamati su un dizionario o un insieme, a condizione che non ci siano chiamate che modificano il dizionario o l'insieme.
- @time e @timev ora hanno una descrizione facoltativa che permette di annotare la fonte dei report sui tempi, ad esempio. @time "Valutazione di foo" foo().
- range accetta ora o stop o length come unico argomento chiave.
- precision e setprecision ora accettano base come chiave.
- Gli oggetti socket TCP ora forniscono il metodo closewrite e supportano l'uso della modalità semichiusa.
- extrema ora accetta l'argomento init.
- Iterators.countfrom ora accetta qualsiasi tipo che definisce il metodo +.
- @time ora evidenzia la % del tempo speso a ricompilare i metodi con tipi modificati.
- Modifiche alla libreria standard
- Le chiavi con valore Nothing ora vengono rimosse dall'ambiente in addenv.
- Iterators.reverse (e quindi last) supporta eachline.
- La funzione length per intervalli di tipi definiti non verifica più il sovraccarico intero. È disponibile una nuova funzione checked_length, che contiene la logica di controllo del riporto. Se necessario, utilizza SaferIntegers.jl per costruire il tipo di intervallo.
- L'iteratore Iterators.Reverse implementa l'inversione di eachindex, se possibile.
- Gestore pacchetti
- Nuovi indicatori ⌃ e ⌅ accanto ai pacchetti nello stato «pkg>», per i quali sono disponibili nuove versioni. ⌅ indica che nuove versioni non possono essere installate.
- Nuovo argomento outdated::Bool per Pkg.status (—outdated o -o in modalità REPL), per mostrare informazioni sui pacchetti con versioni precedenti.
- Nuovo argomento compat::Bool per Pkg.status (—compat o -c in modalità REPL), per mostrare eventuali voci [compat] in Project.toml.
- Nuova modalità «pkg> compat» (e Pkg.compat) per la configurazione delle voci di compatibilità del progetto. Fornisce un editor interattivo tramite «pkg> compat» o gestione diretta della voce attraverso «pkg> Foo 0.4,0.5», che può caricare le voci attuali tramite completamento automatico con tabulazione. Cioè, «pkg> compat Fo<TAB>» viene automaticamente completata in «pkg> Foo 0.4,0.5» per poter modificare la voce esistente.
- Ora Pkg sta cercando di caricare i pacchetti da server i pacchetti solo se il server tiene traccia di un registro contenente il pacchetto.
- Pkg.instantiate ora visualizzerà un avviso quando Project.toml non è sincronizzato con Manifest.toml. Questo avviene sulla base dell'hash delle voci deps e compat del progetto (altri campi vengono ignorati) nel manifesto durante la sua risoluzione, così è possibile rilevare eventuali modifiche nelle voci deps di Project.toml o compat senza una nuova risoluzione.
- Se «pkg> add» non riesce a trovare un pacchetto con il nome specificato, ora verranno suggeriti pacchetti con nomi simili che possono essere aggiunti.
- La versione di julia memorizzata nel manifesto non include più il numero di build, ovvero master ora sarà registrato come 1.9.0-DEV.
- L'interruzione del test «pkg>» ora verrà riconosciuta in modo più stabile e restituirà correttamente in REPL.
- InteractiveUtils
- Nuovo macro @time_imports per riportare il tempo trascorso nell'importazione di pacchetti e delle loro dipendenze, evidenziando il tempo di compilazione e ricompilazione in percentuale sull'importo.
- Algebra lineare
- Il sottModulo BLAS ora supporta le funzioni BLAS di livello 2 spr!.
- La libreria standard LinearAlgebra.jl è ora completamente indipendente da SparseArrays.jl sia dal punto di vista del codice sorgente che dei test modulari. Di conseguenza, gli array sparsi non vengono più restituiti (implicitamente) dai metodi di LinearAlgebra applicati agli oggetti di Base o LinearAlgebra. In particolare, ciò porta ai seguenti cambiamenti critici:
- Le concatenazioni utilizzando matrici «sparse» speciali (ad esempio, diagonali) ora restituiscono matrici dense. Di conseguenza, i campi D1 e D2 degli oggetti SVD, creati durante le chiamate a getproperty, sono ora matrici dense.
- Il metodo similar(::SpecialSparseMatrix, ::Type, ::Dims) restituisce una matrice zero densa. Di conseguenza, i prodotti di matrici bi- e tri-diagonali simmetriche tra loro generano una matrice densa. Inoltre, la costruzione di tali matrici con tre argomenti da matrici «sparse» speciali da matrici (non statiche) ora fallisce a causa di «zero(::Type{Matrix{T}})».
- Printf
- Ora per il formato della larghezza %s e %c si usa l'argomento textwidth.
- Profile
- Il monitoraggio del carico della CPU ora registra i metadati, inclusi i thread e i task. Profile.print() ha un nuovo argomento groupby che consente di raggruppare thread, task o thread/nestati task, task/thread, insieme agli argomenti threads e tasks per facilitare il filtraggio. Inoltre, la percentuale di utilizzo ora viene riportata sia come totale sia per thread, a seconda che il thread sia inattivo o meno in ogni campione. Profile.fetch() include nuovi metadati per impostazione predefinita. Per garantire la retrocompatibilità con i consumatori esterni dei dati di profiling, è possibile escluderlo passando include_meta=false.
- Il nuovo modulo Profile.Allocs consente di profilare l'assegnazione della memoria. Viene registrata la traccia dello stack, il tipo e la dimensione di ogni allocazione di memoria, e l'argomento sample_rate consente di saltare un numero personalizzabile di allocazioni, riducendo così il carico sulle prestazioni.
- Il profiling della CPU con durata fissa può ora essere avviato dall'utente durante l'esecuzione dei task senza bisogno di caricare un profilo in anticipo, e il report verrà visualizzato in tempo reale. Su MacOS e FreeBSD premi ctrl-t o invia SIGINFO. Per altre piattaforme, attiva SIGUSR1, ovvero % kill -USR1 $julia_pid. Su Windows questo non è disponibile.
- REPL
- Il RadioMenu ora supporta combinazioni di tasti aggiuntive per la selezione diretta delle opzioni.
- La sequenza «?(x, y» seguita dalla pressione di TAB mostra tutti i metodi che possono essere chiamati con gli argomenti x, y, … (uno spazio all'inizio non consente l'ingresso nella modalità di aiuto). «MyModule.?(x, y» limita la ricerca a «MyModule». La pressione di TAB richiede che almeno un argomento possieda un tipo più specifico rispetto ad Any. Oppure usa SHIFT-TAB invece di TAB per consentire metodi compatibili.
- La nuova variabile globale err permette di ottenere l'eccezione più recente, simile al comportamento di ans con l'ultima risposta. Immettere err ristampa le informazioni sull'eccezione.
- SparseArrays
- Il codice di SparseArrays è stato spostato dal repository di Julia a un repository esterno chiamato SparseArrays.jl.
- Le nuove funzioni di concatenazione sparse_hcat, sparse_vcat e sparse_hvcat restituiscono il tipo SparseMatrixCSC indipendentemente dai tipi degli argomenti di input. Questo è diventato necessario per unificare il meccanismo di unione delle matrici dopo la separazione del codice di LinearAlgebra.jl e SparseArrays.jl.
- Logging
- I livelli di log standard BelowMinLevel, Debug, Info, Warn, Error e AboveMaxLevel sono ora esportati dalla libreria standard Logging.
- Unicode
- È stata aggiunta la funzione isequal_normalized per controllare l'equivalenza Unicode senza costruire esplicitamente stringhe normalizzate.
- La funzione Unicode.normalize ora accetta la parola chiave chartransform, che può essere utilizzata per fornire associazioni di caratteri personalizzate, e è anche fornita la funzione Unicode.julia_chartransform per riprodurre l'associazione utilizzata durante la normalizzazione degli identificatori dal parser di Julia.
- Test
- ‘@test_throws «some message» triggers_error()’ può ora essere utilizzato per verificare se il testo visualizzato dell'errore include «some message», indipendentemente dal tipo specifico di eccezione. Sono supportate anche espressioni regolari, elenchi di stringhe e funzioni di corrispondenza.
- @testset foo() può ora essere utilizzato per creare un insieme di test a partire da una funzione specificata. Il nome dell'insieme di test corrisponde al nome della funzione chiamata. La funzione chiamata può contenere @test e altre definizioni di @testset, incluse chiamate ad altre funzioni, registrando tutti i risultati intermedi del test.
- TestLogger e LogRecord ora vengono esportati dalla libreria standard Test.
- Distribuito
- SSHManager ora supporta i thread di lavoro con un wrapper csh/tcsh attraverso il metodo addprocs() e il parametro shell=:csh.
- Altre modifiche
- GC.enable_logging(true) può essere utilizzato per registrare ogni operazione di garbage collection specificando il tempo e la quantità di memoria raccolta.
Fonte: opennet.ru
