I linguaggi di programmazione dovrebbero essere rigidi o lenti? [chiuso]


14

In Python e JavaScript, i punti e virgola sono facoltativi.

In PHP, le virgolette attorno alle chiavi dell'array sono opzionali ( $_GET[key]vs $_GET['key']), anche se se le ometti cercherà prima una costante con quel nome. Inoltre, consente 2 diversi stili per i blocchi (due punti o delimitato da parentesi graffe).

Sto creando un linguaggio di programmazione ora e sto cercando di decidere quanto rigoroso dovrei farlo. Ci sono molti casi in cui i personaggi extra non sono realmente necessari e possono essere interpretati in modo inequivocabile a causa delle priorità, ma mi chiedo se dovrei ancora farli rispettare o non incoraggiare la coerenza.

Cosa pensi?


Va bene, il mio linguaggio non è tanto un linguaggio di programmazione quanto un linguaggio di fantasia. Una specie di incrocio tra i modelli Haml e Django . Pensato per essere utilizzato con il mio framework Web C # e dovrebbe essere molto estensibile.


22
Questo è un argomento per una guerra santa.

1
I pitonisti scoraggiano l'uso del punto e virgola. Francamente, non sono sicuro che siano necessari affatto - solo per consentire più dichiarazioni per riga, che possono essere totalmente evitate senza sofferenza. Quindi ... sono a favore di linguaggi più severi. Tuttavia, a volte è possibile applicare elementi al di fuori di un linguaggio con strumenti di analisi del codice, come StyleCop.
Giobbe

1
Le virgolette per le chiavi dell'array PHP non sono facoltative. Erano in PHP2, ma le versioni successive definivano automaticamente le costanti. Tuttavia, non sono consentite nell'interpolazione di stringhe di base "..$_GET[raw]..".
mario,

1
@Ralph: le regole sono un po 'più complicate. È corretto scrivere "xx$_GET[raw]xx"- Se si inizia a utilizzare parentesi graffe, la chiave deve essere racchiusa "xx{$_GET['raw']}xx"tra virgolette. Se vengono utilizzate parentesi graffe, il normale parser PHP lo controlla e si applica la sintassi rigorosa. È solo per questo "$_GET[x]"che la chiave viene trattata come stringa non elaborata, ed è anche una regola rigorosa, PHP analizzerebbe l'errore "$_GET['x']".
Mario,

