Perché esiste un supporto così limitato per Design by Contract nella maggior parte dei moderni linguaggi di programmazione?

39

Recentemente ho scoperto Design by Contract (DbC) e trovo un modo estremamente interessante per scrivere codice. Tra l'altro, sembrerebbe offrire:

  • Migliore documentazione. Poiché il contratto è la documentazione, è impossibile che uno sia obsoleto. Inoltre, poiché il contratto specifica esattamente cosa fa una routine, aiuta a supportare il riutilizzo.
  • Debug più semplice. Dal momento che l'esecuzione del programma si interrompe nel momento in cui un contratto fallisce, gli errori non possono propagarsi, e l'asserzione specifica violata sarà presumibilmente evidenziata. Questo offre supporto durante lo sviluppo e durante la manutenzione.
  • Migliore analisi statica. DbC è fondamentalmente solo un'implementazione della logica Hoare, e dovrebbero essere applicati gli stessi principi.

I costi, a confronto, sembrano piuttosto piccoli:

  • Dattilografia aggiuntiva. Poiché i contratti devono essere enunciati.
  • Prende un po 'di allenamento per sentirsi a proprio agio con i contratti di scrittura.

Ora, avendo familiarità principalmente con Python, mi rendo conto che è in effetti possibile scrivere le precondizioni (solo lanciando eccezioni per input inappropriati) ed è anche possibile usare asserzioni per testare nuovamente alcune postcondizioni. Ma non è possibile simulare certe caratteristiche come "vecchio" o "risultato" senza un po 'di magia in più che alla fine sarebbe considerata non-Pythonic. (Inoltre, ci sono alcune librerie che offrono supporto, ma alla fine ho l'impressione che sarebbe sbagliato usarle, come la maggior parte degli sviluppatori no.) Suppongo che sia un problema simile per tutte le altre lingue (eccetto ovviamente , Eiffel).

La mia intuizione mi dice che la mancanza di supporto deve essere il risultato di un qualche tipo di rifiuto della pratica, ma la ricerca online non è stata fruttuosa. Mi chiedo se qualcuno possa chiarire perché la maggior parte delle lingue moderne sembra offrire così poco supporto? DbC è imperfetto o eccessivamente costoso? O è solo obsoleto a causa di Extreme Programming e altre metodologie?

    
posta Ceasar Bautista 06.01.2012 - 01:01
fonte

9 risposte

8

Probabilmente sono supportati praticamente in ogni linguaggio di programmazione.

Ciò di cui hai bisogno sono "asserzioni".

Questi sono facilmente codificati come istruzioni "if":

if (!assertion) then AssertionFailure();

Con questo, puoi scrivere contratti posizionando tali asserzioni nella parte superiore del tuo codice per i vincoli di input; quelli nei punti di ritorno sono vincoli di output. È anche possibile aggiungere invarianti per tutto il codice (anche se non fanno realmente parte della "progettazione per contratto").

Quindi sostengo che non sono diffusi perché i programmatori sono troppo pigri per codificarli, non perché non puoi farlo.

Puoi renderli un po 'più efficienti nella maggior parte dei linguaggi definendo una costante booleana in fase di compilazione "verificando" e rivedendo un po' le affermazioni:

if (checking & !Assertion) then AssertionFailure();

Se la sintassi non ti piace, puoi ricorrere a varie tecniche di astrazione del linguaggio come i macro.

Alcune lingue moderne ti danno una bella sintassi per questo, ed è quello che penso intendi per "supporto linguistico moderno". Questo è il supporto, ma è piuttosto sottile.

