"Facile ragionare su" - cosa significa? [chiuso]


49

Ho sentito molte volte in cui altri sviluppatori usano quella frase per "pubblicizzare" alcuni schemi o sviluppare le migliori pratiche. Il più delle volte questa frase viene usata quando si parla di vantaggi della programmazione funzionale.

La frase "Facile ragionare su" è stata utilizzata così com'è, senza alcuna spiegazione o esempio di codice. Quindi per me diventa come la prossima parola "buzz", che più sviluppatori "esperti" usano nei loro discorsi.

Domanda: puoi fornire alcuni esempi di "Non facile da ragionare", in modo che possa essere confrontato con esempi "Facile da ragionare su"?


4
@MartinMaat una frase più precisa che è ampiamente usata è il ragionamento equazionale, suggerirei che questo potrebbe essere ciò che Fabio sta
cercando

3
Mi piace usare la frase "carico cognitivo" per questo genere di cose.
Baldrickk,

16
Sai cosa significa ragionamento sui programmi ?
Bergi,

5
In senso non formale, lo uso per indicare che una soluzione è abbastanza semplice da capire (in generale) quali saranno i risultati per ogni dato input senza testarlo. Ciò significa che per qualsiasi set di input, i risultati non saranno sorprendenti. Le soluzioni che hanno casi angolari non ovvi, per esempio, sono difficili da ragionare. Principalmente lo uso in riferimento alla robustezza.
JimmyJames,

7
Sono molto colpevole di usare frequentemente "più facile ragionare su"; Noto comunque che cerco di stare attento a dire il comparativo più facile piuttosto che l'assoluto facile . C'è stato un giorno nella mia vita in cui potevo ragionare su nessun software, quindi non è stato facile quel giorno; è diventato facile solo spendendo molto tempo e fatica. Dire che qualsiasi problema di programmazione è facile è prendere una posizione peggiorativa nei confronti di chiunque non possa (ancora) trovarlo facile. Dire che un modello è più facile di un altro è dire che ci sono meno concetti coinvolti, meno parti in movimento e così via.
Eric Lippert,

Risposte:


58

A mio avviso, la frase "facile ragionare su" si riferisce al codice che è facile da "eseguire nella tua testa".

Quando si guarda un pezzo di codice, se è breve, chiaramente scritto, con buoni nomi e una mutazione minima dei valori, lavorare mentalmente attraverso ciò che fa il codice è un compito (relativamente) facile.

Un lungo pezzo di codice con nomi scadenti, variabili che cambiano costantemente valore e ramificazioni contorte richiedono normalmente, ad esempio, una penna e un pezzo di carta per tenere traccia dello stato corrente. Pertanto, tale codice non può essere facilmente elaborato solo nella tua testa, quindi non è facile ragionare su tale codice.


29
Con un leggero avvertimento che non importa quanto bene si nominano le variabili, un programma che cerca di confutare la congettura di Goldbach è intrinsecamente difficile da "eseguire", nella tua testa o altrove. Ma può ancora essere facile ragionare, nel senso di essere facile convincere te stesso che se afferma di aver trovato un contro-esempio, allora sta dicendo la verità ;-)
Steve Jessop,

4
Non vorrei mai eseguire il codice nella mia testa. Quello, per me, sarebbe lo spettacolo finale di "non facile ragionare su". Vorrei poter fare dichiarazioni previsionali su cosa farebbe il computer senza eseguirlo. Il codice "facile da ragionare" è il codice che non deve essere eseguito nella tua testa, ma può essere ragionato invece.
Cort Ammon,

1
Come si può rispondere a una domanda sul ragionamento sul codice senza nemmeno menzionare la verifica formale ? Questa risposta suggerisce che il ragionamento sul codice è informale e ad hoc. non è, di solito è fatto con grande cura e approcci matematici. Ci sono alcune proprietà matematiche che rendono il codice "facile da ragionare" in senso oggettivo (funzioni pure, per dare un esempio molto semplice). i nomi delle variabili non hanno nulla a che fare con quanto sia facile "ragionare" sul codice, almeno non in senso formale.
Polygnome,

