2016-04-08 47 views
5

Ricco di funzioni vettoriali, mappe e impostazioni, mentre l'elenco e la sequenza non sono funzioni. Perché non tutte queste raccolte possono essere funzionali per renderla coerente?Perché il progettista ha realizzato vettori, mappe e set di funzioni in clojure?

Inoltre, perché non facciamo tutti questi dati di composizione come una funzione che mappa la posizione dei suoi dati interni?

Se facciamo tutti questi dati di comporre come funzione, allora ci saranno solo i dati di funzione e di atomo in clojure. Questo minimizzerà gli elementi fondamentali in quel linguaggio, giusto?

Credo che un minimo, il migliore solo 2, insieme di elementi fondamentali renderebbe il linguaggio più semplice, più espressivo e più flessibile. È corretto?

+0

C'è una differenza tra un elenco e una sequenza? –

+0

Benvenuti in StackOverflow, È difficile rispondere alle domande sullo stato della mente di qualcun altro in un modo che sarà possibile contrassegnare come "corretto" o "errato", quindi è difficile rispondere obiettivamente a questa domanda. –

+0

La sequenza @BobJarvis è un'interfaccia implementata da tutti i tipi di raccolta, inclusa la lista. –

risposta

9

I vettori, le mappe e gli insiemi sono tutte strutture di dati associative. Le mappe sono le più ovvie; semplicemente associano chiavi arbitrarie a valori arbitrari. Un vettore può essere pensato come una mappa il cui set di chiavi deve essere l'insieme di tutti gli interi non negativi meno della dimensione del vettore. Infine, le serie possono essere pensate come mappe che mappano le chiavi a se stesse.

È importante capire che la natura sequenziale di un vettore e la natura associativa di un vettore sono due cose ortogonali. Si tratta di una struttura dati progettata per essere efficace nel supportare entrambe le astrazioni (in una certa misura, ad esempio, non è possibile inserire in modo efficiente all'inizio di un vettore).

Le liste sono più semplici dei vettori; sono strutture di dati sequenziali finite, niente di più. Un elenco non può restituire in modo efficiente l'elemento in un particolare indice, quindi non espone tale funzionalità come parte della sua interfaccia principale. Ovviamente, è possibile ottenere un elemento di un elenco per indice utilizzando nth, ma in tal caso lo si considera esplicitamente come sequenza, non come struttura associativa.

Quindi, per rispondere alla tua domanda, le implementazioni IFn per vettori, mappe e insiemi ci sono a causa della relazione estremamente stretta tra l'idea di una struttura di dati associativa e l'idea di una funzione pura. Le liste e le altre sequenze non sono intrinsecamente associative, quindi per coerenza non implementano IFn.

+0

Ho controllato che la proprietà del set in Clojure sembra non sia una struttura associativa. Esegui: (aggiornamento # {1 2} 1 inc) si otterrà un'eccezione: PersistentHashSet non può trasmettere a clojure.lang.Associative – Shark

+0

@Shark Con "associative", non intendevo letteralmente "l'implementazione di ['Associazione"] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Associative.java) interfaccia "; piuttosto, ho semplicemente inteso che supportano efficientemente le query dalle chiavi ai valori. In Clojure, le serie sono state gestite come [un caso speciale] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L746-L749), ma questo non cambia il fatto che supportano intrinsecamente una ricerca efficiente e gli elenchi no. –

+0

grazie per avermi mostrato il codice sorgente. Ora posso dire che è un difetto nella definizione del tipo di Set in clojure? Supponiamo di implementare Associative per renderlo consistente? – Shark

2

La risposta di Elogent è eccellente. C'è una ragione in più che non avrebbe senso che le liste fossero funzioni:

Gli elenchi letterali hanno già un ruolo diverso, molto importante, quindi non possono essere trattati come funzioni nel modo in cui i vettori sono.

Iniziamo con un vettore contenente due funzioni, partial e + e un numero, 5. Siamo in grado di trattare il vettore come una funzione, come sapete, per restituire il valore indicizzato da suo argomento:

user=> ([partial + 5] 2) 
5 

Fin qui, tutto bene. Supponiamo di voler utilizzare un elenco (partial + 5) al posto del vettore, come suggerito, per restituire il valore 5. Verrà visualizzato un messaggio di errore? No! Ma non avremo 5 come risultato, sia:

user=> ((partial + 5) 2) 
7 

Che cosa è successo? (partial + 5) ha restituito una funzione, la funzione che aggiunge 5 al suo singolo argomento, e quindi questa funzione è stata applicata all'argomento 2.

Quando una lista viene valutata, il suo primo elemento viene valutato e deve restituire una funzione. Se il primo elemento è un simbolo, viene valutato e quindi la funzione che ne è il valore viene applicata agli argomenti, che sono gli altri elementi dell'elenco. Se il primo argomento di una lista è esso stesso una lista, allora viene valutato nello stesso modo in cui sarebbe valutato se fosse al livello più alto. L'intera espressione in quell'elenco interno dovrebbe restituire una funzione, che verrà quindi applicata agli altri elementi dell'elenco esterno.

Poiché un elenco interno che è il primo elemento della lista che viene valutato ha già questo ruolo, non può anche giocare il tipo di ruolo giocato dai vettori che sono i primi elementi.

+0

Penso che tu debba cambiare il tuo demone a ('(parziale + 5) 2) – Shark

+0

Non intendevo che fosse citato, e se lo fosse, il codice che ho dato non avrebbe fatto quello che ho detto. Ma hai un buon punto: cosa è analogo a '([: a: b] 1)', o '('[: a: b] 1)', è '(' (: a: b) 1)', che genera un errore. Quindi penso che la risposta di Elogent sia pertinente, specialmente riguardo all'efficienza. L'accesso a una voce di vettore è veloce; comporta l'indicizzazione o un altro metodo veloce. L'accesso a mappe e insiemi è veloce perché usano l'hashing. Questi accessi implicano un semplice calcolo, come una semplice funzione. L'accesso alle liste è lento perché può coinvolgere un puntatore dopo l'altro, più e più volte. – Mars

Problemi correlati