2
@mario: Il fatto stesso che stiamo anche avendo questa conversazione significa che c'è un po 'di ambiguità e confusione nel modo in cui vengono gestite le chiavi dell'array. Sembra all'interno di stringhe, è inequivocabile ma incoerente (non è possibile utilizzare le virgolette quando si è già in una stringa, a meno che non si utilizzino parentesi graffe, quindi è necessario, ma all'esterno si dovrebbe). E stringhe esterne, in PHP "normale" ... beh, fa strane cazzate così.
Aprire il

Risposte:


19

Diversi tipi di lingue hanno usi diversi, quindi la risposta a questa domanda dipende davvero da cosa la userete.

Ad esempio, Perl è un linguaggio molto sciolto, e lo trovo molto utile per la scrittura di correzioni rapide o script per scricchiolare i numeri. Per progetti solidi e solidi uso C #.

È necessario ottenere l'equilibrio giusto per l'utilizzo target. Più è rigoroso, più tempo è necessario per scrivere il codice, ma si ottiene una maggiore robustezza, riusabilità e facilità di manutenzione.


26

Quello che cerco in un linguaggio di programmazione (al contrario di un linguaggio di scripting) è coerenza e digitazione forte.

Negli attuali linguaggi di programmazione è possibile omettere il punto e virgola, ad esempio, in alcuni punti senza diventare ambiguo (l'ultima espressione in un {}blocco è una). Se un linguaggio di programmazione ti consente di omettere i caratteri in questi casi, un programmatore ora ha un problema in più; oltre alla sintassi del linguaggio generale, ora deve sapere in quali casi è consentito omettere anche parti della sintassi.

Questa conoscenza aggiuntiva non è un problema per il programmatore che scrive il codice, ma diventa un peso per chiunque debba interpretare il codice esistente in un secondo momento (incluso l'autore originale dopo un po ').

Il tuo esempio PHP apre la possibilità di bug sottili in un programma quando la costante keyverrebbe aggiunta nello stesso contesto. Il compilatore non ha modo di sapere che non è ciò che intendeva, quindi il problema diventa evidente solo in fase di esecuzione anziché in fase di compilazione.


1
D'accordo, dovresti limitare le possibilità per gli sviluppatori: più possibilità => bisogno di pensare di più (dovrei procedere in questo modo o in quel modo) => meno tempo per fare il vero lavoro
Kemoda,

Non riesco a capire cosa abbia a che fare la mancanza di cast impliciti con la sintassi di un linguaggio.
dan_waterworth,

5
Inoltre, quando leggi $_GET[key]non sai nulla. Finisci per aggirare l'intero progetto solo per sapere se keyè una costante o no. Una cosa del genere risparmia 0,5 secondi di scrittura e richiede 20 secondi per la lettura.
Moshe Revah,

Se la tua lingua ti offre opzioni senza distinzioni, lo stile di codifica - codificato o meno - tende a standardizzare su uno di essi ...
Deduplicatore

11

In ogni luogo in cui c'è qualche ambiguità, il compilatore deve avere un modo per indovinare cosa intendesse realmente il programmatore. Ogni volta che ciò accade, c'è la possibilità che il programmatore abbia davvero significato qualcosa di diverso, ma non ha avuto la regola della risoluzione dell'ambiguità giù.

Scrivere un codice logicamente corretto è già abbastanza difficile. L'aggiunta di ambiguità sintattiche può sembrare "amichevole" in superficie, ma è un invito aperto a introdurre nuovi bug inattesi, difficili da debug nella base di codice. In conclusione, sii il più rigoroso possibile.

Dal tuo esempio, hai affermato che i punti e virgola sono facoltativi in ​​Python e JavaScript. Per Javascript, almeno, questo non è del tutto vero. I punti e virgola sono richiesti in JS come in qualsiasi altra lingua della famiglia C. Ma il parser JavaScript è richiesto dalle specifiche della lingua per inserire punti e virgola mancanti in determinate circostanze. Questo è ampiamente considerato come una cosa molto brutta perché tende a sbagliare le intenzioni e rovinare il codice.


6

La risposta a quanto dovresti fare la tua lingua è uguale alla risposta della domanda pronunciata con un accento texano "Quanto ti senti fortunato, punk?".


Non capisco
aprono il

4
Il mio brutto tentativo di scherzo è stato che la digitazione dinamica potrebbe morderti man mano che i sistemi diventano sempre più grandi, specialmente quando si aggiungono sviluppatori inesperti al mix. Nella mia esperienza, i sistemi di qualsiasi valore tendono a diventare sempre più grandi e hanno un numero crescente di sviluppatori che li sviluppano. Avere "Trova tutti gli usi del simbolo" o "Rinomina tutto" o "Eliminazione sicura" o "Trova errori nella soluzione" è quindi assolutamente prezioso. La tipizzazione dinamica nel senso limitato del fatto che VB è in ritardo e fa estendere la coercizione del tipo ha causato molti bug durante il concerto attuale.
Henrik,

Ergo, se ti senti fortunato per il tuo progetto, ad esempio fortunato ad avere sviluppatori validi ed esperti, o fortunato in termini di scrittura del codice corretto; puoi usare la digitazione dinamica.
Henrik,

2
Ah ... ma questa domanda non ha mai riguardato la digitazione dinamica :)
apre il

1
Ah, vero Raplh. Tendo a pensare ai linguaggi dinamici come più sciolti in quanto di solito sono più sciolti. Hai ragione però.
Henrik,

4

Tutti non dovrebbero lavorare così duramente per la coerenza del codice se le lingue non presentassero tanta variazione. Non ci piace quando gli utenti fanno richieste che aumentano inutilmente la complessità, quindi perché dovrebbe essere richiesto quello dei nostri linguaggi di sviluppo?


+1: sono totalmente d'accordo. Non vedo perché principi come KISS e YAGNI non dovrebbero applicarsi al design del linguaggio.
Giorgio,

2

La mia preferenza personale è per la capacità di avere la rigidità sufficiente per catturare i miei errori di battitura, ma con il minor numero possibile di boilerplate. Parlo di questo problema a http://www.perlmonks.org/?node_id=755790 .

Detto questo, stai progettando la tua lingua per te stesso. Dovresti farlo diventare quello che vuoi che sia.


+1: ... La capacità di avere la rigidità necessaria per catturare i miei errori di battitura, ma con il minor numero possibile di boilerplate. - Sì. Conosci il piano di Anders Hejlsberg per C #? Sta prendendo una decisione consapevole di enfatizzare "l'essenza sulla cerimonia". channel9.msdn.com/Blogs/matthijs/…
Jim G.

@ jim-g: grazie per il pensiero. Non ho familiarità con gran parte di nulla su C #. Non lavoro nel mondo Microsoft da molti, molti anni.
btilly,

1

Mi piace che le mie lingue facciano ciò che intendo. Generalmente questo si appoggia piuttosto duro verso sciolto. Vorrei anche essere in grado di taggare "rigoroso" su un elemento o blocco per poter eseguire il debug / analizzare quell'area limitata.


1

In genere tendo a schierarmi dalla parte di "Cosa mi renderebbe più facile come programmatore". Naturalmente ciò può significare più di una cosa. In Javascript non c'è quasi nessun controllo del tipo, che funziona benissimo fino a quando non si colpisce uno strano bug. D'altra parte in Haskell c'è un sacco di controllo del tipo che mette in primo piano il lavoro ma blocca alcune classi di bug.

Ad essere sincero, darei un'occhiata a un sacco di lingue per vedere cosa fanno e provare a trovare una nicchia che nessuno di loro colpisce!

Non penso che esista un modo giusto ovvio per farlo, o almeno se non c'è ancora qualcosa su cui la gente abbia trovato un consenso. Quindi, creando lingue con sistemi di tipo diverso, stiamo imparando.

In bocca al lupo.


1

Suggerirei che un buon linguaggio di programmazione dovrebbe avere regole rigorose, che le implementazioni dovrebbero applicare in modo coerente, ma che le regole dovrebbero essere scritte in modo tale da essere utili. Suggerirei inoltre di prendere in considerazione l'idea di progettare una lingua per evitare casi in cui la "distanza di Hamming" tra due programmi sostanzialmente diversi è solo una. Ovviamente non si può ottenere una cosa del genere con valori letterali numerici o di stringhe (se un programmatore che intendeva 123 invece digita 1223 o 13, il compilatore non può ben sapere cosa significasse il programma). D'altra parte, se la lingua dovesse essere usata :=per il compito e ==per il confronto di uguaglianza, e non usarne una sola= per qualsiasi scopo legale, ridurrebbe notevolmente le possibilità sia di incarichi accidentali che dovevano essere confronti, sia di confronti accidentali del nulla che dovevano essere compiti.

Suggerirei che mentre ci sono luoghi in cui è utile per i compilatori dedurre le cose, tale inferenza è spesso più preziosa nei casi più semplici e meno preziosa nei casi più complicati. Ad esempio, consentendo la sostituzione di:

  Dizionario <complicatedType1, complicatedType2> item =
    nuovo dizionario <complicatedType1, complicatedType2 ()>;

con

  var item = new Dictionary <complicatedType1, complicatedType2 ()>;

non richiede alcuna inferenza di tipo complicata, ma rende il codice molto più leggibile (tra l'altro, utilizzando la sintassi più dettagliata solo negli scenari in cui è necessario, ad es. perché il tipo di posizione di archiviazione non corrisponde esattamente al tipo dell'espressione crearlo, aiuterà a richiamare la massima attenzione sui luoghi che potrebbero richiederlo).

Una delle maggiori difficoltà nel tentare un'inferenza di tipo più sofisticato è che possono sorgere situazioni ambigue; Suggerirei che un buon linguaggio dovrebbe consentire a un programmatore di includere informazioni che il compilatore potrebbe utilizzare per risolvere tali ambiguità (ad esempio considerando alcuni tipi di caratteri come preferibili ad altri), determinare che non contano (ad esempio perché anche se due possibili i sovraccarichi possono eseguire codice diverso, il programmatore ha indicato che dovrebbero comportarsi in modo identico nei casi in cui uno potrebbe essere utilizzato) o contrassegnare quelli (e solo quelli) che non possono essere gestiti in nessuno dei due modi precedenti.


1

Per me, la leggibilità è molto importante.

Per qualcuno che ha esperienza con la lingua, il significato di un frammento di codice dovrebbe essere chiaro senza dover analizzare a fondo il contesto.

La lingua dovrebbe essere in grado di contrassegnare gli errori il più spesso possibile. Se ogni sequenza casuale di caratteri crea un programma sintatticamente corretto, non è utile. E se le variabili vengono creati automaticamente la prima volta che vengono utilizzati, quindi errore d'ortografia clientcome cleintnon vi darà un errore di compilazione.

Oltre alla sintassi, il linguaggio dovrebbe avere una semantica chiaramente definita, e forse è ancora più difficile che decidere su una sintassi decente ...

Buoni esempi:

  • In Java, "1"è una stringa, 1è un int, 1.0è un doppio ed 1Lè un lungo. Uno sguardo e sai di cosa si tratta.

  • In Java, =è il compito. Assegna il valore per i tipi primitivi e il riferimento per i tipi di riferimento. Non copia mai dati complessi o confronti.

  • In Java, chiamare un metodo richiede parentesi e in questo modo è chiaramente distinto dalle variabili - quindi, se non c'è parentesi, non è necessario cercare una definizione di metodo, è solo leggere i dati.

Cattivi esempi:

  • In Java, un simbolo simile clientpuò essere praticamente qualsiasi cosa: un elemento del percorso del pacchetto, un nome di classe o di interfaccia, un nome di classe interno, un nome di campo, un nome di metodo, una variabile locale e altro ancora. Spetta all'utente introdurre o obbedire alle convenzioni di denominazione o meno.

  • In Java, il punto .è sovrautilizzato . Può essere separatore all'interno del nome del pacchetto, separatore tra pacchetto e classe, separatore tra classe esterna e interna, connettore tra espressione dell'istanza e metodo da invocare sull'istanza e molti altri.

  • In molte lingue, le parentesi graffe dei ifblocchi sono opzionali, portando a cattivi errori se qualcuno aggiunge un'ulteriore istruzione al blocco (non realmente esistente).

  • Operatori Infix: a volte devo fermarmi a un'espressione numerica e pensare attentamente cosa significhi, passo dopo passo. Siamo tutti abituati a scrivere espressioni matematiche in notazione infissa come a * b / c * d + e. Il più delle volte ricordiamo la precedenza della moltiplicazione e della divisione sull'addizione e la sottrazione (ma ti sei reso conto che non stiamo dividendo c*d, ma dividendo solo per ce poi moltiplicando per d?). Ma ci sono così tanti operatori infix aggiuntivi con le proprie regole di precedenza e in alcune lingue sovraccarico che è difficile tenere traccia. Forse far rispettare l'uso delle parentesi era stato un approccio migliore ...


Hai parlato principalmente di ambiguità, ma possono esserci più modi per fare la stessa cosa senza creare ambiguità. Forse possiamo avere due operatori di moltiplicazione *e ×. Entrambi 5*3e 5 × 3` significano la stessa cosa, e un programmatore esperto sa esattamente cosa significano senza dover guardare il contesto circostante. Il problema, tuttavia, è che ora ci sono due modi per fare la stessa cosa e qualcuno potrebbe scambiarsi tra loro durante il programma. Credo che questo sia ciò di cui ero più preoccupato quando ho posto la domanda.
Aprire il

-2

Potresti considerare un'analogia con il linguaggio naturale. In email, sei un nazista grammaticale? Oppure stai bene con alcuni errori grammaticali, come infiniti divisi, congiunzioni mancanti o modificatori fuori posto. La risposta si riduce alle preferenze personali.

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.