La sintassi conta davvero in un linguaggio di programmazione? [chiuso]


41

Uno dei miei professori afferma che "la sintassi è l'interfaccia utente di un linguaggio di programmazione", linguaggi come Ruby hanno un'ottima leggibilità e stanno crescendo, ma vediamo molti programmatori produttivi con C \ C ++, quindi come programmatori importa davvero che la sintassi dovrebbe essere accettabile?

Mi piacerebbe conoscere la tua opinione al riguardo.

Disclaimer: non sto cercando di iniziare una discussione. Ho pensato che questo fosse un buon argomento di discussione.

Aggiornamento: questo risulta essere un buon argomento. Sono contento che tutti voi vi stiate partecipando.


16
Hmm, questo sembra presumere che la sintassi C / C ++ sia cattiva? Certamente alcuni elementi dei modelli C ++ sono brutti, ma per quanto riguarda le lingue (storicamente), C / C ++ è ancora molto, molto leggibile.
Macneil,

2
bene conosco molti programmatori che non saranno d'accordo su questo, per lo più dalla comunità di ruby, è più leggibile che lis per quanto posso dire :)
Saif al Harthi,

9
È stato un corso teorico? Ricorda: i professori sono spesso alcuni dei peggiori programmatori. Non hanno idea di com'è là fuori allo stato brado.
Giobbe

2
La leggibilità è negli occhi di chi guarda :).
MAK,

8
Una buona sintassi non può migliorare una lingua miserabile. Ma una misera sintassi può peggiorare una buona lingua;)
Dario,

Risposte:


65

Sì lo fa. Se sei in dubbio, prendi APL , o J , o Brainfuck , o anche Lisp o Forth semplice e chiaro, e cerca di capire qualsiasi programma non del tutto banale su di esso. Quindi confrontare ad es. Python.

Quindi confronta lo stesso Python (o Ruby, o anche C #) con cose come Cobol o VB6.

Non sto cercando di dire che la sintassi pelosa è cattiva e la sintassi simile al linguaggio naturale è buona in tutte le circostanze. Ma la sintassi ovvia fa una differenza enorme. Tutto sommato, tutto ciò che puoi scrivere nel più bel linguaggio di programmazione che puoi anche scrivere come un programma di Turing machine - ma di solito non vuoi, vero?


26
Lisp è sicuramente comprensibile.
cbrandolino,

65
+1 per l'inclusione di Lisp nell'elenco delle lingue illeggibili.
asmeurer,

65
-1 per includere Lisp nell'elenco delle lingue illeggibili.
Paul Nathan,

27
La programmazione in generale è illeggibile per chi non lo sapesse. Così come la notazione musicale e le planimetrie architettoniche. (= XY) è leggibile quanto X == Y, per qualcuno che sa leggere.
Paul Nathan,

6
Ho adorato APL e, a meno che il codice non sia stato scritto intenzionalmente per offuscare (molto facile da fare), è stato abbastanza facile da leggere. Il potere della sintassi era che si potevano programmare algoritmi in 2 o 3 righe di codice APL che avrebbero richiesto dozzine o centinaia di righe di C, Fortran o COBOL. La concisione e il potere di un linguaggio come APL è importante per questa discussione perché cercare di leggere centinaia di righe di codice di un'altra lingua può essere frustrante quanto decifrare elementi oscuri di APL.
oosterwal,

11

In pratica penso che sia importante. La leggibilità è già stata discussa sopra. Un altro problema potrebbe essere il numero di sequenze di tasti necessarie per esprimere un'idea / algoritmo? Ancora un altro problema è quanto sia facile per i semplici errori di battitura essere catturati dall'occhio umano e quanta cattiveria possono causare.

Ho anche trovato utile in alcuni contesti analizzare e / o generare frammenti di codice tramite un altro programma per computer. La difficoltà di analizzare la lingua e / o generare il codice corretto influisce direttamente sulla quantità di sforzi necessari per creare / mantenere tali strumenti.


Grande osservazione sui refusi che sono facili da distinguere.

7
Ma in teoria non c'è differenza tra teoria e pratica.
Giobbe

10

Credo che il tuo professore si riferisca allo zucchero sintattico .

Zucchero sintattico è un termine di informatica che si riferisce alla sintassi all'interno di un linguaggio di programmazione progettato per rendere le cose più facili da leggere o da esprimere, mentre esistono modi alternativi di esprimerle .

Quindi, ciò che il tuo professore sta insinuando, è che qualunque codice / sintassi scritto in un linguaggio di programmazione, possa essere espresso in altre lingue nello stesso modo, o anche nella stessa lingua.

Robert Martin, tratto dal teorema di Programmazione Strutturata , ha sottratto ciò che i programmatori fondamentalmente fanno con i linguaggi di programmazione nel suo keynote a RailsConf 2010: Robert Martin (video YouTube, vedi dopo 14 minuti, anche se raccomando tutto):

  • Sequenza (assegnazione)
  • Selezione (se dichiarazioni)
  • Iterazione (do-loop)

Questo è tutto ciò che fanno i programmatori, da un linguaggio di programmazione a un altro, solo in una diversa sintassi o interfaccia utente (UI). Questo è quello che immagino stia arrivando il tuo professore, se parla in modo astratto dei linguaggi di programmazione.

Quindi, in sostanza , la sintassi non ha importanza . Ma se vuoi essere specifico, ovviamente alcune lingue e la sintassi sono più adatte per determinati compiti rispetto ad altri, per cui potresti argomentare che la sintassi è importante.


Chiameresti C solo uno zucchero sintattico per assemblatore?
Goran Jovic,

1
Vorrei. Ma sostengo che la sintassi sia importante. ;)
Lennart Regebro,

