Che cosa è meglio per la prototipazione: un linguaggio tipizzato staticamente o uno tipizzato dinamicamente? [chiuso]

8

Quando elabora il progetto per un nuovo sistema, è meglio iniziare con un linguaggio tipizzato staticamente (come Haskell) o con un linguaggio tipizzato dinamicamente (come Ruby)?

Argomenti a cui posso pensare:

  • Con un linguaggio statico, puoi creare rapidamente una specifica e uno scopo per ciò che farà il programma. Con un linguaggio dinamico, puoi creare rapidamente una demo funzionante da presentare al cliente per la revisione.

  • Con un linguaggio dinamico, eviti spesso di dover riorganizzare le strutture dati e il codice refactoring quando cambi il tuo design. Con un linguaggio statico, puoi definire i tipi prima dell'implementazione, mantenendo il codice da mantenere molto piccolo.

  • Con un linguaggio statico, devi capire in anticipo cosa farà il tuo programma. Con un linguaggio dinamico, puoi iniziare a scrivere codice e far crescere organicamente il design. Come dice Paul Graham in Hacker e pittori :

    A programming language is for thinking of programs, not for expressing programs you've already thought of.

  • Con un linguaggio statico, il compilatore può aiutare a identificare molti tipi di bug. Con un linguaggio dinamico, puoi iniziare a testare e trovare i bug prima.

La tipizzazione statica e dinamica hanno entrambi vantaggi e svantaggi per quanto riguarda la prototipazione. Tuttavia, entrambi mi sembrano approcci altrettanto validi. In base alle tue esperienze, quale è in definitiva migliore?

Note

Prototipazione in linguaggio naturale

Un terzo tipo di linguaggio da considerare: linguaggio naturale. Invece di prototipare in codice, si può prototipare per iscritto. Il cliente può quindi leggere la documentazione e criticare il tuo progetto in anticipo, ma non può divertirsi con una demo funzionante. Se ben scritta, la documentazione può rendere l'implementazione in qualsiasi lingua semplice. Avvertenze:

  • La documentazione può essere noiosa da leggere e difficile da digerire senza essere in grado di vederla. Suppongo che un cliente preferisca sperimentare qualcosa che funziona piuttosto che leggere un muro di testo (e immagini).

  • La prototipazione di un'applicazione in inglese anziché nelle definizioni di tipo è più prolissa e meno concreta.

I tipi di Haskell sono descrittivi

Si noti che i tipi sono particolarmente descrittivi in Haskell, più che in molti linguaggi statici come C ++ e Java. Ad esempio, supponiamo di avere una funzione con questo tipo di firma in Haskell:

foo :: forall a. [a] -> a

Una funzione che, per qualsiasi tipo a , prende un elenco di voci di tipo a e restituisce un valore di tipo a .

