0Pricing
Scala for Backend Engineering & Functional Programming · Lezione

La pigrizia spiegata

Calcoli i valori solo quando servono.

La pigrizia spiegata è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Scala for Backend Engineering & Functional Programming, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.

Che cos'è la pigrizia?

In Scala, la maggior parte dei valori è strict: viene calcolata nel momento stesso in cui la definisce. La valutazione lazy cambia questo comportamento. Un valore lazy viene calcolato solo quando serve per la prima volta, mai prima.

È importante quando i calcoli sono costosi, possono fallire o potrebbero non essere mai utilizzati. Perché pagare il costo di un lavoro che nessuno richiede?

val strict

Un normale val valuta immediatamente l'espressione a destra, anche se non lo legge mai più.

Esegua questo codice e noti che "computing" viene stampato prima di "after". Il lavoro avviene al momento della definizione.

object Demo extends App {
  val x = { println("computing"); 42 }
  println("after")
  println(x)
}

lazy val

Anteponendo lazy a un val, la valutazione viene rimandata fino al primo accesso.

Qui "after" viene stampato per primo, poi "computing" solo quando si legge x. Il risultato viene inoltre memorizzato: il corpo viene eseguito al massimo una volta.

object Demo extends App {
  lazy val x = { println("computing"); 42 }
  println("after")
  println(x)
  println(x)
}

Parametri by-name

Un parametro dichiarato come => A viene passato by name: l'argomento non viene valutato finché non viene utilizzato all'interno del metodo.

Questo è il fondamento della valutazione lazy. LazyList usa parametri by-name affinché la coda non venga mai calcolata prima che venga richiesta.

def maybe(cond: Boolean, value: => Int): Int =
  if (cond) value else 0

val r = maybe(false, { println("side"); 99 })
// "side" never prints; value was unused

Alla scoperta di LazyList

LazyList è la sequenza lazy di Scala (dalla versione 2.13+ ha sostituito la precedente Stream). La testa viene valutata eager, mentre la coda è lazy.

Gli elementi vengono prodotti su richiesta e memorizzati dopo il calcolo, quindi la stessa cella non viene mai ricalcolata due volte.

val ll = LazyList(1, 2, 3)
println(ll)
// prints LazyList(<not computed>) until forced

Forzare la valutazione

Una LazyList rimane non valutata finché non la forza. Chiamare toList, foreach o stampare ogni elemento forza le celle.

La REPL mostra <not computed> per la coda lazy. Forzandola vengono rivelati i valori reali.

object Demo extends App {
  val ll = LazyList(1, 2, 3)
  println(ll.toList)
}

L'operatore #::

Si antepone un elemento a una LazyList con #::. A differenza di :: delle liste, l'operando destro di #:: è by-name, quindi la coda non viene costruita finché non serve.

Questo consente di descrivere sequenze la cui parte restante viene calcolata in modo lazy.

val ll = 1 #:: 2 #:: 3 #:: LazyList.empty
println(ll.head)

Memoizzazione

Una volta calcolata una cella di LazyList, il suo valore viene memorizzato. Rileggerlo non ha costi e l'espressione che lo produce non viene eseguita due volte.

Esegua questo codice: "calc" viene stampato solo al primo accesso a ciascun elemento forzato, non nelle letture successive.

object Demo extends App {
  val ll = LazyList(1, 2).map { n =>
    println("calc " + n); n * 10
  }
  println(ll.head)
  println(ll.head)
}

La coda lazy in azione

Poiché la coda è lazy, è possibile applicare map a una LazyList e solo gli elementi che vengono toccati saranno calcolati.

Qui "map" viene stampato una sola volta anche se la lista ha tre elementi, perché viene forzata solo la testa.

object Demo extends App {
  val r = LazyList(1, 2, 3).map { n =>
    println("map " + n); n + 1
  }
  println(r.head)
}

Perché la valutazione lazy è utile

La valutazione lazy consente tre cose: evitare il lavoro inutile, costruire sequenze infinite e separare il modo in cui si descrive un calcolo dalla quantità che ne viene eseguita.

Scrive l'intera pipeline una volta sola; sarà il consumatore a decidere quanti elementi richiedere.

Una precauzione

La valutazione lazy ha dei costi. Una LazyList usa la memoizzazione, quindi mantenere un riferimento alla testa conserva in memoria ogni elemento già forzato. Per dati enormi o infiniti, eviti di conservare la testa.

Inoltre, gli effetti collaterali nel codice lazy vengono eseguiti in momenti inattesi, complicando il debug.

Verifica rapida

Verifichi la sua comprensione della valutazione lazy.

Riepilogo

La valutazione strict esegue il lavoro immediatamente; quella lazy lo rimanda fino a quando serve. lazy val e i parametri by-name (=> A) sono i costrutti fondamentali.

LazyList si basa su di essi: testa eager, coda lazy memoizzata, forzata tramite toList o l'accesso agli elementi. Ora costruiremo LazyList manualmente.

Domande Frequenti

La lezione «La pigrizia spiegata» è gratuita?

Sì — il testo completo di «La pigrizia spiegata» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Scala for Backend Engineering & Functional Programming, passa a CoddyKit PRO. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.

Cosa imparerò in «La pigrizia spiegata»?

Calcoli i valori solo quando servono. Eserciti Scala for Backend Engineering & Functional Programming con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Scala for Backend Engineering & Functional Programming?

Non è richiesta alcuna esperienza precedente. Scala for Backend Engineering & Functional Programming su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «La pigrizia spiegata»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Scala for Backend Engineering & Functional Programming?

Sì. Ogni lezione Scala for Backend Engineering & Functional Programming include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. La pigrizia spiegata
  2. Costruire una LazyList
  3. Stream infiniti
  4. Prelevare e filtrare in modo lazy
← Torna a Scala for Backend Engineering & Functional Programming