2
"... Robert Martin ha estratto ciò che i programmatori fondamentalmente fanno ..." Robert Martin? Robert Martin ?? Potresti davvero prendere in considerazione questo articolo: C. Böhm, G. Jacopini, "Diagrammi di flusso, macchine di Turing e lingue con solo due regole di formazione", Comm. dell'ACM, 9 (5): 366-371,1966. che di solito è accreditato come la fonte del "teorema del programma strutturato". it.wikipedia.org/wiki/Structured_program_theorem
leed25d

@ lee25d Non intendevo accreditare lo zio Bob come il creatore dell'astrazione, ma come la fonte in cui l'ho sentito di recente (e collegato). Ma grazie per il link, aggiornerò la mia risposta per riflettere il tuo link.
spong

Il pezzo di Wikipedia collegato sopra non comprende del tutto la storia del "teorema di programmazione strutturata". L'idea ha preceduto Bohm e Jacopini. Il contributo di Bohm & Jacopini stava dimostrando che era un teorema, non solo una congettura, cioè che forniva una rigorosa prova formale.
John R. Strohm,

7

Sì e no.

Esistono un paio di aspetti diversi della sintassi.

  • leggibilità
  • espressività
  • parsability

La leggibilità è già stata menzionata.

L'espressività è un caso interessante. Userò il passaggio di funzioni come esempio, perché è una specie di punto di flesso dolore semantico / sintattico.

Prendiamo ad esempio C ++. Posso creare una funzione di primo ordine dopo questa moda:

class funcClass
{
  int operator()(int);
}
funcClass fun;

void run_func(funcClass fun)
{
   fun();
}

Questo particolare linguaggio è comunemente usato negli Elementi di programmazione di Stepanov .

D'altra parte, posso imitare in Common Lisp con qualcosa come questo :

(defun myfunc() )

(defun run_func(fun)
  (fun))

Oppure, in Perl -

   sub myfunc
   {
   }

   sub run_func
   {
      my $func = shift;
      $func->();          #syntax may be a little off.
   }

Oppure, in Python -

def myfunc():
    pass

def run_func(f):
    f()

