Repository navigation
Libro 04 Lessico
Prima di costruire frasi bisogna conoscere le parole. Questo capitolo descrive il lessico di Triad-Core: come il testo di un programma viene spezzato in unità elementari (i token) e quali regole governano quella suddivisione. Sembra materia arida, ma molti errori dei principianti nascono proprio qui, e alcune scelte lessicali di Triad hanno conseguenze che si sentono in tutto il linguaggio.
Quando l'interprete legge un file, la prima cosa che fa è scorrerlo carattere per carattere e
raggrupparlo in token: un nome, un numero, una stringa, un operatore, una parentesi, un
separatore. Gli spazi e i commenti servono solo a separare i token e poi scompaiono. Nel
capitolo 19 vedremo la funzione tokenize che fa questo lavoro nell'interprete di riferimento;
qui ci interessa il risultato.
Un identificatore inizia con una lettera o con _ e prosegue con lettere, cifre o _.
x, somma_parziale, _tmp, fib2 sono nomi validi; 2fib no, perché inizierebbe con una
cifra. È ammesso un ! finale, come in push!: per convenzione indica una funzione che
modifica il proprio argomento, e lo ritroveremo nei capitoli sulle liste.
Alcuni nomi sono riservati perché hanno un significato nella grammatica: function, end,
if, elseif, else, while, let, begin, return, break, continue, true, false,
nothing. Triad-Full ne aggiunge altri (struct, fact, rule, solve, for, try, …), e
conviene evitarli come nomi anche scrivendo in Core, perché un programma Core deve restare
valido in Full.
In Core esistono solo interi: 0, 42, 1_000_000. Il trattino basso è un separatore
visivo, ignorato dal lettore, utile per i numeri lunghi. Il segno meno non fa parte del numero:
-5 è l'operatore "meno unario" applicato a 5. La differenza è sottile ma ha una conseguenza
pratica: - 5 e -5 sono la stessa cosa.
Non esistono numeri decimali: scrivere 1.5 in Core produce un errore di sintassi. È una delle
rinunce più evidenti di Core, giustificata dalla difficoltà di implementare la virgola mobile in
codice macchina scritto a mano; Triad-Full ha il tipo Float.
Una stringa è racchiusa tra virgolette doppie: "ciao". Dentro la stringa il carattere \
introduce una sequenza di escape per i caratteri che non si possono scrivere direttamente:
| escape | significato |
|---|---|
\n |
a capo |
\t |
tabulazione |
\" |
virgolette doppie |
\\ |
il carattere backslash |
println("riga uno\nriga due")
println("una \"citazione\" e un backslash: \\")
println("a\tb")Output:
riga uno
riga due
una "citazione" e un backslash: \
a b
Attenzione. In Triad-Full si può scrivere
"x vale $x"e il valore dixviene inserito nella stringa (interpolazione). In Core no: il$resta un carattere qualsiasi e la stringa viene stampata letteralmente. Per comporre testo e valori in Core si concatena:"x vale " * string(x).
Un simbolo è un nome preceduto da due punti: :alice, :rosso, :ok. A differenza di una
stringa, un simbolo non è testo da elaborare ma un'etichetta: due simboli sono uguali se e solo
se hanno lo stesso nome, e confrontarli è immediato. Si usano per rappresentare valori di
un'enumerazione (:nord, :sud), etichette di dati (:Punto), risultati (:ok, :errore).
Anche un operatore può diventare un simbolo: :+ è il simbolo il cui nome è +.
direzione = :nord
println(direzione)
println(direzione == :nord, " ", :a == :b)Output:
nord
true false
Nota che println stampa il simbolo senza i due punti. Il capitolo 5 spiega quando li mostra.
# inizia un commento che dura fino a fine riga. #= e =# delimitano un commento su più
righe:
#= Questo programma
calcola una somma. =#
s = 1 + 2 # somma di prova
println(s)Output:
3
Nota. Lo standard Full prevede che i commenti
#= … =#si possano annidare, uno dentro l'altro. L'interprete di riferimento Core non lo fa: si ferma al primo=#. Evita quindi di annidarli nel codice Core.
In Triad un'istruzione finisce alla fine della riga. Non serve il punto e virgola, ma lo si può usare per mettere più istruzioni sulla stessa riga:
a = 1; b = 2; println(a + b)Output:
3
Le righe vuote sono ignorate. In compenso, una riga spezzata nel punto sbagliato cambia il
significato del programma: scrivere x = 1 + su una riga e 2 sulla successiva è un errore in
Core, perché la prima riga è un'istruzione incompleta. La regola pratica è tenere ogni
istruzione su una riga, oppure andare a capo solo dentro parentesi e dentro i blocchi.
Gli operatori di Core sono + - * % ^ (aritmetica), == != < <= > >= (confronto),
&& || ! (logica), = += -= *= (assegnamento), -> (lambda) e ? : (ternario). Le
parentesi tonde raggruppano espressioni e racchiudono gli argomenti, quelle quadre costruiscono
e indicizzano liste, la virgola separa elementi. Il loro significato e la loro precedenza sono
l'argomento del capitolo 6.
- I nomi iniziano con una lettera o
_; un!finale segnala per convenzione una funzione che modifica i suoi argomenti. - In Core i numeri sono solo interi;
1.5e/appartengono a Full. - Le stringhe usano gli escape
\n \t \" \\; l'interpolazione con$è solo Full. - I simboli (
:nome) sono etichette confrontabili istantaneamente. - Un'istruzione finisce a fine riga o al
;.
- Quali di questi sono identificatori validi?
conta!,_x1,1x,valore_finale,end. - Scrivi un programma che stampi, su tre righe, un testo che contenga una tabulazione, delle virgolette e un backslash.
- Prova a scrivere
println(1.5)e osserva il messaggio d'errore dell'interprete.
← Capitolo 3 — L'ambiente e il primo programma · Sommario · Capitolo 5 — Valori e tipi →
Parte prima
Parte seconda 4. Le parole del linguaggio 5. Valori e tipi 6. Espressioni, operatori e variabili 7. Decidere e ripetere 8. Funzioni e ricorsione 9. Lambda, chiusure e visibilità dei nomi 10. Liste e dati strutturati 11. Stringhe, simboli e byte 12. Quando le cose vanno storte 13. Progetto: un piccolo interprete
Parte terza 14. Tipi, struct e multiple dispatch 15. Programmazione logica 16. Codice come dato e macro 17. Garanzie, costrutti Full e interfaccia
Parte quarta 18. Anatomia del progetto e contratto di conformità 19. L'interprete di riferimento 20. Il seed in codice macchina 21. Verso il self-hosting 22. Gli strumenti di sviluppo
Appendici
- Riferimento dei builtin Core
- Catalogo conformance Core
- Catalogo conformance Full
- Sorgenti degli esempi
- Sorgenti self-hosted
- Documenti di riferimento
- Indice analitico
Manuale di consultazione