3
@Polygnome Il ragionamento sul codice di solito non viene fatto con grande cura e approcci matematici. Mentre scrivo questo, le persone che ragionano sul codice in modo informale stanno superando di numero gli avvicinatori matematici di milioni a uno, almeno, o almeno così credo.
Kaz,

2
@Polygnome "Code easy to reason about" almost exclusively alludes to its mathematical properties and formal verification- che suona approssimativamente come una risposta alla domanda. Potresti voler pubblicare questa come risposta invece di non essere d'accordo su quale sia la risposta (soggettiva) nei commenti.
Dukeling,

47

Un meccanismo o un pezzo di codice è facile da ragionare su quando è necessario prendere in considerazione alcune cose per prevedere cosa farà e le cose che è necessario prendere in considerazione sono facilmente disponibili.

Vere funzioni senza effetti collaterali e senza stato sono facili da ragionare perché l'output è completamente determinato dall'input, che è proprio lì nei parametri.

Al contrario, un oggetto con stato è molto più difficile da ragionare, perché devi tenere conto dello stato in cui si trova l'oggetto quando viene chiamato un metodo, il che significa che devi pensare a quali altre situazioni potrebbero portare l'oggetto in un stato particolare.

Ancora peggio sono le variabili globali: per ragionare sul codice che legge una variabile globale, devi capire dove nel tuo codice quella variabile potrebbe essere impostata e perché - e potrebbe non essere nemmeno facile trovare tutti quei posti.

Quasi la cosa più difficile da ragionare è la programmazione multithread con stato condiviso, perché non solo hai lo stato, hai più thread che lo cambiano allo stesso tempo, quindi per ragionare su cosa fa un pezzo di codice quando viene eseguito da un thread tu deve consentire la possibilità che in ogni singolo punto di esecuzione, alcuni altri thread (o diversi di essi!) possano essere eseguiti praticamente in qualsiasi altra parte del codice e modificare i dati sui quali stai operando proprio sotto i tuoi occhi. In teoria, ciò può essere gestito con mutex / monitor / sezioni critiche / come lo chiami, ma in pratica nessun semplice essere umano è in grado di farlo in modo affidabile a meno che non limiti drasticamente lo stato condiviso e / o il parallelismo a valori molto piccoli sezioni del codice.


9
Sono d'accordo con questa risposta, ma anche con funzioni pure, approcci dichiarativi (come CSS, o XSLT, makeo anche specializzazione di template C ++ e sovraccarico di funzioni) possono rimetterti nella posizione di considerare l'intero programma. Anche quando pensi di aver trovato la definizione di qualcosa, la lingua consente a una dichiarazione più specifica in qualsiasi parte del programma di sovrascriverla. Il tuo IDE potrebbe aiutarti in questo.
Steve Jessop,

4
Aggiungo che nello scenario multithread devi anche avere una comprensione ragionevolmente profonda di quali istruzioni di livello inferiore desugar il tuo codice: un'operazione che sembra atomica nella fonte potrebbe avere punti di interruzione imprevisti nell'esecuzione effettiva.
Jared Smith,

