Perché una lingua dovrebbe preferire il rientro rispetto a marcatori espliciti per i blocchi?


11

Sto imparando Haskell e stavo cercando uno strumento di rientro automatico. Non ho guardato molto e ho imparato che in Haskell (come in Python), il rientro indica un blocco. Di conseguenza, suppongo che sia impossibile creare uno strumento di formattazione automatica, forte come in altre lingue della famiglia C, che utilizza marcatori espliciti, come {} (parentesi graffe) o begin endparole chiave.

Non mi dispiace un linguaggio che imponga il rientro per la leggibilità, ma non riesco a capire i vantaggi sia di imporre il rientro sia di avere un marcatore esplicito, in modo che gli strumenti automatizzati possano capire ciò che appartiene a quale blocco.

Se la preferenza del rientro segna un blocco, è così che il codice sembra migliore, quindi ancora non capisco il vantaggio. Dato che le schede e gli spazi sono rappresentati in modo diverso in diversi editor e caratteri diversi (i caratteri mono-spazio, ad esempio, sembrano più ordinati), è impossibile aspettarsi che il programmatore presenti il ​​codice in modo decente. Uno strumento che può tenere conto dell'attuale editor di testo, sarebbe molto più appropriato per formattare correttamente il codice.

Perché un designer linguistico dovrebbe scegliere il rientro rispetto ai marcatori di blocco espliciti?


8
Non è una risposta, ma Haskell rende la sensibilità agli spazi molto più opzionale di Python. Puoi usare il punto e virgola per la maggior parte delle cose e, se lo desideri, avvolgi i blocchi tra parentesi graffe. let x =1; y = 2; z = 3è completamente valido, così com'è do { putStrLn $ show x; putStrLn $ show y; putStrLn $ show z; }. Quelli non hanno bisogno di essere sulla stessa linea.
KChaloux,

8
"è impossibile creare uno strumento di formattazione automatica" - in realtà, non è necessario uno strumento di formattazione automatica in Python a causa delle regole di rientro.
Doc Brown,

13
Ehm, aumentare il rientro è un marcatore di blocco esplicito.
Karl Bielefeldt,

3
@ K.Gkinis: la migliore fonte per le motivazioni esatte alla base di una decisione di progettazione del linguaggio sono gli stessi progettisti del linguaggio.
Robert Harvey,

3
Questa domanda non è in realtà soggettiva. Si chiede perché alcuni designer di linguaggi abbiano scelto una certa sintassi. È possibile rispondere a questa domanda. Se la domanda avesse posto la sintassi migliore , sarebbe soggettiva.
JacquesB,

Risposte:


13

Guido Von Rossum

Da un'intervista a Guido Van Rossum , che può essere visto in full text con books.google.com (sottolineatura mia):

La scelta del rientro per il raggruppamento non era un nuovo concetto in Python; L'ho ereditato da ABC , ma si è verificato anche in occam, una lingua più vecchia. Non so se gli autori della ABC abbiano preso l'idea dall'occam, o se la abbiano inventata indipendentemente, o se ci fosse un antenato comune. Certo, avrei potuto ha scelto di non seguire l'esempio di ABC, come ho fatto in altri settori (ad esempio, ABC maiuscolo utilizzato per parole chiave del linguaggio e nomi di routine, un'idea non ho copiato), ma mi era venuto a come la funzione piuttosto una un po 'mentre si usa l'ABC, in quanto sembrava eliminare un certo tipo di dibattito inutile comune tra gli utenti C all'epoca, su dove posizionare le parentesi graffe .

Von Rossum fu fortemente ispirato dall'ABC e, sebbene non fosse costretto a copiarlo interamente, l'uso della rientranza fu mantenuto perché poteva essere utile per evitare guerre di religione.

Ero anche ben consapevole del fatto che il codice leggibile usa volontariamente il rientro per indicare il raggruppamento, e mi ero imbattuto in sottili bug nel codice in cui il rientro non era d'accordo con il raggruppamento sintattico usando parentesi graffe: il programmatore e tutti i revisori avevano ipotizzato che il rientro corrispondesse al raggruppamento e quindi non notato il bug. Ancora una volta, una lunga sessione di debug ha insegnato una lezione preziosa.

Rossum ha anche assistito a bug a causa dell'incongruenza tra raggruppamento e rientro, e apparentemente sebbene basarsi sull'indentazione solo per strutturare il codice sarebbe più sicuro dagli errori di programmazione 1 .

Donald E. Knuth e Peter J. Landin

Nell'intervista citata, Guido menziona l'idea di Don Knuth di usare il rientro. Questo è dettagliato in La citazione dell'indentazione di Knuth riscoperta , che cita la programmazione strutturata con dichiarazioni goto . Knuth fa anche riferimento ai prossimi 700 linguaggi di programmazione di Peter John Landin (vedere la sezione Discussione sull'indentazione). Landin ha progettato ISWIM che assomiglia alla prima lingua con rientro anziché blocco iniziale / finale. Questi documenti riguardano più la fattibilità dell'uso del rientro per strutturare i programmi piuttosto che argomenti reali a favore di ciò.


