0Pricing
Scala for Backend Engineering & Functional Programming · Lezione

Basi delle macro

Codice in fase di compilazione

Basi delle macro è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 2 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'è una macro?

Una macro è codice che viene eseguito a tempo di compilazione per generare altro codice. Le macro di Scala 3 consentono di ispezionare gli argomenti, costruire espressioni e inserirle nel programma prima della compilazione.

Schema inline + macro

Una macro viene invocata da un inline def che delega a un metodo contrassegnato con ${ ... }. L'inline def è l'API pubblica; l'implementazione della macro viene eseguita dal compilatore.

import scala.quoted.*

inline def power(x: Double, inline n: Int): Double =
  ${ powerImpl('x, 'n) }

Il contesto Quotes

Ogni implementazione di macro riceve un contesto implicito Quotes. Esso fornisce accesso all'API di reflection e la possibilità di costruire e inserire espressioni.

import scala.quoted.*

def powerImpl(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] =
  ???

Expr[T]

Expr[T] rappresenta un'espressione tipizzata di tipo T come dato a tempo di compilazione. Le macro ricevono e restituiscono valori Expr.

Elevare valori a Expr

Expr(value) eleva un valore di runtime calcolato nella macro a un'espressione da reinserire. Funziona per qualsiasi tipo con un'istanza di ToExpr.

import scala.quoted.*

def constImpl(using Quotes): Expr[Int] = Expr(42)

Estrarre argomenti costanti

n.value (o n.valueOrAbort) estrae la costante contenuta in un Expr quando l'argomento è noto staticamente, consentendo alla macro di scegliere un ramo in base a essa.

import scala.quoted.*

def powerImpl(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] = {
  val exp = n.valueOrAbort
  ??? // build x*x*...*x exp times
}

Segnalazione degli errori

Usi quotes.reflect.report.errorAndAbort per emettere un errore di compilazione con messaggio e posizione quando i prerequisiti della macro non sono soddisfatti.

import scala.quoted.*

def check(n: Expr[Int])(using q: Quotes): Expr[Int] = {
  import q.reflect.*
  val v = n.valueOrAbort
  if (v < 0) report.errorAndAbort("must be >= 0")
  Expr(v)
}

Dove risiedono le macro

Le implementazioni delle macro devono essere compilate prima del codice che le usa, in genere in un file o modulo separato. Il compilatore le esegue durante la compilazione del chiamante.

Casi d'uso comuni

Le macro consentono:

  • la derivazione di typeclass (codec JSON e così via)
  • la convalida a tempo di compilazione (regex, SQL)
  • il logging che cattura le posizioni nel codice sorgente
  • astrazioni a costo zero

Sicurezza e igiene

Le macro di Scala 3 sono hygienic: gli identificatori generati non possono catturare accidentalmente le variabili dell'utente e il sistema dei tipi verifica il codice generato, prevenendo molti bug classici delle macro.

Equivalente a runtime

Una macro che calcola una potenza a tempo di compilazione produce lo stesso risultato di questa versione autosufficiente a runtime, ma con le moltiplicazioni incorporate dal compilatore.

object Main {
  def power(x: Double, n: Int): Double =
    if (n == 0) 1.0 else x * power(x, n - 1)
  def main(args: Array[String]): Unit = {
    println(power(2.0, 3)) // 8.0
  }
}

Verifica rapida

Quale tipo rappresenta un'espressione tipizzata a tempo di compilazione che le macro ricevono e restituiscono?

Riepilogo

Ha appreso i fondamenti delle macro:

  • le macro vengono eseguite a tempo di compilazione tramite lo schema inline def ... ${ }
  • il contesto Quotes e Expr[T]
  • l'elevamento con Expr(...) e l'estrazione con .value
  • segnalazione degli errori e igiene

Prossimo argomento: quotes e splice.

Domande Frequenti

La lezione «Basi delle macro» è gratuita?

Sì — il testo completo di «Basi delle macro» è 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 «Basi delle macro»?

Codice in fase di compilazione 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 2 di 4.

Quanto tempo richiede la lezione «Basi delle macro»?

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. Metodi inline
  2. Basi delle macro
  3. Quote e splice
  4. Macro pratiche
← Torna a Scala for Backend Engineering & Functional Programming