Continuiamo il nostro studio di Scheme analizzando un altro elemento fondamentale della programmazione Lisp: la manipolazione delle liste. Come abbiamo visto in precedenza in Scheme tutto ciò che non è un atomo (numeri, stringhe, caratteri e altri tipi base) è una lista, appare quindi chiara l’importanza che riveste la loro manipolazione nella programmazione funzionale.
Per fare ciò analizzaremo quella manciata di comandi che ci permettono di fare tutto.
CAR e CDR
Questi sono i due comandi principali. Grazie a questi comandi possiamo già fare praticamente tutto. I comandi che vedremo successivamente possono benissimo essere ricreati usando solo CDR e CAR (e CONS). Nei nostri esempi considereremo una lista di numeri (1 2 3 4 5 6).
Tengo a precisare che indicare una lista così:
'(1 2 3 4 5 6)
è del tutto equivalente all’uso del comando list.
(list 1 2 3 4 5 6)
EFFETTI:
- CAR estrae il primo elemento della lista passata per argomento.
ESEMPIO:(car '(1 2 3 4 5 6)) restituisce 1
- CDR ritorna la lista formata dalla lista passata per argomento senza il primo elemento.
ESEMPIO:(cdr '(1 2 3 4 5 6) restituisce (2 3 4 5 6)
Questi comandi inoltre godono di una proprietà particolare. Possono essere composti a piacimento inserendo una A per ogni CAR e
una D per ogni CDR nella parola C*R. Detto così sembra complicato, in realtà è però molto semplice. Facciamo un esempio.
- (CADR lista) equivale a (CAR (CDR lista)).
- (CADDR lista) equivale a (CAR (CDR (CDR lista))).
- (CDADR lista) equivale a (CDR (CAR (CDR (CAR lista)))).
In queste composizioni è però necessario considerare il risultato di ogni applicazione. Sia CAR che CDR prendono come argomento una lista ma mentre CDR restituisce sempre una lista CAR restituisce una lista SE E SOLO SE la lista che gli viene data è una lista di liste.
Questo è causa di errori. Infatti non si può fare il CAR/CDR di un elemento.
Confusi? E’ normale. Ci vuole un po per afferrare questi concetti ma risulteranno molto intuitivi dopo un po di applicazioni.
CONS
Cons è un altro comando essenziale. Questo comando la cui sintassi è
(CONS arg1 arg2)
Non fa altro che inserire in testa alla lista arg2 l’elemento arg1.
APPEND
Append è un altro comodo comando la cui sintassi è identica a quella di CONS.
(APPEND arg1 arg2)
Questo comando però serve a concatenare due liste dando come risultato una lista contenente prima tutti gli elementi di arg1 e poi tutti gli elementi di arg2.
REVERSE
Ultimo comando che userete spesso è Reverse. Questo comando inverte semplicemente l’ordine degli elementi all’interno della lista. Ad esempio:
(REVERSE '(1 2 3)) restituisce (3 2 1)
RICAPITOLANDO
- CAR estrae il primo elemento di una lista.
- CDR restituisce la lista senza il primo elemento.
- CAR si applica solo a LISTE e il suo risultato è un ELEMENTO o una LISTA
- CDR si applica solo a LISTE e il suo risultato è sempre una LISTA.
- CAR e CDR possono combinarsi in comandi come CADR o CADDDDR in cui ogni A indica un CAR e ogni D indica un CDR.
- CONS inserisce un elemento in testa ad una lista.
- APPEND concatena due liste.
- REVERSE inverte l’ordine degli elementi di una lista.
ESERCIZI E SPUNTI DI RIFLESSIONE
Lascio qui di seguito alcuni “esercizi” per mettere alla prova la comprensione di questa lezione.
- Esprimere in un comando CAR/CDR una funzione che estrae il secondo elemento della seconda lista di questa lista ( (0 2) (4 3 2) (9 9 9) 9 ).
- Date le due list LIST1 = (1 2 3) e LIST2 = (4 5 6) riflettere sulla differenza fra (CONS LIST1 LIST2) e (APPEND LIST1 LIST2).
La prossima volta vedremo come affrontare decisioni e condizioni. Comincieremo cioè a scrivere le prime funzioni complete e funzionali.
Siccome seguo da poco (due giorni) può darsi che chieda una cosa già nota a tutti ma comunque…
Quale versione conviene installare? Nella Gestione pacchetti di Ubuntu ne esistono più di una.
Poi, per farmi perdonare: in Scheme tutto è una lista, e gli atomi (del Lisp)?
fin qui ti seguo…