Lezione 3 di 7 · 12 min di lettura

Il laboratorio

Cosa c'è nella cartella learn-mojo, a cosa servono pyproject.toml e uv.lock, come si aggiorna Mojo e quali comandi mette a disposizione lo strumento mojo.

Una cartella, tre file e un ambiente

Nella prima lezione hai creato il laboratorio con due comandi, uv init --bare learn-mojo e uv add mojo. Aggiunti i programmi della lezione scorsa, la cartella contiene questo:

output
learn-mojo/
├── .venv/            # the environment: compiler, standard library, tools
├── pyproject.toml    # what the project needs
├── uv.lock           # the exact versions that were installed
├── greeting.mojo
├── hello             # the executable built by mojo build
└── hello.mojo

Mojo non ha (ancora) un gestore di progetti suo: prende in prestito quelli dell’ecosistema Python, uv o pixi, e si installa come un normale pacchetto. È una scelta coerente con il suo obiettivo di vivere accanto a Python: nello stesso ambiente potrai aggiungere NumPy o qualsiasi altra libreria Python e chiamarla dal tuo codice Mojo.

pyproject.toml: cosa serve al progetto

pyproject.toml
[project]
name = "learn-mojo"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = [
    "mojo>=1.1.0",
]

È il file di configurazione standard dei progetti Python. A noi interessa la lista dependencies: uv add mojo ha aggiunto la riga "mojo>=1.1.0", cioè “serve Mojo, versione 1.1.0 o successiva”. La riga requires-python dipende dal Python che uv ha trovato sul tuo computer: Mojo non lo usa per compilare, ma serve all’ambiente e all’integrazione con Python.

uv.lock: cosa è stato installato davvero

pyproject.toml dice cosa ti serve in generale; uv.lock registra le versioni esatte che uv ha scelto e scaricato, con le loro impronte digitali (hash). Il pacchetto mojo, a sua volta, si porta dietro alcune dipendenze: il compilatore vero e proprio (mojo-compiler), la libreria standard precompilata, il debugger e il formattatore. Puoi vedere l’albero con:

terminale
uv tree
output
learn-mojo v0.1.0
└── mojo v1.1.0
    ├── mblack v26.6.0
    │   ├── click v8.5.0
    │   ├── mypy-extensions v1.1.0
    │   ├── pathspec v1.1.1
    │   └── platformdirs v4.12.0
    ├── mojo-compiler v1.1.0
    │   └── mojo-compiler-mojo-libs v1.1.0
    └── mojo-lldb-libs v1.1.0

uv.lock non si scrive a mano. Se condividi il progetto (per esempio su Git), includilo: chi lo scarica e lancia uv sync otterrà esattamente le tue stesse versioni, e un esempio che compila da te compilerà anche da lui.

Dettagli nerd Cosa significa >=1.1.0? (il versionamento semantico)

Un numero di versione come 1.1.0 segue quasi sempre il versionamento semantico (semver): MAGGIORE.MINORE.PATCH. La patch sale per le correzioni di bug, la minore per le novità compatibili con il passato, la maggiore quando qualcosa si rompe: codice scritto per la 1.x potrebbe non compilare con la 2.0.

Mojo segue il semver dalla versione 1.0, ma con una precisazione importante nella sua documentazione: sono stabili il linguaggio e le parti della libreria standard esplicitamente marcate come stabili. Il resto della libreria può ancora cambiare tra una versione minore e l’altra. Ecco perché questo corso dichiara la versione con cui è stato verificato.

.venv: dove vive Mojo

La cartella nascosta .venv è l’ambiente virtuale del progetto: una piccola installazione isolata, che non tocca il resto del sistema. Dentro .venv/bin ci sono i comandi (mojo, il language server mojo-lsp-server per l’editor, il debugger mojo-lldb…), e in profondità ci sono il compilatore e la libreria standard, distribuita già compilata in un unico file std.mojoc. In tutto sono circa 700 MB: per questo conviene un solo progetto per tutto il corso, invece di uno per esercizio.

