È stato pubblicato il rilascio del linguaggio di programmazione Julia 1.9, che combina caratteristiche come elevate 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 con 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 cambiamenti in Julia 1.9:
- Nuove funzionalità del linguaggio
- È consentito eseguire assegnazioni in un altro modulo utilizzando "setproperty!(::Module, ::Symbol, x)".
- È consentita l'assegnazione multipla non nell'ultima posizione. Ad esempio, la riga "a, b…, c = 1, 2, 3, 4" sarà trattata come "a = 1; b…, = 2, 3; c = 4". Questo viene gestito tramite Base.split_rest.
- I letterali per i singoli simboli ora supportano la stessa sintassi dei letterali stringa; cioè, la sintassi può rappresentare sequenze UTF-8 non valide, come consentito dal tipo Char.
- È stato aggiunto il supporto per la specifica Unicode 15.
- Le combinazioni di tuple annidate e le tuple nominate ora possono essere utilizzate come parametri di tipo.
- Nuove funzioni integrate "getglobal(::Module, ::Symbol[, order])" e "setglobal!(::Module, ::Symbol, x[, order])" per leggere e scrivere esclusivamente in variabili globali. Il metodo getglobal deve ora essere preferito per accedere alle variabili globali rispetto al metodo getfield.
- Modifiche al linguaggio
- Il macro "@invoke", introdotto nella versione 1.7, ora è esportato e disponibile per l'uso. Inoltre, ora utilizza il metodo "Core.Typeof(x)" invece di "Any" nel caso in cui l'annotazione del tipo sia omessa per l'argomento "x". Questo è necessario affinché i tipi passati come argomenti siano trattati correttamente.
- È stata inclusa l'esportazione della funzione "invokelatest" e del macro "@invokelatest", apparsi nella versione 1.7.
- Miglioramenti del compilatore / ambiente di esecuzione
- È stata notevolmente ridotta la latenza fino alla prima esecuzione (TTFX — Time to first execution). La compilazione anticipata del pacchetto ora salva il codice macchina in "pkgimage", il che significa che il codice generato durante la compilazione anticipata non richiederà una nuova compilazione dopo il caricamento del pacchetto. L'uso della modalità pkgimages può essere disattivato con l'opzione "—pkgimages=no".
- È stato risolto il problema noto di complessità quadratica nell'inferenza dei tipi e in generale l'inferenza utilizza meno memoria. Alcuni casi limite con funzioni lunghe generate automaticamente (ad esempio, ModelingToolkit.jl con equazioni differenziali e grandi modelli causali) vengono compilati molto più rapidamente.
- Le chiamate con argomenti senza tipi specifici ora possono essere ottimizzate tramite il metodo Union-splitting per l'inserimento o la risoluzione statica, anche se ci sono più candidati di tipo diverso per la dispatch. Questo può migliorare le prestazioni in determinate situazioni, quando i tipi degli oggetti non sono completamente risolti staticamente, grazie alla risoluzione statica dei punti di chiamata "@nospecialize-d" e evitando la ricompilazione.
- Tutti i casi d'uso del macro @pure nel modulo Base sono stati sostituiti con Base.@assume_effects.
- Le chiamate invoke(f, invokesig, args…) con tipi meno specifici rispetto a quelli normalmente usati per f(args…) non provocano più la ricompilazione del pacchetto.
- Modifiche ai parametri della riga di comando
- In Linux e Windows, il parametro "—threads=auto" ora cerca di determinare il numero disponibile di processori in base all'affinità della CPU, la cui maschera è solitamente impostata in ambienti di calcolo ad alte prestazioni e in ambienti cloud.
- Il parametro "—math-mode=fast" è stato disattivato e si consiglia di utilizzare il macro "@fastmath", che ha una semantica ben definita.
- Il parametro "—threads" ora ha il formato "auto | N[,auto|M]", dove M indica il numero di thread interattivi da creare (attualmente auto significa 1).
- È stata aggiunta l'opzione "—heap-size-hint=", che stabilisce una soglia oltre la quale inizia la raccolta attiva della spazzatura. La dimensione può essere specificata in byte, kilobyte (1000 KB), megabyte (300 MB) o gigabyte (1,5 GB).
- Modifiche al multithreading
- "Threads.@spawn" ora ha un primo argomento opzionale con valore "default" o "interactive". Un'attività interattiva richiede una bassa latenza di risposta ed è progettata per essere breve o spesso eseguita. Le attività interattive verranno eseguite in thread interattivi, se specificati all'avvio di Julia.
- I thread avviati al di fuori dell'ambiente di esecuzione di Julia (ad esempio, da C o Java) possono ora chiamare il codice Julia utilizzando "jl_adopt_thread". Questo accade automaticamente quando si inserisce codice Julia tramite "cfunction" o il punto di ingresso "@ccallable". Di conseguenza, il numero di thread può ora cambiare durante l'esecuzione.
- Nuove funzioni di libreria
- Nuova funzione "Iterators.flatmap".
- Nuova funzione «pkgversion(m::Module)» per ottenere la versione del pacchetto caricato da questo modulo, simile a «pkgdir(m::Module)».
- Nuova funzione «stack(x)», che generalizza «reduce(hcat, x::Vector{<:Vector})» a qualsiasi dimensione e accetta qualsiasi iteratore di iteratori. Il metodo «stack(f, x)» generalizza «mapreduce(f, hcat, x)» ed è più efficiente.
- Nuovo macro per l'analisi della memoria allocata «@allocations», simile a «@allocated», ma ritorna il numero di operazioni di allocazione invece del totale della memoria allocata.
- Nuove funzionalità della libreria
- «RoundFromZero» ora funziona per tipi diversi da «BigFloat».
- Ora «Dict» può essere ridotto manualmente usando «sizehint!».
- «@time» ora indica separatamente la percentuale di tempo speso nella ricompilazione di metodi non validi.
- Modifiche alla libreria standard
- Risolto un problema di accesso concorrente nei metodi di iterazione per Dict e altri oggetti derivati, come keys(::Dict), values(::Dict) e Set. Questi metodi di iterazione possono ora essere chiamati per Dict o Set parallelamente a un numero illimitato di thread, a condizione che non ci siano operazioni che modificano il dizionario o l'insieme.
- La negazione della funzione predicativa «!f» ora restituisce una funzione composita «(!) ∘ f» anziché una funzione anonima.
- Le funzioni di slicing dimensionale ora funzionano su più dimensioni: «eachslice», «eachrow» e «eachcol» restituiscono un oggetto «Slices», che consente la dispatching per fornire metodi più efficienti.
- È stato aggiunto il macro «@kwdef» all'API pubblica.
- Risolta la questione dell'ordine delle operazioni in «fld1».
- L'ordinamento ora è sempre stabile nel tempo (QuickSort riprogettato).
- «Base.splat» ora è esportato. Il valore di ritorno è un tipo «Base.Splat», non una funzione anonima, il che lo rende bello da visualizzare.
- Gestore pacchetti
- «Package Extensions»: supporto per il caricamento di frammenti di codice da altri pacchetti caricati nella sessione Julia. L'uso è simile al pacchetto «Requires.jl», ma supporta la precompilazione e la compatibilità delle impostazioni.
- Libreria LinearAlgebra
- A causa del rischio di confusione con la divisione elemento per elemento, sono stati rimossi i metodi «a / b» e «b \ a» con lo scalare «a» e il vettore «b», che erano equivalenti a «a * pinv(b)».
- Per chiamare BLAS e LAPACK ora si usa «libblastrampoline (LBT)». OpenBLAS è fornito di default, ma la costruzione di un'immagine di sistema con altre librerie BLAS/LAPACK non è supportata. Si raccomanda di utilizzare il meccanismo LBT per sostituire BLAS/LAPACK con un'altra libreria.
- «lu» supporta una nuova strategia di rotazione della matrice «RowNonZero()», che seleziona il primo elemento non nullo della rotazione per l'uso con i nuovi tipi aritmetici e per scopi didattici.
- «normalize(x, p=2)» ora supporta qualsiasi spazio vettoriale normalizzato «x», inclusi gli scalari.
- Il numero di thread di BLAS di default ora è pari al numero di thread CPU sull'architettura ARM e alla metà del numero di thread CPU su altre architetture.
- Printf: Per una migliore leggibilità, i messaggi di errore per le stringhe in formato errato sono stati riprogettati.
- Profile: Nuova funzione «Profile.take_heap_snapshot(file)», che scrive un file in formato «.heapsnapshot» basato su JSON, supportato in Chrome.
- Random: randn e randexp ora funzionano per qualsiasi tipo di AbstractFloat che definisce rand.
- REPL
- La pressione della combinazione di tasti «Alt-e» ora apre l'input corrente nell'editor. Il contenuto (se modificato) sarà eseguito all'uscita dall'editor.
- Il contesto del modulo attivo in REPL può essere cambiato (di default è Main) usando la funzione «REPL.activate(::Module)» o inserendo il modulo in REPL e premendo la combinazione di tasti «Alt-m».
- La modalità «prompt numerato», che visualizza numeri per ogni input e output e salva i risultati valutati in Out, può essere attivata con «REPL.numbered_prompt!()».
- Il completamento automatico tramite tabulazione mostra gli argomenti delle parole chiave disponibili.
- SuiteSparse: Il codice per il risolutore «SuiteSparse» è stato spostato in «SparseArrays.jl». I risolutori ora sono riesportati in «SuiteSparse.jl».
- SparseArrays
- I risolutori «SuiteSparse» sono ora disponibili come sottogruppi di «SparseArrays».
- Le modalità di protezione dei thread UMFPACK e CHOLMOD sono state migliorate escludendo le variabili globali e utilizzando serrature. Il «ldiv!» multithread degli oggetti UMFPACK ora può essere eseguito in modo sicuro.
- La funzione sperimentale «SparseArrays.allowscalar(::Bool)» consente di disattivare o attivare l'indicizzazione scalare di matrici sparse. Questa funzione è destinata a rilevare l'indicizzazione scalare casuale degli oggetti «SparseMatrixCSC», che è una comune fonte di problemi di prestazioni.
- Una nuova modalità di tolleranza ai guasti per i set di test, che termina anticipatamente l'esecuzione del test in caso di errore o fallimento. Può essere impostata tramite «@testset kwarg failfast=true» o «export JULIA_TEST_FAILFAST=true». Questo è utile nei lanci CI per ricevere messaggi di errore tempestivi.
- Date: Le stringhe vuote non vengono più analizzate in modo errato come valori validi di «DateTime», «Dates» o «Times» e producono invece un errore «ArgumentError» nei costruttori e nell'analisi sintattica, mentre «tryparse» non restituisce nulla.
- Pacchetto Distributed
- La configurazione del pacchetto (progetto attivo, «LOAD_PATH», «DEPOT_PATH») è ora distribuita quando si aggiungono processi di lavoro locali (ad esempio utilizzando «addprocs(N::Int)» o tramite il flag della riga di comando «—procs=N»).
- «addprocs» per i processi di lavoro locali ora accetta un argomento chiamato «env» per passare le variabili di ambiente ai processi di lavoro.
- Unicode: «graphemes(s, m:n)» restituisce una sottostringa dalla m-esima alla n-esima grafema in «s».
- Il pacchetto DelimitedFiles è stato rimosso dalle librerie di sistema ed è ora distribuito come pacchetto separato che deve essere installato esplicitamente per essere utilizzato.
- Dipendenze esterne
- Su Linux viene automaticamente rilevata la versione della libreria di sistema libstdc++ e se è più recente, viene caricata. Il comportamento precedente di caricamento della libstdc++ incorporata indipendentemente dalla versione del sistema può essere ripristinato impostando la variabile di ambiente «JULIA_PROBE_LIBSTDCXX=0».
- È stato rimosso il «RPATH» dal file binario di julia, il che può causare su Linux problemi con le librerie che non sono riuscite a trovare la variabile «RUNPATH».
- Miglioramenti agli strumenti: L'output di «MethodError» e dei metodi (ad esempio da «methods(my_func)») è ora formattato e colorato secondo il principio di output dei metodi durante il tracciamento dello stack.
Fonte: opennet.ru
