Julia è un linguaggio di programmazione dinamico e fortemente tipizzato. Lo stile di programmazione è principalmente funzionale, ma con più flessibilità rispetto a linguaggi come Haskell.
Esiste un sistema di tipi robusto e versatile, che diventerà importante nei concetti successivi. In pratica, Julia di solito inferirà un valore predefinito adeguato dal contesto.
Nonostante l'enfasi sulla leggibilità, che lo fa sembrare un linguaggio di scripting come Python e Ruby, il codice Julia viene compilato prima di essere eseguito. Il compilatore Just In Time (JIT) produce codice altamente ottimizzato per ogni funzione nel momento in cui la incontra, il che porta a una elevata velocità di esecuzione.
Julia non è un linguaggio orientato agli oggetti e non esiste una gerarchia di classi come quella centrale in molti altri linguaggi.
Al contrario (e non spaventarti mentre leggi questo!), Julia si basa su:
Questi termini piuttosto confusi diventeranno più chiari man mano che avanzeremo nel percorso.
La documentazione ufficiale contiene molte informazioni preziose per la versione attuale, anche se può risultare un po' opprimente per chi comincia.
Tra i video:
Includere commenti nel codice è estremamente importante per aiutare gli esseri umani a leggere il tuo codice e capire le tue intenzioni: forse altre persone, ma anche il te stesso del futuro. Sono (in gran parte) ignorati dal compilatore.
In Julia sono possibili due opzioni:
#
#= e terminano con =#. È consentito l'annidamento.# This is a single-line comment
x = 3 # This is an inline comment
#=
Multi-line comments can be used for longer explanations.
They are especially useful to comment out blocks of code during debugging.
=#
Per creare una variabile, basta assegnarle un valore:
julia> myvar = 42 # an integer (in fact, Int64)
42
julia> bigint = 1_234_567_890 # optionally use underscore as digit separator, for readability
1234567890
julia> name = "Maria" # strings are surrounded by double-quotes ""
"Maria"
L'assegnazione «lega» un valore alla variabile.
Specificare un tipo è facoltativo e nella maggior parte dei casi Julia inferirà un valore predefinito adeguato dal contesto.
I tipi sono un argomento importante in Julia. Li esploreremo più a fondo nei concetti successivi. Per ora, è meglio non preoccuparsene.
A differenza di molti linguaggi funzionali, in Julia le variabili possono essere riassegnate e sei libero di cambiare sia il valore sia il tipo associato alla variabile:
julia> myvar = 3
3
julia> myvar = "now a string"
"now a string"
Le variabili globali, create al di fuori di qualsiasi funzione, sono:
*.jl; la REPL funziona diversamente).Se un valore deve essere disponibile in tutto il programma, ma non si prevede che cambi, usa invece una costante.
Anteporre la parola chiave const all'assegnazione permette al compilatore di generare codice più efficiente.
Se provi accidentalmente a cambiare il valore di una const, otterrai un avviso:
julia> const answer = 42
42
julia> answer = 24
WARNING: redefinition of constant Main.answer. This may fail, cause incorrect answers, or produce other errors.
24
L'aritmetica funziona in gran parte in modo convenzionale:
2 + 3 # 5 (addition)
2 - 3 # -1 (subtraction)
2 * 3 # 6 (multiplication)
8 / 2 # 4.0 (division)
8 % 3 # 2 (remainder)
2 ^ 3 # 8 (exponentiation)
Nota che la divisione con / restituisce sempre un valore in virgola mobile.
Torneremo su questo punto nei concetti successivi, dove parleremo della divisione intera con div() o ÷ per troncare e di // per ottenere un numero razionale.
Per ottenere le migliori prestazioni in fase di esecuzione, è meglio collocare la maggior parte del codice all'interno di funzioni. Avere molte funzioni piccole va bene, a differenza di alcuni altri linguaggi.
Ci sono due modi comuni per definire una funzione con nome in Julia:
Usando la parola chiave function
function muladd(x, y, z)
x * y + z
end
L'indentazione di 4 spazi è convenzionale per la leggibilità, ma il compilatore la ignora.
La parola chiave end è essenziale: più simile a Ruby che a Python.
Nota che avremmo potuto scrivere return x * y + z.
Tuttavia, le funzioni Julia restituiscono sempre l'ultima espressione valutata, quindi la parola chiave return è facoltativa.
Molti programmatori preferiscono includerla per rendere le loro intenzioni più esplicite.
Usando la «forma di assegnazione»
muladd(x, y, z) = x * y + z
Si usa più comunemente per definizioni di funzioni su una sola riga o per funzioni matematiche, dove il corpo della funzione è una singola espressione.
Nella forma di assegnazione la parola chiave return non viene mai usata.
Le due forme sono equivalenti e si usano esattamente allo stesso modo, quindi scegli quella che ti sembra più leggibile.
Per chiamare una funzione, si specifica il suo nome e si passano gli argomenti per ciascuno dei parametri della funzione:
# invoking a function
muladd(10, 5, 1)
# and of course you can invoke a function within the body of another function:
square_plus_one(x) = muladd(x, x, 1)
Dal fatto che le chiamiamo funzioni «con nome», potresti intuire che esistono anche funzioni «anonime». Ne parleremo in un concetto successivo.
Come molti linguaggi, Julia richiede che i nomi (di variabili, funzioni e molte altre cose) inizino con una lettera, seguita da qualsiasi combinazione di lettere, cifre e underscore.
Per convenzione, i nomi di variabili, costanti e funzioni sono in minuscolo, e gli underscore si evitano tranne quando servono a evitare confusione.
Tuttavia, Julia usa Unicode ovunque, quindi «lettera» viene interpretato in modo piuttosto flessibile.
Sono supportate anche lingue diverse dall'inglese, e lo stesso vale per le emoji (ma mi raccomando, usa buon gusto e scegli qualcosa di appropriato).
In particolare, sono disponibili tutte le lettere greche care ai matematici (e diversi valori utili sono predefiniti):
julia> π # a built-in constant
π = 3.1415926535897...
Gli editor che conoscono Julia, tra cui la REPL, Pluto.jl e VS Code con il plugin di Julia, rendono facili da inserire questi caratteri.
Per π, digita \pi e poi premi <Tab>. Quello che hai digitato verrà sostituito dal carattere greco.
Vedrai molti altri esempi di questo nei concetti successivi.
In realtà, le abbreviazioni con la barra rovesciata non sono qualcosa di specifico di Julia. Provengono da LaTeX, un sistema di composizione tipografica che molti scienziati e ingegneri usano quasi ogni giorno per scrivere relazioni.