Tutti questi hanno - essenzialmente - lo stesso contenuto semantico, sebbene l'esempio C ++ abbia dei metadati di tipo. Quale lingua esprime al meglio l'idea di passare al meglio una funzione di ordine superiore? Il Lisp comune fa appena una variazione sintattica. Il C ++ richiede che venga creata una classe solo per "trasportare" la funzione. Perl è piuttosto semplice nel fare un certo livello di differenziazione. Lo stesso vale per Python.

Quale approccio si adatta meglio al dominio problematico? Quale approccio può meglio esprimere i pensieri nella tua testa con il minimo "disadattamento di impedenza"?

Nella mia mente, la paragonabilità è un grosso problema. In particolare, mi riferisco alla capacità dell'IDE di analizzare e tagliare la lingua senza fare errori. La riformattazione è utile. Le lingue delimitate da token tendono ad analizzare bene - ruby ​​/ c / pascal, ecc.

Considera però: i principali sistemi di ogni genere sono stati creati con ogni linguaggio serio per risolvere i problemi del mondo reale. Sebbene la sintassi sia una barriera per esprimere alcune cose, è una barriera aggirabile. Equivalenza di Turing e tutto il resto.


5

La sintassi è sicuramente importante, anche se tendi a notarla di più quando non è intuitiva e incoraggia i bug. Ad esempio, il famigerato scherzo "ultimo bug del mondo":

if (AlertCode = RED)
   {LaunchNukes();}

2
+1: Interessante, non ho mai visto (o riconosciuto) questo famigerato scherzo "ultimo bug del mondo". Ma posso vedere come, a seconda della sintassi di una lingua (o addirittura della semantica), il risultato di questo pseudo-codice potrebbe essere qualsiasi cosa. Dato anche l'angolo semantico, questo può davvero essere attribuito al classico caso di cattiva comunicazione culturale.
Stephen Swensen,

Questo è il motivo per cui dovresti usare i condizionali Yoda, cioè if(RED = AlertCode)non compilare mai perché il ROSSO è costante (o dovrebbe esserlo!)
Malfist,

4
@Malfist: E così vediamo che una sintassi errata porta a una sintassi ancora peggiore per compensare. I condizionali Yoda sono brutti e difficili da leggere perché non sono il modo in cui le persone pensano del concetto associato. Il mio punto era più "questo è (uno dei tanti motivi) per cui dovresti evitare la famiglia C ogni volta che è possibile".
Mason Wheeler,

1
Bene, per fortuna, quel codice ha due bug. Certo, entrerà sempre nel condizionale, ma lì dentro sta solo ottenendo un riferimento alla LaunchNukesprocedura e non invocandola mai. La crisi è stata evitata!
munifico

3
Dipende da ciò che REDè. Se è 0, LaunchNukes()non verrebbe mai chiamato.
dan04,

5

La sintassi è importante e posso darti due esempi di supporto: Dylan, che è un Lisp con una sintassi più convenzionale, e Liskell, che è Haskell con una sintassi simile a Lisp. In ogni caso, fu proposta una variante del linguaggio che aveva esattamente la stessa semantica, ma una sintassi radicalmente diversa.

Nel caso di Dylan, si pensava che il rilascio di espressioni S in favore di qualcosa di più convenzionale avrebbe aiutato ad attirare una gamma più ampia di programmatori. Si è scoperto che la sintassi non era l'unica cosa che impediva ai programmatori di usare Lisp.

Nel caso di Liskell, si pensava che l'uso di s-express avrebbe permesso un uso più semplice delle macro. Si è scoperto che le macro non sono davvero necessarie in Haskell, quindi neanche quell'esperimento ha funzionato.

Ecco la cosa: se la sintassi non avesse importanza per nessuno, nessuno dei due esperimenti sarebbe stato provato.


1
Dylan era troppo piccolo, troppo tardi rispetto alle altre lingue. Ciò che aveva a suo favore non poteva compensarlo. Non possiamo più supporre che sia un errore di sintassi di quanto non sia stato un errore nella denominazione.
Macneil,

