Lisp – l’hanno chiamato così per via di List Processing – 3

l12Oggi, continuando da qui finisco di copiare il capitolo, qui.

Funzioni per la manipolazione di liste

Con le cose viste finora siamo in grado di guardare alla libreria di funzioni per la manipolazione delle liste.

Abbiamo già visto le funzioni base per accedere agli elementi di una lista: first e rest. Benché con chiamate successive a rest e first sia possibile accedere a ogni elemento della lista questo è noioso; il Lisp fornisce funzioni per questo, nominate secondo gli ordinali: da second fino a tenth. Più in generale nth prende 2 argomenti, un indice e una lista e ritorna l’ennesimo elemento (zero based) della lista. Allo stesso modo nthcdr con un indice e una lista ritorna il cdr della lista a partire da quell’indice, quindi (nthcdr 0 ...) ritorna la lista originale, (nthcdr 1 ...) ritorna rest e così via. Tuttavia nessuna di queste funzioni è più efficiente che chiamare combinazioni di firsts e rests —there’s no way to get to the nth element of a list without following n cdr references, dice Peter.

Le 28 funzioni composte car/cdr sono un’altra famiglia di funzioni che possono essere usate. Ogni funzione si chiama con una sequenza di A e D tra C e R rappresentanti A una chiamata a car e D a cdr, quindi:

(caar list) === (car (car list))
(cadr list) === (car (cdr list))
(cadadr list) === (car (cdr (car (cdr list))))

Notare che parecchie di queste funzioni hanno senso solo per liste contenenti liste. per esempio caar estrae il car del car della lista data che quindi deve contenere una lista come suo primo elemento. In altre parole queste sono funzioni per alberi (trees) più che per liste:

l12-12

Oggi sono molto meno usate di una volta (ricordo perfettamente 🙄 cioè quasi).

Le firsttenth e car, cdr e famiglia possono essere usate come setf-abili.

Una tabella che riassume altre funzioni per le liste non esaminate in dettaglio:

Function    Description
last        Returns the last cons cell in a list. With an integer, 
            argument returns the last n cons cells.
butlast	    Returns a copy of the list, excluding the last cons cell. 
            With an integer argument, excludes the last n cells.
nbutlast    The recycling version of BUTLAST; may modify and return 
            the argument list but has no reliable side effects.
ldiff       Returns a copy of a list up to a given cons cell.
tailp       Returns true if a given object is a cons cell that's part 
            of the structure of a list.
list*       Builds a list to hold all but the last of its arguments 
            and then makes the last argument the CDR of the last cell 
            in the list. In other words, a cross between list and append.
make-list   Builds an n item list. The initial elements of the list are nil
            or the value specified with the :initial-element keyword argument.
revappend   Combination of reverse and append; reverses first argument 
            as with reverse and then appends the second argument.
nreconc	    Recycling version of REVAPPEND; reverses first argument as if 
            by nreverse and then appends the second argument. 
            No reliable side effects.
consp       Predicate to test whether an object is a cons cell.
atom        Predicate to test whether an object is not a cons cell.
listp       Predicate to test whether an object is either a cons cell or nil.
null        Predicate to test whether an object is nil. Functionally
            equivalent to NOT but stylistically preferable when testing 
            for an empty list as opposed to boolean false.

Mappatura

Un altro aspetto dello stile funzionale è l’uso di funzioni di ordine superiore (higher-order), funzioni che prendono altre funzioni come argomenti o ritornano funzioni come valori. Ne abbiamo già viste parecchie, come map. Benché map possa essere usata sia con vettori che liste (cioè con le sequenze) Common Lisp fornisce sei funzioni di mappatura specifiche per le liste. Le differenze tra queste sei funzioni riguardano come costruiscono i loro risultati e se applicano i le funzioni agli elementi della lista o alle cons cells della struttura della lista.

mapcar è la funzione più simile a map. Siccome torna sempre una lista non richiede il result-type che map vuole. Invece il suo primo argomento è la funzione che dev’essere applicata e i susseguenti argomenti sono le liste i cui elementi  saranno passati alla funzione. Insomma, funziona come map:

l12-13

maplist è simile a mapcar ma invece di passare gli elementi della lista alla funzione passa le cons cells. È più primitiva, ha accesso non solo ai cars ma anche ai cdrs delle celle.

mapcan e mapcon fanno le stesse cose di mapcar e maplist costruendo una lista interamente nuova unendo i risultati; quindi ogni invocazione a funzione  può fornire ogni numero di elementi che saranno inclusi nei risultati (non ho capito niente, nada, zilch!). Esempio:

(mapcan #'(lambda (x) (if (= x 10) nil (list x)))  list)

rimuove 10 dalla lista list.

Infine mapc e mapl sono costrutti di controllo che sembrano funzioni; ritornano il loro primo argomento e sono utili soltanto quando i side effects delle funzioni mappate hanno qualcosa d’interessante. Sono io che sto crescendo per l’aspetto rinko o stiamo entrando in un universo parallelo? 👿

Altre strutture

Cons cells e liste sono tipicamente considerate equivalenti ma queste possono essere usate per rappresentare alberi (trees). Ci sono funzioni per rappresentare alberi, sets e mappe di tipo key/value. Prossimamente, temo :mrgreen:

Posta un commento o usa questo indirizzo per il trackback.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: