Lezione 7 di 7 · 15 min di lettura

Riepilogo e sfida finale

Tutto il modulo in una pagina, un quiz di controllo e un programma completo da scrivere da zero.

Guarda quanta strada

Sei lezioni fa non avevi nemmeno il compilatore. Adesso sai:

  • installare Gleam ed Erlang, creare un progetto ed eseguirne i moduli;
  • leggere un programma Gleam riga per riga, sapendo cosa fa ogni parola;
  • dare un nome ai valori con let e const, sapendo che nessuno li cambierà mai;
  • distinguere Int, Float, String e Bool, e convertire dall’uno all’altro quando serve;
  • fare calcoli senza cadere nella divisione intera, e senza mescolare interi e decimali;
  • porre domande con i confronti e combinarle con la logica;
  • costruire esattamente il testo che vuoi, con il tubo |>, i decimali giusti e le colonne allineate.

Non è poco. Sono le fondamenta su cui poggia tutto il resto del corso, e per questo motivo vale la pena consolidarle prima di andare avanti.

La pagina da tenere accanto

Questa tabella riassume tutta la sintassi del modulo. Tienila aperta mentre fai la sfida, e torna qui ogni volta che ti serve. (Trovi tutto anche nel Codex: il bottone in basso a destra, o il tasto K.)

CosaCome si scrive
Nuovo progettogleam new nome
Eseguiregleam run oppure gleam run -m modulo
Controllare / formattaregleam check, gleam format
Importare un moduloimport gleam/io
Punto d’ingressopub fn main() -> Nil { ... }
Stampare (a capo)io.println("testo")
Stampare per il debugecho valore
Variabilelet age = 34
Nuovo valore, stesso nomelet age = age + 1
Annotazione di tipolet age: Int = 34
Costanteconst vat_rate = 0.22
TipiInt, Float (2.0), String, Bool (True/False), Nil
Aritmetica intera+ - * / %, con / che taglia i decimali e x / 0 == 0
Aritmetica decimale+. -. *. /.
Confronti< > <= >= (con il punto per i Float), == !=
Logica&& \|\| !
Raggruppare{ 1 + 2 } * 3
Attaccare stringhe"a" <> "b"
Convertireint.to_string, float.to_string, bool.to_string, int.to_float, float.round, float.truncate
Il tubox \|> f(a) equivale a f(x, a)
Allinearestring.pad_start, string.pad_end, string.repeat
Commenti// riga, /// documenta la definizione, //// documenta il modulo

Le regole dei nomi, in una riga

variabile_funzione_costante_modulo in snake_case, TipoDefinito in PascalCase. Se te le ricordi, il compilatore ti lascerà in pace. (E se te le scordi, te le ricorderà lui, con tanto di Try: my_name.)

Quiz di controllo

Tre domande che mescolano tutto. Se le sbagli, non è grave: la spiegazione ti dice in quale lezione tornare.

Quiz

Cosa stampa io.println(float.to_string(int.to_float(10 / 4)))?

Quiz

Quale riga compila senza errori?

Quiz

Con let x = 5, quanto vale x % 2 == 1 && x > 3 || x == 0?

La sfida: cronaca di una maratona

Ora un programma intero, da zero, senza copiare. Usa tutto quello che sai: costanti, variabili, conversioni, divisione intera e resto, operatori sui Float, confronti e costruzione del testo.

Esercizio · sul tuo computer

Cronaca di una maratona

Nel progetto exercises crea src/marathon.gleam. Un’atleta ha corso una maratona in 3 ore, 45 minuti e 30 secondi. La distanza della maratona è 42 195 metri: mettila in una costante Int chiamata distance_m.

Il programma deve calcolare e stampare, in questo ordine:

  1. la distanza in chilometri, come Float (metri diviso 1000, con gli operatori giusti);
  2. il tempo nel formato 3h 45m 30s, seguito tra parentesi dal totale in secondi;
  3. la velocità media in km/h, arrotondata a 2 decimali con float.to_precision (chilometri diviso ore; le ore sono i secondi totali diviso 3600, in decimale);
  4. il passo, cioè quanti secondi servono per un chilometro, espresso come 5 min 20 s per km: calcola i secondi totali diviso i chilometri, troncalo a intero con float.truncate, poi usa / 60 e % 60;
  5. se il tempo è sotto le 4 ore, come Bool convertito in testo.

L’output atteso, carattere per carattere:

output
Distance: 42.195 km
Time: 3h 45m 30s (13530 seconds)
Average speed: 11.23 km/h
Pace: 5 min 20 s per km
Under 4 hours: True

Suggerimento: parti da let hours = 3, let minutes = 45, let seconds = 30 e calcola il totale in secondi come hours * 3600 + minutes * 60 + seconds. Per la velocità ti servirà un paio di graffe, per fare la divisione per 3600 prima dell’altra.

Mostra una soluzione (prima prova da solo!)
src/marathon.gleam
import gleam/bool
import gleam/float
import gleam/int
import gleam/io

const distance_m = 42_195

pub fn main() -> Nil {
  let hours = 3
  let minutes = 45
  let seconds = 30
  let total_seconds = hours * 3600 + minutes * 60 + seconds

  let km = int.to_float(distance_m) /. 1000.0
  let speed = km /. { int.to_float(total_seconds) /. 3600.0 }
  let pace = float.truncate(int.to_float(total_seconds) /. km)

  io.println("Distance: " <> float.to_string(km) <> " km")
  io.println(
    "Time: "
    <> int.to_string(hours)
    <> "h "
    <> int.to_string(minutes)
    <> "m "
    <> int.to_string(seconds)
    <> "s ("
    <> int.to_string(total_seconds)
    <> " seconds)",
  )
  io.println(
    "Average speed: "
    <> speed |> float.to_precision(2) |> float.to_string
    <> " km/h",
  )
  io.println(
    "Pace: "
    <> int.to_string(pace / 60)
    <> " min "
    <> int.to_string(pace % 60)
    <> " s per km",
  )
  io.println("Under 4 hours: " <> bool.to_string(total_seconds < 4 * 3600))
}

Qualche dettaglio da notare:

  • distance_m è un Int, quindi prima di dividerlo con /. va convertito con int.to_float.
  • Nella velocità, le graffe fanno calcolare le ore (total_seconds / 3600, in decimale) prima della divisione dei chilometri.
  • Il passo esatto sarebbe 320,65 secondi: float.truncate lo taglia a 320, che fanno 5 minuti (320 / 60) e 20 secondi (320 % 60).
  • Nella riga della velocità il tubo lavora dentro una catena di <>: siccome |> viene prima di <>, non servono graffe.

Cosa succede nel Modulo 2

Finora i nostri programmi sono andati sempre dritti, dalla prima riga all’ultima. Nel prossimo modulo impareremo a far prendere decisioni al programma e a ripetere le cose. In Gleam non esistono if, for e while come in altri linguaggi: al loro posto ci sono strumenti più potenti, come le espressioni case e il pattern matching, e la ricorsione. E impareremo finalmente a scrivere funzioni nostre, così lo scontrino della lezione precedente diventerà la metà.