@Macneil: hai ragione riguardo alla cosa troppo piccola, troppo tardi. Far cadere la sintassi di Lisp era solo l'ultimo chiodo nella bara. Non penso che sia stata la ragione principale del fallimento di Dylan, ma non sono sicuro di come riformulare la risposta per riflettere al meglio.
Larry Coleman,

Interessante, non sapevo che avevano la sintassi di Lisp in una versione precedente ... Era quando si chiamava Ralph? Il Newton Message Pad originariamente avrebbe avuto Dylan al centro. 15 anni dopo, abbiamo iOS con Objective-C al centro, il linguaggio minore dei due, IMHO.
Macneil,

Non ricordo i dettagli esatti su quando Dylan perse le espressioni s. Sono stato in agguato su comp.lang.lisp da molto tempo e ricordo l'argomento che emerge in una delle loro periodiche guerre di fiamma tra parentesi.
Larry Coleman,

Dylan è antecedente a Java e non credo che ci fossero molti C ++ a quei tempi.
Tom Hawtin - affronta l'

3

La risposta potrebbe essere nel separare ciò che "conta" in fattori informatici e fattori umani . Ci sono molti fattori umani nella sintassi:

  • leggibilità
  • succinctness
  • manutenibilità
  • Pedagogia
  • Prevenzione degli errori
  • Adeguatezza allo scopo: è un linguaggio REPL, un linguaggio di script o un linguaggio di sistemi di grandi dimensioni?

Per quanto riguarda il computer, l'unico problema della sintassi è se ci sono delle ambiguità che devono essere risolte e quanto tempo ci vuole per tokenizzare / analizzare il codice al momento della compilazione / interpretazione - ed è solo nel caso di quest'ultimo in cui l'overhead dell'analisi è un problema significativo.

Questo potrebbe essere il motivo per cui otterrai sempre una risposta "sì e no" a questa domanda, perché ci sono due aspetti.


1

Senza sintassi, non avremmo un "modello" comune da cui comunicare, a livello umano, l'intento di un blocco di codice. La sintassi fornisce un framework comune da cui i compilatori possono essere standardizzati; i metodi possono essere condivisi; la manutenzione può essere semplificata.


Perché la mia risposta è stata sottoposta a votazione negativa?
Estratto

1

Penso cosa che conta davvero sia l' accesso alle API e la disponibilità di funzionalità di basso livello (come il controllo e il blocco della memoria) quando necessario. La maggior parte delle altre lingue include queste funzionalità. Il problema è che quando hai bisogno di funzionalità aggiuntive devi spesso usare un linguaggio come C per implementarlo. Ed è complicato interfacciare C con la lingua che stai usando.

Per tutto tranne lo sviluppo web (e la matematica) ho scoperto che C / C ++ è ancora il linguaggio di un sistema operativo e di un'applicazione. È ciò che è supportato la maggior parte del tempo per un vero sviluppo di applicazioni multi-thread, preforming e multipiattaforma. E la sintassi di C va bene. Solo molto semplice e relativamente dettagliato. La sintassi straordinaria non ha molta importanza.Disponibilità di potenza e API Dobbiamo tutti interfacciarci con il codice di altre persone (che è il più delle volte scritto in C o suoi derivati).


Non ho scrupoli con C, ma la folla di ML / Haskell avrebbe probabilmente qualcosa da dire riguardo al threading.
Rei Miyasaka,

+1 per "Accesso API": penso che questo possa essere persino più importante delle funzionalità linguistiche.
Giorgio,

1

La sintassi è sicuramente importante. È terribilmente prezioso se la sintassi della lingua è abbastanza flessibile da permetterti di creare un linguaggio specifico del dominio comodo e leggibile per la tua applicazione. Se ne dubiti, immagina di fare problemi di algebra in latino prosaico, come è stato fatto prima del 18 ° secolo, o immagina di fare calcoli senza l'ormai familiare notazione di Leibniz. Certo, un testo di calcolo è illeggibile per un principiante, ma con la pratica possiamo usare il calcolo e la notazione di Leibniz per risolvere rapidamente una classe di problemi che richiedevano pagine di matematica con metodi classici. La programmazione è solo un altro pezzetto di matematica. Una notazione conveniente, vicina al dominio del problema, può fare un'enorme differenza nella produttività.