Ciò che la maggior parte dei linguaggi moderni non ti dà sono asserzioni "temporali" (su arbitrari precedenti o successivi [operatore temporale "alla fine"], di cui hai bisogno se vuoi scrivere contratti davvero interessanti. ti aiuto qui.

    
risposta data 16.01.2012 - 04:34
fonte
15

Come dici tu, Design by Contract è una funzione di Eiffel, che è stata a lungo uno di quei linguaggi di programmazione che è ben rispettato nella comunità ma che non ha mai preso piede.

DbC non è in nessuna delle lingue più popolari perché è relativamente recente che la comunità di programmazione tradizionale è arrivata ad accettare che aggiungere vincoli / aspettative al proprio codice è una cosa "ragionevole" da aspettarsi dai programmatori. È ormai normale che i programmatori capiscano quanto siano preziosi i test di unità, e questo ha spinto i programmatori ad accettare di inserire il codice per convalidare i loro argomenti e vedere i benefici. Ma un decennio fa, probabilmente la maggior parte dei programmatori direbbe "è solo un lavoro extra per cose che sai sarà sempre ok".

Penso che se tu oggi andassi dallo sviluppatore medio e parlassi di post-condizioni, loro annuncerebbero con entusiasmo e dire "OK, è come un test unitario". E se parli di pre-condizioni, loro direbbero "OK, è come la validazione dei parametri, che non sempre facciamo, ma, sai, immagino sia ok ..." E poi se parli di invarianti , inizierebbero a dire "Accidenti, quanta overhead è questa? Quanti altri bug riusciremo a catturare?" ecc.

Quindi penso che ci sia ancora molta strada da fare prima che DbC sia adottato in maniera molto ampia.

    
risposta data 06.01.2012 - 02:25
fonte
7

My intuition tells me that the lack of support must be a result of some kind of rejection of the practice,...

False.

È una pratica design . Può essere incorporato esplicitamente nel codice (stile Eiffel) o implicitamente nel codice (la maggior parte delle lingue) o nei test unitari. La pratica del design esiste e funziona bene. Il supporto linguistico è dappertutto sulla mappa. Tuttavia, è presente in molte lingue nel framework di test unitario.

I'm wondering if someone can clarify why most modern languages seem to offer so little support? Is DbC flawed or overly expensive?

È costoso. E. Ancora più importante, ci sono alcune cose che non possono essere dimostrate in una determinata lingua. La terminazione del loop, ad esempio, non può essere dimostrata in un linguaggio di programmazione, richiede una funzionalità di prova "di ordine superiore". Quindi alcuni tipi di contratti sono tecnicamente inesprimibili.

Or is it just obsolete due to Extreme Programming and other methodologies?

No.

Utilizziamo principalmente test unitari per dimostrare che DbC è soddisfatto.

Per Python, come hai notato, il DbC va in diversi punti.

  1. I risultati del test docstring e docstring.

  2. Asserzioni per convalidare input e output.

  3. Test delle unità.

Per ulteriori.

È possibile adottare strumenti di programmazione in stile letterale per scrivere un documento che includa le informazioni DbC e che generi script di test di unità Python più puliti. L'approccio di programmazione letterale ti consente di scrivere un bel pezzo di letteratura che include i contratti e la fonte completa.

    
risposta data 06.01.2012 - 11:54
fonte
5

Solo indovinando. Forse parte del motivo per cui non è così popolare è perché "Design by Contract" è un marchio registrato di Eiffel.

    
risposta data 06.01.2012 - 08:29
fonte
3

Un'ipotesi è che per un programma complesso sufficientemente grande, specialmente per quelli con un bersaglio mobile, la massa dei contratti stessi può diventare buggata e difficile da debugare, o più, del codice del programma da solo. Come in ogni modello, è possibile che i ritorni decrescenti dell'utilizzo vengano utilizzati, oltre a vantaggi evidenti se utilizzati in modo più mirato.

Un'altra possibile conclusione è che la popolarità dei "linguaggi gestiti" è la prova attuale del supporto della progettazione per contratto per le funzionalità gestite selezionate (limiti di matrice per contratto, ecc.)

    
risposta data 06.01.2012 - 03:00
fonte
2

La ragione per cui la maggior parte delle lingue mainstream non ha le funzionalità di DbC nella lingua è il rapporto costo / benefici di implementazione è troppo alto per l'implementatore di lingua.

un lato di questo è già stato visto nelle altre risposte, unit test e altri meccanismi di runtime (o anche alcuni meccanismi di tempo di compilazione con meta programmazione template) possono darti già un sacco della bontà del DbC. Pertanto, mentre c'è un vantaggio, è probabile che sia visto come piuttosto modesto.

L'altro lato è il costo, il montaggio retroattivo di DbC in una lingua esistente è probabilmente un cambiamento troppo grande e molto complesso da avviare. Introdurre nuova sintassi in una lingua senza rompere il vecchio codice è difficile. Aggiornare la tua libreria standard esistente per utilizzare un cambiamento di tale portata sarebbe costoso. Pertanto possiamo concludere che l'implementazione delle funzionalità di DbC in una lingua esistente ha un costo elevato.

Vorrei anche notare che concetti che sono praticamente contratti per i modelli e quindi in qualche modo correlati a DbC, sono stati eliminati dall'ultimo standard C ++ poiché anche dopo anni di lavoro su di essi è stato stimato che avevano ancora bisogno di anni di lavoro. Questo tipo di cambiamenti ampi, vasti e ampi verso le lingue sono troppo difficili da attuare.

    
risposta data 16.01.2012 - 14:39
fonte
2

DbC sarebbe usato in modo più esteso se i contratti potessero essere controllati in fase di compilazione in modo che non fosse possibile eseguire un programma che violasse qualsiasi contratto.

Senza il supporto del compilatore, "DbC" è solo un altro nome per "verificare invarianti / ipotesi e generare un'eccezione se violato".

    
risposta data 16.01.2012 - 16:18
fonte
0

Ho una spiegazione semplice, la maggior parte delle persone (inclusi i programmatori) non vuole altro lavoro a meno che non lo ritengano necessario. Programmazione avionica in cui la sicurezza è considerata molto importante Non ho visto la maggior parte dei progetti senza.

Tuttavia, se stai prendendo in considerazione la programmazione di siti Web, desktop o dispositivi mobili, i crash e il comportamento imprevisto a volte non sono considerati così dannosi e i programmatori eviteranno di lavorare in più quando segnalano bug e successivamente li risolveranno in modo adeguato.

Questa è probabilmente la ragione per cui ritengo che Ada non sia mai approdata al di fuori del settore della programmazione aeronautica perché richiede più lavoro di programmazione anche se Ada è un linguaggio fantastico e se vuoi costruire un sistema affidabile, è la lingua migliore per il lavoro (escluso SPARK quale linguaggio proprietario basato su Ada).

Le librerie design per contratto per C # erano sperimentali di Microsoft, e sono molto utili per creare software affidabile, ma non hanno mai preso slancio nel mercato altrimenti le avresti già viste come parte del linguaggio core C #.

Le asserzioni non sono le stesse del supporto pienamente funzionale per condizioni pre / post e invarianti. Sebbene possa provare ad emularli, ma un linguaggio / compilatore con il supporto appropriato fa l'analisi 'abstract syntax tree' e controlla gli errori logici che semplicemente le asserzioni non possono.

Modifica: Ho effettuato una ricerca e la discussione correlata che segue potrebbe essere utile: link

    
risposta data 08.08.2017 - 03:41
fonte
-2

Per lo più le ragioni sono le seguenti:

  1. È disponibile solo in lingue che non sono popolari
  2. Non è necessario poiché le stesse cose possono essere fatte in modo diverso nei linguaggi di programmazione esistenti da chiunque lo voglia veramente fare
  3. È difficile da capire e da usare - richiede conoscenze specializzate per farlo correttamente, quindi ci sono poche persone che lo fanno
  4. richiede grandi quantità di codice per farlo - i programmatori preferiscono ridurre al minimo la quantità di caratteri che scrivono - se ci vuole un pezzo di codice lungo, qualcosa deve essere sbagliato con esso
  5. i vantaggi non ci sono - non riesco a trovare abbastanza bug per renderlo utile
risposta data 06.01.2012 - 02:35
fonte

Leggi altre domande sui tag