6
@SteveJessop: In effetti, questo punto è spesso trascurato. C'è un motivo per cui C # ti fa dire quando vuoi che un metodo sia sovrascrivibile piuttosto che rendere silenziosamente l'overridabilità il valore predefinito; desideriamo sventolare una bandiera che dice "la correttezza del tuo programma potrebbe dipendere dal codice che non puoi trovare in fase di compilazione" a questo punto. (Detto questo, vorrei anche che "sigillato" fosse il valore predefinito per le lezioni in C #.)
Eric Lippert,

@EricLippert Quali sono stati gli ultimi motivi per sealednon essere l'impostazione predefinita?
Zev Spitz,

@ZevSpitz: quella decisione è stata presa molto prima del mio tempo; Non lo so.
Eric Lippert,

9

Nel caso della programmazione funzionale, il significato di "Facile ragionare su" è principalmente che è deterministico. Con ciò intendevo dire che un determinato input porterà sempre allo stesso output. Puoi fare quello che vuoi al programma, finché non tocchi quel pezzo di codice, non si romperà.

D'altra parte, OO è in genere più difficile da ragionare perché l '"output" prodotto dipende dallo stato interno di ogni oggetto coinvolto. Il modo tipico in cui si manifesta sono effetti collaterali imprevisti : quando si modifica una parte del codice, una parte apparentemente non correlata si interrompe.

... il rovescio della medaglia della programmazione funzionale è che, in pratica, molto di ciò che si desidera fare è l'IO e la gestione dello stato.

Tuttavia, ci sono molte altre cose di cui è più difficile ragionare, e sono d'accordo con @Kilian che la concorrenza è un ottimo esempio. Anche i sistemi distribuiti.


5

Evitare discussioni più ampie e rispondere alla domanda specifica:

Puoi fornire alcuni esempi di "Non facile da ragionare su", in modo che possa essere confrontato con "Facile da ragionare su" esempi?

Vi rimando a "La storia di Mel, un vero programmatore" , un pezzo di folklore programmatore che risale al 1983 e quindi conta come "leggenda", per la nostra professione.

Racconta la storia di un programmatore che scrive codice che preferisce le tecniche arcane laddove possibile, incluso il codice autoreferenziale e autoregolante e lo sfruttamento deliberato dei bug della macchina:

un apparente ciclo infinito era infatti stato codificato in modo tale da sfruttare un errore di riporto. L'aggiunta di 1 a un'istruzione decodificata come "Carica dall'indirizzo x" ha normalmente prodotto "Carica dall'indirizzo x + 1". Ma quando x era già l'indirizzo più alto possibile, non solo l'indirizzo si spostava a zero, ma un 1 veniva portato nei bit da cui sarebbe stato letto il codice operativo, cambiando il codice operativo da "carica da" a "salta a" così che l'istruzione completa è cambiata da "carica dall'ultimo indirizzo" a "passa all'indirizzo zero".

Questo è un esempio di codice "difficile da ragionare".

Certo, Mel non sarebbe d'accordo ...


1
+1 per fare riferimento alla storia di Mel, uno dei miei preferiti perenni.
John Bollinger,

3
Leggi La storia di Mel qui, poiché l'articolo di Wikipedia non si collega ad esso.
TRiG,

@TRiG nota 3 nella pagina, no?
AakashM,

@AakashM In qualche modo è riuscito a perderlo.
TRiG

5

Posso fornire un esempio e uno molto comune.

Considera il seguente codice C #.

// items is List<Item>
var names = new List<string>();
for (var i = 0; i < items.Count; i++)
{
    var item = items[i];
    var mangled = MyMangleFunction(item.Name);
    if (mangled.StartsWith("foo"))
    {
        names.Add(mangled);
    }
}

Ora considera questa alternativa.

// items is List<Item>
var names = items
    .Select(item => MyMangleFunction(item.Name))
    .Where(s => s.StartsWith("foo"))
    .ToList();

Nel secondo esempio, so esattamente cosa sta facendo questo codice a colpo d'occhio. Quando vedo Select, so che un elenco di elementi viene convertito in un elenco di qualcos'altro. Quando vedo Where, so che alcuni elementi vengono filtrati. A colpo d'occhio, posso capire cos'è namese farne un uso efficace.

Quando vedo un forciclo, non ho idea di cosa stia succedendo fino a quando non ho effettivamente letto il codice. E a volte devo rintracciarlo per essere sicuro di aver tenuto conto di tutti gli effetti collaterali. Devo fare un po 'di lavoro anche per capire cosa sono i nomi (oltre la definizione del tipo) e come usarlo efficacemente. Pertanto, il primo esempio è più difficile da ragionare rispetto al secondo.

In definitiva, essere facili da ragionare qui dipende anche dalla comprensione dei metodi LINQ Selecte Where. Se non li conosci, allora il secondo codice è più difficile da ragionare inizialmente. Ma paghi solo il costo per capirli una volta. Paghi il costo per capire un forciclo ogni volta che ne usi uno e di nuovo ogni volta che cambia. A volte vale la pena pagare, ma in genere essere "più facili da ragionare" è molto più importante.


2

Una frase correlata è (I parafrasi),

Non è sufficiente che il codice non abbia " nessun bug ovvio ": dovrebbe invece avere " ovviamente nessun bug ".

Un esempio di "facile ragionamento" relativamente potrebbe essere RAII .

Un altro esempio potrebbe essere quello di evitare un abbraccio mortale : se riesci a tenere un lucchetto e acquisirne un altro, e ci sono molti lucchetti, è difficile essere sicuri che non ci sia uno scenario in cui potrebbe verificarsi un abbraccio mortale. L'aggiunta di una regola come "esiste un solo blocco (globale)" o, "non ti è consentito acquisire un secondo blocco mentre tieni premuto un primo blocco", rende il sistema relativamente facile da ragionare.


1
Hmm. Non sono sicuro che RAII sia così facile da ragionare. Certo, è facile da capire concettualmente , ma diventa più difficile ragionare effettivamente (cioè prevedere) il comportamento del codice che fa ampio uso di RAII. Voglio dire, sono sostanzialmente chiamate di funzioni invisibili a livello di ambito. Il fatto che molte persone abbiano difficoltà a ragionare su questo è molto chiaro se hai mai fatto una programmazione COM .
Cody Grey,

Intendevo relativamente facile (C ++ rispetto a C): ad esempio l'esistenza di un costruttore supportato dal linguaggio significa che i programmatori non possono creare / avere / usare un oggetto che dimenticano di inizializzare, ecc.
ChrisW,

Quell'esempio basato su COM è problematico perché mescola gli stili, ovvero il puntatore intelligente in stile C ++ ( CComPtr<>) con la funzione in stile C ( CoUninitialize()). Lo trovo anche un bizzarro esempio, per quanto ricordo che invochi CoInitialize / CoUninitialize nell'ambito del modulo e per l'intera durata del modulo, ad es. In maino in DllMain, e non in qualche piccolo ambito di funzione locale di breve durata come mostrato nell'esempio .
ChrisW,

È un esempio eccessivamente semplificato a fini illustrativi. Hai perfettamente ragione che COM sia inizializzato nell'ambito del modulo, ma immagina l'esempio di Raymond (come l'esempio di Larry) come la funzione entry point ( main) per un'applicazione. Si inizializza COM all'avvio e quindi si disinizializza subito prima di uscire. Tranne che hai oggetti globali, come i puntatori intelligenti COM, che usano il paradigma RAII. Per quanto riguarda gli stili di missaggio: un oggetto globale che ha inizializzato COM nel suo ctor e non inizializzato nel suo dtor è praticabile, e ciò che Raymond suggerisce, ma è sottile e non facile da ragionare.
Cody Gray,

Direi che, in molti modi, la programmazione COM è più facile da ragionare in C, perché tutto è una chiamata di funzione esplicita. Non c'è nulla di nascosto o invisibile dietro la schiena. È un po 'più lavoro (cioè più noioso), perché devi scrivere manualmente tutte quelle chiamate di funzione e tornare indietro e controllare il tuo lavoro per vedere che l'hai fatto correttamente, ma è tutto messo a nudo, che è la chiave per rendere facile ragionare . In altre parole, "a volte i puntatori intelligenti sono semplicemente troppo intelligenti" .
Cody Gray,

2

Il punto cruciale della programmazione è l'analisi del caso. Alan Perlis ha osservato questo in Epigram # 32: i programmatori non devono essere misurati dalla loro ingegnosità e dalla loro logica, ma dalla completezza della loro analisi del caso.

È facile ragionare su una situazione se l'analisi del caso è semplice. Ciò significa che ci sono pochi casi da considerare o, in mancanza, pochi casi speciali : potrebbero esserci ampi spazi di casi, ma che collassano a causa di alcune regolarità o soccombono a una tecnica di ragionamento come l'induzione.

Una versione ricorsiva di un algoritmo, ad esempio, di solito è più facile da ragionare rispetto a una versione imperativa, perché non contribuisce a casi superflui che sorgono attraverso la mutazione di variabili di stato di supporto che non compaiono nella versione ricorsiva. Inoltre, la struttura della ricorsione è tale da adattarsi a un modello matematico di prova per induzione. Non dobbiamo considerare complessità come varianti di loop e precondizioni rigide più deboli e quant'altro.

Un altro aspetto di questo è la struttura del case case. È più facile ragionare su una situazione che ha una divisione piatta o prevalentemente piatta in casi rispetto a una situazione gerarchica di casi: casi con sotto-casi e sotto-sotto-casi e così via.

Una proprietà dei sistemi che semplifica il ragionamento è l' ortogonalità : questa è la proprietà che i casi che governano i sottosistemi rimangono indipendenti quando questi sottosistemi vengono combinati. Nessuna combinazione dà origine a "casi speciali". Se un qualcosa a quattro casi è combinato con qualcosa a tre casi ortogonalmente, ci sono dodici casi, ma idealmenteogni caso è una combinazione di due casi che rimangono indipendenti. In un certo senso, non ci sono davvero dodici casi; le combinazioni sono solo "fenomeni simili a casi emergenti" di cui non dobbiamo preoccuparci. Ciò significa che abbiamo ancora quattro casi a cui possiamo pensare senza considerare gli altri tre nell'altro sottosistema e viceversa. Se alcune combinazioni devono essere appositamente identificate e dotate di logica aggiuntiva, il ragionamento è più difficile. Nel peggiore dei casi, ogni combinazione ha un trattamento speciale, e poi ci sono davvero dodici nuovi casi, che si aggiungono ai quattro e ai tre originali.


0

Sicuro. Prendi la concorrenza:

Sezioni critiche imposte dai mutex: facile da capire perché esiste un solo principio (due thread di esecuzione non possono entrare contemporaneamente nella sezione critica), ma inclini sia all'inefficienza che allo stallo.

Modelli alternativi, ad esempio programmazione o attori senza blocco: potenzialmente molto più elegante e potente, ma incredibilmente difficile da capire, perché non puoi più fare affidamento su concetti (apparentemente) fondamentali come "ora scrivi questo valore in quel luogo".

Essere facili da ragionare è un aspetto di un metodo. Ma scegliere quale metodo usare richiede di considerare tutti gli aspetti in combinazione.


13
-1: esempio davvero brutto che mi fa pensare che tu non capisca cosa significhi te stesso la frase. Le "sezioni critiche imposte dai mutex" sono in effetti una delle cose più difficili su cui ragionare là fuori - praticamente tutti coloro che le usano introducono condizioni di gara o deadlock. Ti darò una programmazione senza blocchi, ma il punto maledetto del modello dell'attore è che è molto, molto più facile ragionare.
Michael Borgwardt,

1
Il problema è che la concorrenza è di per sé un argomento molto difficile per i programmatori su cui ragionare, quindi non costituisce un ottimo esempio. Hai perfettamente ragione sul fatto che le sezioni critiche imposte dai mutex sono un modo relativamente semplice per implementare la concorrenza, rispetto alla programmazione senza blocchi, ma la maggior parte dei programmatori sono come Michael, e i loro occhi si guardano intorno quando inizi a parlare di sezioni critiche e mutex, quindi questo certamente non sembra una cosa facile da capire. Per non parlare di tutti i bug.
Cody Grey,

0

Limitiamo il compito al ragionamento formale. Perché il ragionamento umoristico o inventivo o poetico ha leggi diverse.

Anche così, l'espressione è definita in modo oscuro e non può essere impostata in modo rigoroso. Ma ciò non significa che dovrebbe rimanere così debole per noi. Immaginiamo che una struttura stia superando alcuni test e ottenga punti per punti diversi. I buoni voti per OGNI punto indicano che la struttura è conveniente in ogni aspetto e quindi "Facile ragionare".

La struttura "Facile ragionare su" dovrebbe ottenere buoni voti per quanto segue:

  • I termini interni hanno nomi ragionevoli, facilmente distinguibili e definiti. Se gli elementi hanno una certa gerarchia, la differenza tra i nomi padre e figlio dovrebbe essere diversa dalla differenza tra i nomi dei fratelli.
  • Il numero di tipi di elementi strutturali è basso
  • I tipi usati di elementi strutturali sono cose facili a cui siamo abituati.
  • Gli elementi difficilmente comprensibili (ricorsioni, meta passi, geometria dimensionale 4+ ...) sono isolati - non combinati direttamente tra loro. (ad esempio, se proverai a pensare ad alcune regole ricorsive che cambiano per 1,2,3,4..n..dimensionali cubi, sarà molto complicato. Ma se trasferirai ciascuna di queste regole in una formula a seconda di n, avrai separatamente una formula per ogni n-cubo e separatamente una regola di ricorsione per tale formula. E che due strutture separatamente possono essere facilmente pensate)
  • I tipi di elementi strutturali sono ovviamente diversi (ad esempio, non utilizzare matrici miste a partire da 0 e da 1)

Il test è soggettivo? Sì, naturalmente lo è. Ma anche l'espressione stessa è soggettiva. Ciò che è facile per una persona, non è facile per un'altra. Quindi, i test dovrebbero essere diversi per i diversi domini.


0

L'idea che i linguaggi funzionali possano essere ragionati proviene dalla loro storia, in particolare ML, che è stato sviluppato come un linguaggio di programmazione analogo ai costrutti che la Logica per le funzioni calcolabili ha usato per il ragionamento. La maggior parte dei linguaggi funzionali sono più vicini ai calcoli di programmazione formale rispetto a quelli imperativi, quindi la traduzione dal codice nell'input di un sistema di ragionamento è meno onerosa.

Per un esempio di un sistema di ragionamento, in pi-calcolo, ogni posizione di memoria mutabile in un linguaggio imperativo deve essere rappresentata come un processo parallelo separato, mentre una sequenza di operazioni funzionali è un singolo processo. A quarant'anni di distanza dal proiettore di teoremi LFC, stiamo lavorando con GB di RAM, quindi avere centinaia di processi è meno un problema: ho usato pi-calculus per rimuovere potenziali deadlock da alcune centinaia di righe di C ++, nonostante la rappresentazione abbia centinaia di elabora il ragionatore esaurendo lo spazio degli stati in circa 3 GB e cura un bug intermittente. Ciò sarebbe stato impossibile negli anni '70 o avrebbe richiesto un supercomputer nei primi anni '90, mentre lo spazio statale di un programma linguistico funzionale di dimensioni simili era abbastanza piccolo da poter essere considerato all'epoca.

Dalle altre risposte, la frase sta diventando una parola d'ordine, anche se gran parte della difficoltà che ha reso difficile ragionare sulle lingue imperative è erosa dalla legge di Moore.


-2

È facile ragionare su un termine culturalmente specifico, motivo per cui è così difficile trovare esempi concreti. È un termine ancorato alle persone che devono fare il ragionamento.

"Facile ragionare su" è in realtà una frase molto auto-descrittiva. Se uno sta guardando il codice e vuole ragionare su ciò che fa, è facile =)

Va bene, abbattendolo. Se stai guardando il codice, di solito vuoi che faccia qualcosa. Vuoi assicurarti che faccia quello che pensi che dovrebbe fare. Quindi sviluppi teorie su cosa dovrebbe fare il codice, e poi ragionerai su di esso per cercare di argomentare perché il codice funzioni davvero. Cerchi di pensare al codice come un essere umano (piuttosto che come un computer) e cerchi di razionalizzare gli argomenti su ciò che il codice può fare.

Il caso peggiore per "facile ragionare" è quando l'unico modo per dare un senso a ciò che fa il codice è quello di passare riga per riga attraverso il codice come una macchina di Turing per tutti gli input. In questo caso, l'unico modo di ragionare nulla circa il codice è quello di trasformare se stessi in un computer ed eseguirlo nella tua testa. Questi esempi peggiori sono facilmente visibili in concorsi di programmazione offuscati, come queste 3 righe di PERL che decodificano RSA:

#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

Per quanto facile da ragionare, ancora, il termine è altamente culturale. Devi considerare:

  • Quali abilità ha il ragionatore? Quanta esperienza?
  • Che tipo di domande potrebbe avere il ragionatore sul codice?
  • quanto deve essere sicuro il ragionatore?

Ognuno di questi influisce "facilmente su cui ragionare" in modo diverso. Prendi le abilità del ragionatore come esempio. Quando ho iniziato presso la mia azienda, mi è stato consigliato di sviluppare i miei script in MATLAB perché è "facile ragionare". Perché? Bene, tutti nell'azienda conoscevano MATLAB. Se avessi scelto una lingua diversa, sarebbe stato più difficile per chiunque capirmi. Non importa che la leggibilità di MATLAB sia atroce per alcuni compiti, semplicemente perché non è stata progettata per loro. Più tardi, con il progredire della mia carriera, Python divenne sempre più popolare. Improvvisamente il codice MATLAB divenne "difficile da ragionare" e Python era il linguaggio di preferenza per la scrittura di codice su cui era facile ragionare.

Considera anche quali idomi può avere il lettore. Se puoi fare affidamento sul tuo lettore per riconoscere una FFT in una particolare sintassi, è "più facile ragionare su" il codice se ti attieni a quella sintassi. Li consente di guardare il file di testo come tela su cui hai dipinto un FFT, piuttosto che dover entrare nei dettagli grintosi e nitidi. Se usi C ++, scopri quanto i tuoi lettori si sentono a proprio agio con la stdlibreria. Quanto gli piace la programmazione funzionale? Alcuni dei modi di dire che escono dalle librerie dei contenitori dipendono molto dallo stile idomatico che preferisci.

È anche importante capire a quali tipi di domande il lettore potrebbe essere interessato a rispondere. I tuoi lettori sono per lo più interessati alla comprensione superficiale del codice o sono alla ricerca di bug nelle viscere?

Quanto sia sicuro il lettore deve essere davvero interessante. In molti casi, il ragionamento confuso è in realtà sufficiente per far uscire il prodotto. In altri casi, come il software di volo FAA, il lettore vorrà avere ragionamenti coraggiosi. Mi sono imbattuto in un caso in cui ho sostenuto di utilizzare RAII per un compito specifico, perché "Puoi semplicemente impostarlo e dimenticartene ... farà la cosa giusta". Mi è stato detto che mi sbagliavo. Coloro che avrebbero ragionato su questo codice non erano il tipo di persone che "vogliono solo dimenticare i dettagli". Per loro, RAII era più simile a un ciad sospeso, costringendoli a pensare a tutte le cose che possono accadere quando lasci l'ambito.


12
Il codice Perl è difficile da leggere ; non una ragione . Se avessi un po 'di interesse nel doverlo capire, deselezionerei il codice. Il codice su cui è in realtà difficile ragionare è ciò su cui è ancora difficile ragionare quando è ben formattato con identificatori chiari per tutto e nessun trucco con il golf.
Kaz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.