Anche senza conoscere il nome della funzione, so per certo che:

  • Non esegue input / output o modifica alcun valore (beh, a meno che non usi unsafePerformIO in modo errato), perché Haskell è puramente funzionale.

  • Non può trattare gli elementi come, per esempio, numeri interi, perché deve supportare qualsiasi tipo .

  • Ha ha per usare la lista di input (quella, o lanciare un'eccezione o entrare in un ciclo infinito). Altrimenti, dove otterrebbe un valore di tipo a da?

Pertanto, l'unica cosa che questa funzione potrebbe fare (oltre che fallire) è estrarre un elemento dall'elenco di input e restituirlo. Anche se non so ancora quale oggetto userà, [a] -> a mi dice praticamente tutto il resto.

    
posta Joey Adams 05.09.2011 - 00:48
fonte

6 risposte

8

Parlerò con Paul Graham su questo: la tipizzazione dinamica è più utile per la creazione di programmi organicamente, che è esattamente ciò che dovrebbe essere la prototipazione. Il punto è ottenere rapidamente qualcosa che dimostri la funzionalità del prodotto finale, non il prodotto finale stesso. La tipizzazione statica riguarda la correttezza formale, beh, apparentemente; almeno dovrebbe essere (come in Haskell o Agda), ma la digitazione dinamica riguarda la correttezza pratica, che è ciò che conta di più quando si esegue la prototipazione.

Nella lingua corretta, i suggerimenti di tipo statico possono essere forniti dopo il fatto come un'ottimizzazione (e per fornire ulteriore sicurezza per modifiche future), oppure il prototipo può essere riscritto in un linguaggio tipizzato staticamente una volta che i requisiti sono stati chiariti e solidificati dal prototipo.

    
risposta data 05.09.2011 - 01:32
fonte
6

Penso che il problema del tipo statico / dinamico non sia così importante come molte persone lo dimostrano.

  1. Io uso entrambi. A volte uno è semplicemente più utile di un altro in una determinata situazione. Questo è il più delle volte causato dalla necessità di utilizzare alcuni strumenti / librerie / tecnologie specifici. Quindi ho scelto ciò che funziona bene con gli altri componenti che ho.

  2. Penso che una delle cose che piacciono alle persone sui linguaggi dinamici sia che molti sono interpretati; Puoi modificarli mentre sono in esecuzione in modo interattivo utilizzando una console REPL . Qualsiasi lingua con una funzione eval o qualcosa di equivalente può farlo. Quindi, almeno per questo aspetto, il sistema dei tipi è in realtà irrilevante.

  3. Puoi costruire prototipi usando cose che non hanno affatto un sistema di tipo formale come gli script di shell. (Hanno REPL però ...)

risposta data 05.09.2011 - 05:32
fonte
4

Fai ciò che funziona meglio per te e per quello che stai cercando di fare. Trovo che attualmente prototipo meglio in un linguaggio statico. La prototipazione con un sistema di tipo espressivo ti consente di fare cose interessanti:

  • Scrivi firme di funzioni senza implementazioni corrispondenti. Il mio codice Haskell nella fase iniziale ha spesso dichiarazioni come:

    foo :: Foo - > bar
     foo _ = errore "non definito"

Questo perché voglio un'idea di cosa fa foo quando scrivo codice che lo usa, senza dover effettivamente avere una copia di lavoro di foo . In altri linguaggi questo è realizzato con qualcosa come throw new Exception() , che è qualcosa che non faresti mai nel codice reale, ma aiuta un sacco nelle prime fasi.

  • Scrivi il codice senza scrivere prima i tipi e usa l'inferenza di tipo per imparare cose sul tuo codice. Io chiamo frequentemente :t nel GHCi (Haskell REPL) per scoprire che cosa ho appena scritto. Ad esempio, questo può dirvi quanto è generico un pezzo di codice, rivelando così i requisiti dei diversi pezzi del codice e della struttura corrispondente.

Conal Elliot ha descritto la sua visione di Haskell per aiutare lo sviluppo di iPhone in questo modo:

"Una volta che stavo scrivendo Haskell, la macchina imperativa svanì alla vista e non potei fare a meno di iniziare a vedere i modelli essenziali. Armeggiare con questi schemi mi portò a nuove intuizioni ... Sono grato di avere questo pigro di ordine superiore un linguaggio con una ricca digitazione statica come strumento di pensiero, per aiutarmi a ottenere intuizioni ed eliminare i miei errori.E 'un vantaggio per me che anche il linguaggio sia eseguibile. " Source

È vero. Uno degli dei della programmazione funzionale ritiene che il valore primario di Haskell sia un linguaggio di modellazione piuttosto che un linguaggio di implementazione. Altri guru pensano cose simili: Erik Meijer usa Haskell per aiutare a chiarire l'algebra e gli schemi che alla fine entrano in strutture orientate agli oggetti.

La ragione più importante però per la prototipazione in un linguaggio rigoroso, è che molte volte le cose che si vogliono "prototipare" non sono le eleganti applicazioni web in fase iniziale che Paul Graham vuole finanziare. Spesso è necessario prototipare:

  1. Estensioni all'attuale infrastruttura
  2. API per una lingua specifica
  3. Architettura, non solo nuove funzionalità

In ognuno di questi casi si desidera veramente utilizzare un linguaggio che sia vicino al linguaggio di implementazione finale in modi significativi.

Un nitpick però

 foo :: forall a. [a] -> a

non ha istanze "corrette" (termina sempre senza produrre errori o undefined ). Questo perché

[] :: forall a. [a]

Ma non esiste alcuna funzione da [] a a per a che non ha istanze.

    
risposta data 05.09.2011 - 06:02
fonte
4

Intendi caratteristiche o design prototipi?

I prototipi

Feature stanno mostrando una funzionalità al client prima di iniziare lo sviluppo di tale funzione da zero nel linguaggio di implementazione finale, quindi il punto è scrivere quella funzionalità il più velocemente possibile senza preoccuparsi dei bug o manutenibilità. I linguaggi dinamici consentono un compromesso tra correttezza e produttività, consentendo brutti scherzi che nessun linguaggio staticamente tipizzato accetterebbe, il che li rende, in teoria, più adatti per la scrittura di prototipi quick throw-away. Naturalmente, in pratica, l'abilità dello sviluppatore è più importante della lingua, ma un programmatore ugualmente esperto sia in Haskell che in Ruby probabilmente creerebbe un prototipo più veloce in Ruby, e il codice risultante sarebbe un disastro.

I prototipi

Design mirano a trovare un design appropriato del programma attraverso tentativi ed errori. Gli hack brutti sono inutili: solo la capacità di rifattorizzare i progetti conta rapidamente. Un requisito fondamentale per il massiccio refactoring è una suite di test automatizzati. Nei linguaggi dinamici, questa è di solito una suite di test unitari scritti dagli sviluppatori, che richiede una buona quantità di tempo per scrivere. Nelle lingue con tipizzazione statica, le firme dei tipi fungono da test automatici e consentono al compilatore di rilevare eventuali incoerenze causate dalle modifiche al codice. Le lingue tipizzate staticamente brillano al refactoring in modi che nessuna lingua digitata in modo dinamico può raggiungere.

    
risposta data 05.09.2011 - 09:10
fonte
0

Dinamico, soprattutto se si sa che il prodotto effettivo dovrebbe trovarsi in uno dei più diffusi linguaggi statici per essere abbastanza veloce da risolvere il vero problema in natura. Farlo ti proteggerà automaticamente dall'errore di utilizzare il prototipo come prodotto finale.

    
risposta data 05.09.2011 - 21:53
fonte
0

Qualunque sia la lingua con cui hai più familiarità.

Dinamico contro statico in realtà non importa. Funzionale vs OO non ha importanza. La migliore vestibilità, le funzionalità o qualsiasi altra cosa di solito non hanno alcun significato.

L'unico punto di prototipazione è la velocità di implementazione (scrittura del codice) perché è necessario modificare molto il programma. E dovresti essere il più veloce con la tua lingua migliore.

Se hai due migliori lingue sia dinamiche che statiche, scommetterei su quelle statiche. Perché uno statico in genere è in grado di gestire la complessità, mentre uno dinamico non riesce a un certo punto. E nessuno sa davvero quanto grande prototipo crescerà.

    
risposta data 04.05.2014 - 03:10
fonte

Leggi altre domande sui tag