1. Penso che questo sia in realtà un argomento a favore di avere sia costrutti di raggruppamento che di formattazione automatica, al fine di catturare e recuperare da errori di programmazione, che sono destinati ad accadere. Se rovini il rientro in Python, la persona che esegue il debug del tuo codice dovrà indovinare quale sia corretto:

if (test(x)):
  foo(x)
  bar(x)

Verrà barsempre chiamato o solo se il test avrà esito positivo?

I costrutti di raggruppamento aggiungono un livello di ridondanza che consente di individuare un errore durante il rientro automatico del codice. In C, il codice equivalente può essere indentato automaticamente come segue:

if (test(x))
  foo(x);
bar(x);

Se intendevo baressere allo stesso livello di foo, il rientro automatico basato sulla struttura del codice mi fa vedere che c'è qualcosa di sbagliato che può essere risolto aggiungendo parentesi graffe fooe bar.

In Python: Myths about Indentation , c'è un presunto cattivo esempio di C:

/*  Warning:  bogus C code!  */

if (some condition)
        if (another condition)
                do_something(fancy);
else
        this_sucks(badluck);

È lo stesso caso di cui sopra, in Emacs, evidenzio l'intero blocco / funzione, premo Tab e quindi viene reindirizzato tutto il codice. La discrepanza tra rientro umano e struttura del codice mi dice che qualcosa non funziona (questo e il commento precedente!).

Inoltre, il codice intermedio in cui il rientro è disattivato in C semplicemente non riesce a passare attraverso il ramo master, tutti i controlli di stile in atto mi farebbero gridare da GCC / Jenkins. Di recente ho avuto un problema simile a quello descritto sopra in Python, con una dichiarazione di un livello di rientro. A volte ho un codice in C che va oltre una parentesi graffa di chiusura, ma poi premo Tab e il codice rientra "erroneamente": è un'altra possibilità per vedere il bug.


3
"Per evitare guerre di religione ..." Sono sorpreso che la vera ragione sia così banale.
Robert Harvey,

1
@RobertHarvey: l'enfasi su quella frase è di coredump, non di van Rossum. Non è la ragione principale se leggi la citazione di van Rossum nel contesto.
JacquesB,

@JacquesB Per favore, dimmi quale contesto manca dalla citazione, in modo che io possa modificare la risposta.
coredump

4
Non ho commenti personali: se rovini il rientro in Python, allora hai un bug. Se rovini le parentesi graffe in C hai un bug. Se si utilizza il rientro automatico, è esattamente lo stesso in entrambe le lingue. E se non usi il rientro automatico, il bug può essere nascosto di nascosto in C in un modo che non è possibile in Python.
JacquesB,

2
@JacquesB perché digitare una parentesi graffa di chiusura è qualcosa che fai attivamente; non indentare abbastanza è qualcosa che puoi dimenticare di fare. Ovviamente puoi dimenticare di chiudere un tutore al momento giusto, ma alla fine dovrai farlo e avere un'altra possibilità di pensarci. Immagino che Python funzioni bene per i principianti perché forza l'attenzione sull'indentazione.
marstato,

7

Questo è altamente soggettivo e causa di molte guerre di fiamma. Tuttavia:

Avere simboli che delimitano blocchi e rientri viola il principio DRY , poiché esprimi le stesse informazioni in due modi diversi. L'esistenza di strumenti di rientro automatizzati è un sintomo di questa violazione DRY: il fatto che sia possibile generare automaticamente il rientro indica che si tratta di informazioni ridondanti e significa che rientro e simboli potrebbero non essere sincronizzati e portare a codice fuorviante.