source .venv/bin/activate non fa altro che mettere .venv/bin in testa al PATH del terminale corrente, e deactivate lo toglie.

Dettagli nerd Cos'è il PATH?

Quando scrivi mojo nel terminale, la shell (il programma che interpreta i tuoi comandi) non cerca in tutto il disco: scorre una lista di cartelle, in ordine, e lancia il primo eseguibile con quel nome che trova. Quella lista è la variabile d’ambiente PATH, una stringa di cartelle separate da :. Puoi vederla con echo $PATH, e scoprire quale mojo verrà lanciato con which mojo: con l’ambiente attivo risponde .../learn-mojo/.venv/bin/mojo.

Ogni terminale ha la sua copia del PATH, letta all’avvio: per questo l’attivazione va ripetuta in ogni terminale nuovo, e un terminale aperto prima di un’installazione non la vede.

I comandi di mojo

Lo strumento mojo ha pochi comandi, ognuno con un compito preciso. Quelli che userai più spesso:

ComandoCosa fa
mojo file.mojoCompila ed esegue il file (forma breve di mojo run file.mojo).
mojo build file.mojoCompila un eseguibile nativo, senza eseguirlo. Con -o nome scegli il nome del file.
mojo format file.mojoRiformatta il file nello stile ufficiale. Accetta anche una cartella intera: mojo format .
mojo doc file.mojoEstrae le docstring in formato JSON, da cui si genera la documentazione.
mojo debug file.mojoAvvia il programma nel debugger (LLDB).
mojo --versionStampa la versione del compilatore.

Ogni comando ha il suo aiuto dettagliato: mojo build --help, mojo format --help e così via. Esiste anche un REPL (lanci mojo senza argomenti e scrivi codice riga per riga), ma la documentazione avverte che ha problemi noti e non è in sviluppo attivo: in questo corso lavoriamo sempre con i file.

Quiz

Hai finito un programma di simulazione che dovrai lanciare cento volte con dati diversi. Qual è il flusso più sensato?

Un file per esercizio

Da qui in avanti, ogni esempio e ogni esercizio del corso è un file .mojo nella cartella learn-mojo, con il nome indicato nella scheda sopra il codice (per esempio add.mojo). Ogni file ha la sua main ed è un programma indipendente: lo esegui con mojo nome.mojo e non disturba gli altri. Più avanti vedremo come un file possa usare funzioni e tipi definiti in un altro, e come organizzare un programma più grande in moduli e pacchetti.

Esercizio · sul tuo computer

Un secondo programma

  1. Nella cartella learn-mojo crea il file second.mojo, che stampi Running a second program!.
  2. Lancia mojo format . e controlla che il file non sia cambiato (o guarda cosa ha cambiato).
  3. Compilalo con mojo build second.mojo ed esegui ./second.

Copia qui l’output dell’eseguibile.

Mostra una soluzione (prima prova da solo!)
second.mojo
def main():
    print("Running a second program!")

Ricapitolando

  • Mojo si installa come pacchetto Python: il laboratorio learn-mojo è un progetto uv con dentro pyproject.toml, uv.lock e l’ambiente .venv.
  • pyproject.toml dichiara che serve mojo>=1.1.0; uv.lock registra le versioni esatte; uv tree mostra le dipendenze.
  • .venv contiene compilatore, libreria standard e strumenti (circa 700 MB): si attiva con source .venv/bin/activate, che modifica il PATH.
  • uv sync --upgrade-package mojo aggiorna Mojo.
  • Comandi: mojo file.mojo (compila ed esegue), mojo build (eseguibile), mojo format (stile ufficiale), mojo doc, mojo debug.
  • mojo build --emit asm mostra l’assembly generato.

Nella prossima lezione entriamo nel linguaggio vero e proprio: variabili, tipi e il modo in cui Mojo li usa per essere veloce.