Funzioni Lambda

Le funzioni lambda in Scheme sono funzioni anonime, ovvero sono funzioni senza nome. Queste funzioni sono definite in linea e vengono generalmente utilizzate per operazioni brevi e una tantum. Il costrutto lambda è un potente strumento di programmazione funzionale, che consente di creare al volo una logica concisa e flessibile.

Le funzioni Lambda sono particolarmente utili quando:

  • Hai bisogno di una piccola funzione per uno scopo specifico e temporaneo.
  • Passaggio di funzioni come argomenti a funzioni di ordine superiore come map, filter o fold.
  • Restituzione di funzioni da altre funzioni.

Sintassi delle funzioni Lambda

Le funzioni Lambda possono essere definite autonomamente…

(lambda (parameter1 parameter2 ...)
  body-expression)

…o invocato immediatamente:

((lambda (parameter1 parameter2 ...)
   body-expression)
 argument1 argument2 ...)
  • parameter1, parameter2, ...: I parametri accettati dalla funzione.
  • body-expression: La logica eseguita quando viene chiamata la funzione.
  • Invocazione immediata: La seconda forma mostra un lambda che viene immediatamente chiamato con argomenti.

Esempi di funzioni Lambda

Utilizzo di Lambda per calcoli semplici

((lambda (x y) (+ x y)) 3 5)  ; Restituisce 8

Qui:

  • Viene creata una funzione lambda per aggiungere due numeri (x e y).
  • La funzione viene immediatamente richiamata con gli argomenti 3 e 5.

Funzioni Lambda in linea

L’esempio seguente dimostra come utilizzare for-each sia con una funzione denominata che con una funzione lambda:

Utilizzo di una funzione con nome:

(define (print-item x)
  (lumi-message (number->string x)))

(for-each print-item (list 1 2 3 4))
  • Spiegazione:
    • print-item è una funzione con nome che converte un numero in una stringa (number->string) e lo stampa utilizzando lumi-message.
    • for-each applica print-item a ciascun elemento nell’elenco (1 2 3 4).

Uscita: 1 2 3 4

Utilizzo di una funzione Lambda:

La stessa logica può essere scritta in linea con una funzione lambda, evitando la necessità di una funzione con nome separata:

(for-each (lambda (x) (lumi-message (number->string x)))
  (list 1 2 3 4))
  • Spiegazione:
    • (lambda (x) (lumi-message (number->string x))) definisce una funzione anonima.
    • Questa funzione viene applicata a ciascun elemento dell’elenco (1 2 3 4) da for-each.

Uscita: 1 2 3 4

Funzioni Lambda come argomenti

Le funzioni Lambda vengono spesso passate direttamente a funzioni di ordine superiore come map o filter.

Quadratura di una lista di numeri

(map (lambda (x) (* x x)) '(1 2 3 4))  ; Restituisce (1 4 9 16)
  • La funzione lambda quadra ogni elemento dell’elenco.
  • La funzione map applica lambda a ciascun elemento.

Funzioni Lambda come valori restituiti

Puoi restituire una funzione lambda da un’altra funzione per creare un comportamento dinamico.

Generazione di una funzione sommatrice

(define (make-adder n)
  (lambda (x) (+ x n)))

(define add5 (make-adder 5))
(add5 10)  ; Restituisce 15
  • make-adder genera una nuova funzione lambda che aggiunge un numero specifico (n).
  • Il lambda restituito viene memorizzato in add5, che aggiunge 5 al suo input.

Utilizzo di Lambda con let

I lambda vengono spesso utilizzati con let per creare funzioni temporanee con ambito locale.

Lambda locale per aggiunta

(let ((add (lambda (a b) (+ a b))))
  (add 3 4))  ; Restituisce 7
  • let associa una funzione lambda al nome add.
  • La lambda viene quindi utilizzata come una normale funzione nell’ambito let.

Combinazione di Lambda con funzioni di ordine superiore

I Lambda brillano se combinati con funzioni di ordine superiore per eseguire trasformazioni di dati complesse.

Filtraggio dei numeri pari

(filter (lambda (x) (= (modulo x 2) 0)) '(1 2 3 4 5 6))  ; Restituisce (2 4 6)
  • lambda controlla se un numero è pari.
  • La funzione filter utilizza lambda per mantenere solo i numeri pari dall’elenco.

Vantaggi delle funzioni Lambda

  • Concisione: i Lambda riducono il codice standard eliminando la necessità di definire funzioni con nome separate.
  • Flessibilità: puoi definirli e utilizzarli ovunque siano necessari, rendendo il codice più modulare.
  • Leggibilità migliorata: per attività brevi e specifiche, le lambda rendono chiaro l’intento senza ingombrare il codice con funzioni con nome aggiuntive.

Quando utilizzare le funzioni Lambda

Utilizza le funzioni lambda quando:

  • La logica è breve e autonoma.
  • La funzione è necessaria solo temporaneamente o in un ambito specifico.
  • Stai lavorando con funzioni di ordine superiore come map, filter o reduce.

Evitare di utilizzare lambda per logica complessa su più righe, poiché ciò può ridurre la leggibilità. Per operazioni più estese, utilizzare invece una funzione denominata.

Conclusione

Le funzioni Lambda in Scheme forniscono un modo conciso e potente per definire funzioni anonime per attività specifiche. La loro flessibilità e facilità d’uso li rendono uno strumento essenziale per qualsiasi programmatore di Scheme. Capire come utilizzare lambda in modo efficace ti aiuterà a scrivere script più puliti, più modulari ed efficienti.