Perché si deve cons con un null per ottenere una lista adeguata nello schema?

StackOverflow https://stackoverflow.com/questions/1689812

  •  18-09-2019
  •  | 
  •  

Domanda

Mi rendo conto che questa è una domanda n00b totale, ma sono curiosa e ho pensato che avrei potuto ottenere una spiegazione migliore qui che altrove. Ecco un elenco (sto usando Dr. Scheme)

> (list 1 2 3)
(1 2 3)

Che credo è solo zucchero per questo:

> (cons 1 (cons 2 (cons 3 null)))
(1 2 3)

Questo, d'altra parte, fa qualcosa di diverso:

> (cons 1 (cons 2 3))
(1 2 . 3)

Le mie domande è, perché è così diversa? Qual è il punto di richiedere il nulla alla fine della lista?

È stato utile?

Soluzione

La definizione di una lista è ricorsivo.

 1. The null list (empty list) is a list
 2. A list is made up of an item cons a list

Quindi, queste sono le liste:

1. null  => ()  --read as empty list
2. cons 3 null  =>  (3)
3. cons2 (cons 3 null)  => (2, 3) 

L'ultimo esempio ti ha dato contro 2 3 non è conforme a questa definizione lista quindi non è un elenco. Questo è contro accetta una voce e una lista. 3 non è un elenco.

Altri suggerimenti

cons aggiunge un nuovo elemento all'inizio di una lista, in modo da quello che stai facendo quando si scrive:

(cons 1 (cons 2 (cons 3 null)))

è ricorsivamente Aggiunta di elementi a un elenco sempre crescente, iniziando con null, che è definito come il vuoto-list (). Quando si chiama (cons 2 3) che non stai iniziando con la lista vuota per cominciare, quindi non sono la costruzione di una lista aggiungendo 2 al suo inizio.

Lisps, ivi compreso il regime, sono dinamicamente tipizzati, e 'il modo in cui lisp' è quello di avere molte funzioni su una singola struttura di dati piuttosto che diverse strutture di dati per compiti diversi.

Quindi la domanda "Qual è il punto di richiedere il nulla alla fine della lista?" non è proprio quello giusto di chiedere.

La funzione cons non richiede di dare un oggetto cons o nil come secondo argomento. Se il secondo argomento non è un oggetto cons o nil, allora si ottiene una coppia piuttosto che una lista, e il runtime non stamparlo utilizzando la notazione lista, ma con un punto.

Quindi, se si vuole costruire qualcosa che ha la forma di una lista, poi dare cons una lista come secondo argomento. Se si vuole costruire qualcosa di diverso, poi dare qualcosa cons altro come secondo argomento.

Le coppie sono utili se si desidera una struttura di dati che ha esattamente due valori in esso. Con una coppia, non è necessario il nulla, alla fine per marcare la sua lunghezza, quindi è un po 'più efficiente. Un elenco di coppie è una semplice implementazione di una mappa di chiave valore; Common Lisp ha funzioni a sostegno di tali elenchi di proprietà come parte della sua libreria standard.

Quindi la vera domanda è "perché è possibile costruire entrambe le coppie e le liste con la stessa funzione cons?", E la risposta è "perché avere due strutture di dati quando hai solo bisogno di uno?"

A cons istruzione viene utilizzata per allocare una coppia la cui auto è obj1 e la cui cdr è obj2

(cons obj1 obj2)

Pertanto, è necessario porre fine una dichiarazione contro con un null in modo che sappiamo che siamo alla fine della lista.

> (cons 1 (cons 2 3))
(1 2 . 3)

In questo esempio, il CDR sarebbe una coppia <2,3> dove 2 è la macchina e 3 è CDR. Non è la stessa:

(list 1 2 3)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top