Le FAQ sulla progettazione e la storia di Python lo indicano chiaramente:

Perché Python usa il rientro per il raggruppamento di istruzioni?

Guido van Rossum ritiene che l'uso del rientro per il raggruppamento sia estremamente elegante e contribuisca molto alla chiarezza del programma Python medio. Molte persone imparano ad amare questa funzione dopo un po '.

Poiché non ci sono parentesi iniziali / finali, non può esserci disaccordo tra il raggruppamento percepito dal parser e il lettore umano.

È vero che non puoi creare uno strumento di rientro automatico per Python, ma questa è una buona cosa: significa che non hai ridondanze nella sintassi che ti servono per automatizzare gli strumenti per la riconciliazione.

Le schede vs spazi è una preoccupazione legittima in Python e si consiglia di non mescolare mai schede e spazi (per il rientro) nella stessa base di codice.

Python ha ereditato la significativa indentazione dal linguaggio (ormai obsoleto) del predecessore ABC. ABC è uno dei pochissimi linguaggi di programmazione che hanno utilizzato i test di usabilità per dirigere la progettazione. Quindi, mentre le discussioni sulla sintassi di solito si riducono alle opinioni soggettive e alle preferenze personali, la scelta del rientro significativo in realtà ha una base più solida.


6
Anche la contabilità in partita doppia viola i DRY. La ridondanza è talvolta una caratteristica.
coredump,

3
@coredump: vero, ma è una ridondanza deliberatamente progettata. La maggior parte dei linguaggi di programmazione, incluso Python, contiene ridondanze scelte deliberatamente, ad esempio la passparola chiave che può essere dedotta automaticamente, ma che richiede che sia esplicita aiuta a scoprire errori. La ridondanza accidentale di avere entrambi i simboli di inizio / fine (per il compilatore) e il rientro (per il lettore umano) sembra causare più errori di quanti ne abbia colti. Almeno questa sembra essere l'opinione di van Rossum.
JacquesB,

@coredump - Ora so perché non sono un contabile.
JeffO

3
@coredump Ti manca anche COBOL PROCEDURE DIVISION.? Non so mai dove DATA DIVISIONfiniscano le procedure e le procedure in queste nuove lingue.
msw,

2
@coredump: "vedere l'indentazione contraddice ciò che avevo in mente è sufficiente per prevenire errori" - esattamente.
JacquesB,

2

I progettisti linguistici scelgono spazi bianchi sintatticamente significativi perché credono (o almeno pensano che i loro potenziali utenti credano) che i punti e virgola e le parentesi graffe aggiungano rumore durante la lettura del codice, danneggiando la produttività. Un altro motivo comune è che lo stile di codifica errato / incoerente danneggia la leggibilità - forzando uno schema di rientro comune, il linguaggio ha una migliore leggibilità soprattutto. Questa ragione successiva è meno importante ora che gli IDE di formattazione automatica sono più comuni, ma possono ancora essere applicati.


1
Vedo perché si considerano i punti e virgola e il rumore delle parentesi graffe. Ma non è meno produttivo dover digitare 4/8/12 volte lo spazio? E se ne manchi uno (dato che sono invisibili) sei nei guai.
Ripristina Monica il

5
Ecco perché usi le schede invece degli spazi o un IDE che capisce come convertire le schede in blocchi di quattro spazi.
Robert Harvey,

@ K.Gkinis: i rientri non sono invisibili. Solo gli spazi bianchi alle estremità delle linee sono invisibili, ma questo non è significativo in nessuna lingua. Solo se mescoli schede e spazi ti metterai nei guai. Quindi non farlo.
JacquesB,

@JacquesB: il problema con la visibilità / l'invisibilità del rientro è che come essere umano spesso non si può dire la differenza tra spazi e una scheda, mentre il computer può e spesso lo fa. Quindi, mentre il rientro è visibile, il modo in cui il computer interpreta il rientro può essere diverso. Questo è il vero problema: quando il computer tratta i personaggi invisibili in modo diverso rispetto agli umani. Gli umani misurano il rientro come distanza su uno schermo, i computer possono misurarlo come numero letterale di caratteri. questa è la parte invisibile.
Bryan Oakley,

@BryanOakley: Sì, è per questo che non dovresti mescolare tabulazioni e spazi nel rientro.
Jacques
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.