Ci sono buone abitudini che possono mitigare la conflazione dei tipi di strutture di lista in pratica?

-1

Inizierò spiegando cosa intendo in particolare.

Sfondo

In Javascript, gli array fanno tutto (più o meno un tratto Lispy). Non solo puoi inizializzare, spingere e far apparire, ma puoi anche scorrere, filtrare, ridurre, trasmettere e così via. Puoi anche controllare includes (contiene), e con l'overload fornito da librerie enormi come lodash, il cielo è il limite.

La musica si interrompe quando arrivi a un linguaggio strongmente tipizzato come Rust, dove HashSet , HashMap , Vec , Array e Iterator sono tutte bestie diverse, ciascuna con le proprie capacità e costi . Non puoi iniziare con una "cosa in ascesa" e chiamare tutti i metodi che ti rendi conto di aver bisogno in questo momento.

Esempio di contrived

Ecco un esempio: diciamo che ho un mucchio di Foo di strutture con un membro Vec things . Voglio ottenere solo Foo s dove things include gli elementi specifici che sto cercando.

In Javascript o in un linguaggio simile (ad esempio, Clojure, ClojureScript), potrei prendere un array di Foo s e chiamare .filter((foo) => foo.things.includes(target_element)) . Quindi ottengo la conservazione dell'ordine di things per Foo e il controllo di appartenenza di things per il mio elemento di destinazione. (Immutable.JS ha OrderedMap pari, che cancella il giglio.)

D'altra parte, in Rust, ho bisogno di usare un HashMap per has() , ma un array o Vec per conservare l'ordine di things .

Potrei maneggiare una funzione vec_contains che chiama filter(|this_foo| this_foo.things.as_slice().contains(target_element)).collect().len() > 0 su things in Rust, ma ora ho una ricerca lineare e un array che si apre. Mi sembra di combattere il sistema dei tipi.

Domanda

Come tieni fuori dai guai quando usi tipi di raccolta strongmente specializzati in una lingua?

    
posta bright-star 05.02.2017 - 23:58
fonte

2 risposte

5

How do you stay out of trouble when using strongly specialized collection types in a language?

Impari.

Gli array JavaScript possono fare tutto, ma non lo fanno in modo efficiente. Non appena entrate in raccolte di dimensioni vagamente non banali, la ricerca lineare di contains non la taglierà. JavaScript ti consente di farlo perché è stato scritto in una settimana e nessuno ha pensato che sarebbe stato usato per qualcosa di serio.

Tu potresti fare il salto del cerchio nel linguaggio tipizzato in modo statico, ma il sistema di tipi è lì per un motivo. Se ti ritrovi a saltare i cerchi, probabilmente stai facendo qualcosa di sbagliato, e ti colpirà duramente una volta che avrai più di una dozzina di elementi nelle tue raccolte.

Quindi devi imparare i compromessi delle tue raccolte e progettare i tuoi programmi per trarne vantaggio, anche in JavaScript.

    
risposta data 06.02.2017 - 01:20
fonte
1

Credo che la tua domanda porti a risposte molto ponderate. Quindi, il seguente è solo la mia opinione su questo argomento. Suppongo che non ci sarà una risposta "giusta" per questo.

Hai detto che non si tratta di JavaScript vs Rust, ma in generale di come ti senti un certo tipo di limitazione quando ti allontani da un linguaggio tipizzato in modo dinamico come JavaScript e di dover esprimere le stesse idee in un linguaggio tipizzato staticamente come Ruggine, in particolare il tuo uso delle collezioni.

Credo che ci sia un errore nella tua valutazione, nel senso che ritieni che questa sia una limitazione che ritieni dovuta alla natura statica della lingua. Dubito che sia così.

Molte lingue tipizzate staticamente possono essere abbastanza espressive in particolare nelle loro raccolte di raccolte. Solo per citare alcuni esempi, qualsiasi linguaggio .statically tipizzato con LINQ, API Java 8 Stream, le API funzionali di Scala e praticamente qualsiasi linguaggio funzionale staticamente tipizzato offre un sacco di espressività nelle loro librerie di raccolta (SLM, OCaml, F #, Haskel, eccetera). Oserei, in alcuni casi, ancora più elegante di JavaScript.

Non conosco Rust, dal momento che è un linguaggio piuttosto nuovo, forse la limitazione che ritieni sia più correlata a una mancanza di espressività nelle API delle raccolte ancora immature di quanto non sia il risultato della loro tipicità statica.

L'esempio che hai citato di gestire Foos con things in essi, secondo la mia personale opinione ed esperienza, potrebbe essere banalmente implementato in ognuna di queste lingue tipizzate staticamente di cui parli senza alcuna evidente limitazione nell'espressività. Alcuni sembrerebbero abbastanza simili a ciò che faresti in JavaScript:

Stream.of(haystackOfFoos)
   .filter(foo -> foo.things.contains(needle))
   .map(foo -> foo.bar())
   .forEach(bar -> println(bar.name)); 

Questo mi rende teorico: potrebbe essere il caso che forse sei troppo abituato a lavorare con linguaggi di tipo dinamico, in particolare Javascript, e ora che provi con linguaggi tipizzati staticamente, sembra poco familiare e troppo restrittivo? Se è così, penso che con un po 'di pratica e una maggiore esposizione a loro, attraverserai gradualmente la voragine e inizierai ad apprezzarli di più e alla fine raggiungerai più abilità nell'esprimere le stesse idee in loro.

I linguaggi tipizzati dinamicamente sono molto liberali in quello che puoi fare con le strutture dati e trovo che sia piuttosto potente, in particolare quando vieni da linguaggi tipizzati staticamente in cui sei "forzato" a definire le tue astrazioni in modo più rigoroso . Ma quando ti muovi nella direzione opposta, penso che dev'essere più difficile, perché hai la sensazione che il sistema dei tipi sia in qualche modo in grado di esprimere le tue idee. Con la pratica e il tempo, e man mano che acquisisci maggiore familiarità con la lingua, e in particolare se definisci strutture dati e astrazioni valide per il dominio del tuo problema, penso che la sensazione svanisca e inizi ad apprezzare le potenti funzionalità delle lingue tipizzate staticamente sempre di più quando trovi modi per essere ugualmente espressivi in loro.

Dubito di avere in qualche modo risposto alla tua domanda, ma spero di aver almeno contribuito alla discussione in qualche modo.

    
risposta data 06.02.2017 - 03:44
fonte

Leggi altre domande sui tag