I DSL non riguardano solo lo zucchero sintattico. La semantica è una parte molto più preziosa. Va bene progettare eDSL che non aggiungano nulla a una sintassi esistente.
SK-logic,

@SK: certo, ma la semantica è sotto il completo controllo del programmatore. La sintassi è limitata dalla lingua di base. Possiamo creare comodi DSL in Groovy e in altre lingue, ma non tanto in Java.
Kevin Cline,

1

Ecco un programma che calcola la facoltà di 6:

S(K(S(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)KK))))))(S(K(S(S(K(SI))(SII)(S(K(SI))(SII))
(S(K(S(S(KS)(S(KK)(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))
(S(K(S(S(KS)(S(K(SI(KK)))(SI(K(KI)))))))(S(K(S(K(S(S(K(SI))(SII)(S(K(SI))
(SII))(S(K(S(S(KS)(SI(KK)))))(S(S(KS)(S(K(S(KS)))(S(K(S(KK)))(S(S(KS)K)
(K(SI(K(KI))))))))(K(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)))))))))))
(S(S(KS)K)(K(SI(K(KI)))))))))))(S(S(KS)K)(K(SI(K(KI))))))(S(S(KS)(S(KK)(S(KS)
(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)
(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)
(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))

La sintassi è minima:

expression: expression term | term
term: ‘(‘ expression ‘)‘ | combinator
combinator: 'S' | 'K' | 'I' 

Sembra esserci una convinzione comune che la sintassi sia ciò che rende difficile un linguaggio. Come spesso accade con le credenze comuni, è vero esattamente il contrario.

Nota che la sintassi LISP è leggibile (se non del tutto) perché ha molta più sintassi di quanto sopra. Quindi, se i fan di LISP ti dicono che "la sintassi non ha importanza", chiedi loro di essere conseguenti e prova il calcolo SKI. Dovranno ammettere che la sintassi un po 'non è poi così male.


Non riesco a capire il voto negativo. Questa è una risposta davvero perspicace. +1
scravy

0

Non penso che importi oltre le preferenze personali. A parità di tutte le prestazioni (prestazioni, capacità, ecc.), Allora posso capire perché si dovrebbe dare maggior peso a una sintassi del linguaggio, ma scegliendo di trasferire le prestazioni di linguaggi come c / c ++ o qualsiasi altro linguaggio più adatto al lavoro semplicemente a causa di la sintassi sembrerebbe una cattiva idea dappertutto.


6
Che ne dici di "time to market", "cost to benefit", ecc.?
Giobbe

0

Sì, la sintassi è importante, anche se in realtà solo per leggibilità. Confrontare:

for i in range(10):
   print(i)

(Sì, è Python) con

FOR(i<-RNG-<10){PRN<-i}

(Sì, è una lingua che ho appena inventato) Entrambi farebbero esattamente la stessa cosa, allo stesso modo, ma la sintassi è diversa e Python è più facile da leggere. Quindi sì, la sintassi è sicuramente importante. Anche lo "zucchero sintattico" conta.

 @property
 def year(self):
     return self._date.year

È più facile da leggere di

 def year(self):
     return self._date.year
 year = property(year)

0

Sì certo.

Se vuoi accendere una grande fiamma, chiedi alla gente, dove mettono il bracciale di apertura in linguaggi simili a C. intendo

void foo() {
  // blah
}

VS

void foo()
{
  // blah
}

o addirittura VS

void foo() 
{ // blah
}

E questa è solo la stessa lingua! Inoltre, chiedi loro degli spazi, dove li posizionano (nome della funzione e parentesi graffa, operatori ecc.).

1000 risposte sono garantite!


non voglio accendere una fiamma e finora ho avuto buone risposte e li ringrazio tutti per la partecipazione e l'aumento delle mie conoscenze e scommetto che altre persone l'hanno trovato utile
Saif al Harthi,

0

La sintassi è importante. Tuttavia, ai giorni nostri direi che conta quasi interamente a causa della leggibilità e non in termini di quantità di tasti necessari. Perché?

  • A meno che tu non stia scrivendo qualcosa di così semplice, se il numero di tasti che premi è il fattore limitante nella scrittura di un programma, allora o sei davvero, davvero schifo a scrivere o pensi molto, troppo velocemente.
  • Tutti gli IDE decenti in questi giorni hanno un gran numero di scorciatoie che significano che non è necessario digitare effettivamente tutti i personaggi che stai usando la maggior parte del tempo.

Detto questo, se è troppo dettagliato, può arrivare al punto in cui influenza la leggibilità. Preferirei vedere qualcosa del tipo:

foreach (String in stringList)

A:

per ogni stringa presente nell'elenco come indicato dalla variabile stringlist

...qualsiasi giorno!


0

La sintassi è importante per coloro che la stanno imparando, minore è la barriera all'ingresso, più la lingua potrebbe inizialmente essere popolare. Ma se la lingua è difficile o impossibile per esprimere se stessi in modo ricco e succinto, inizierà a appassire in popolarità.

Molto conciso e opaco (Perl) è altrettanto brutto quanto eccessivamente prolisso e prolisso (AppleScript).

È necessario un equilibrio, una barriera inferiore all'ingresso, un'elevata produttività e una facile manutenzione.


-2

Un'altra cosa da considerare è che i linguaggi di programmazione con una sintassi migliore sono più facili da analizzare, rendendo così il compilatore più facile da scrivere, più veloce e meno soggetto a bug.


3
Umm ... 10000 SLOC di parse.yin Ruby non sono d'accordo. C'è un motivo per cui ognuna delle 7 implementazioni Ruby attualmente o presto pronte per la produzione utilizza lo stesso parser e ogni singola implementazione di Ruby che abbia mai provato a sviluppare il proprio parser non è riuscita.
Jörg W Mittag,

E poi c'era il famigerato linguaggio ADA. Insieme alle specifiche della lingua c'erano 100 programmi che dovevano essere eseguiti correttamente per certificare il compilatore. C'erano alcune cose davvero sottili sulla sintassi. Per farla breve, OGNI inizio compilatore di ADA costruito ha lanciato alcuni di questi programmi. E non si trattava semplicemente di correggere un bug, ma dovevano ricominciare da capo. Anche se ha avuto un massiccio sostegno da parte del governo (tutti i contratti DOD hanno richiesto l'ADA), è morto miseramente.
Omega Centauri,

-2

Per dirla semplicemente: la sintassi in quanto tale non ha importanza. La semantica che puoi esprimere attraverso di essa conta.


5
Come esercizio, scrivi un parser complesso in C, quindi un driver di dispositivo in Haskell. La sintassi ti ha aiutato? Quindi fai il contrario, preservando rigorosamente la semantica di entrambi i programmi. </irony>
9000,

1
@ 9000: ho visto un paio di driver di dispositivo in Haskell. Non riuscivo a vedere nulla di particolarmente sbagliato in loro. Ti interessa elaborare?
Jörg W Mittag,

2
@ 9000, dato quanto sia difficile ottenere i driver di dispositivo proprio in C non sono sicuro di aver scelto un buon esempio.

1
@ 9000: quello era esattamente il mio punto. La natura concreta di un costrutto sintattico non ha importanza, è ciò che esprimi con esso. Un linguaggio di programmazione con la sintassi esatta di Haskell , ma che utilizza una diversa strategia di valutazione farà sì che un sacco di Haskell si esibisca in modo terribile o addirittura si blocchi in cicli infiniti. Quando si tratta di costrutti sintattici (o più ampi: caratteristiche del linguaggio), non è la loro sintassi concreta che conta, ma la loro semantica, cioè ciò che puoi esprimere con loro.
back2dos,

@ 9000, non sarà un problema scrivere un parser in un Haskell con sintassi simile a C (o un driver, usando C con una sintassi simile a Haskell).
SK-logic,
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.