Tutte le lingue sono sostanzialmente le stesse?


39

Di recente, ho dovuto capire la progettazione di un piccolo programma scritto in una lingua di cui non avevo idea ( ABAP , se devi saperlo). Potrei capirlo senza troppe difficoltà.

Mi rendo conto che padroneggiare una nuova lingua è un gioco con la palla completamente diverso, ma comprendere semplicemente l'intento del codice (in particolare il codice standard di produzione, che non è necessariamente complesso) in qualsiasi lingua è semplice, se conosci già un paio di lingue (preferibilmente uno procedurale / OO e uno funzionale).

È generalmente vero? Tutti i linguaggi di programmazione sono costituiti da costrutti simili come loop, istruzioni condizionali e messaggi che passano tra le funzioni? Ci sono linguaggi non esoterici che un tipico programmatore Java / Ruby / Haskell non sarebbe in grado di dare un senso? Tutte le lingue hanno un'origine comune?


4
Ti indirizzerò a Beating the Averages di Paul Graham. Puoi o meno voler leggere tutto, ma per la parte pertinente cerca l'intestazione "The Blub Paradox". Il signor Graham non può essere disturbato a mettere le ancore nel suo muro di testo, quindi non posso collegarmi direttamente ad esso.
kwatford,

4
Le lingue non hanno origine comune. Ma tutte le lingue cercano di risolvere qualche problema. Penso che sia in qualche modo analogo alla lingua parlata. Lo scopo è esprimersi. Non posso dire che sia semplice comprendere le lingue in base alla conoscenza di 1 procedura / OO / funzionale. Non l'ho fatto, ma se dovessi porre questa domanda, guarderei perl o lisp con molte parentesi e non sarei in grado di dire che conoscere 1 lingua di ogni tipo è sufficiente.
Shahkalpesh,

1
In tal caso: calcolo Lambda. Forse non è un linguaggio "reale", ma in un certo senso è la madre di tutti i linguaggi di programmazione. Una volta ho dovuto implementare un linguaggio funzionale tale da essere compilato in espressioni lambda (che sono state quindi interpretate direttamente). I risultati erano (almeno per me) illeggibili nonostante preservassero tutti gli identificatori rilevanti. Funzioni particolarmente ricorsive utilizzando il combinatore Y. L'unico modo pratico per capire cosa facessero alcune delle espressioni di esempio era valutarle a mano. Cose semplici come fibonnaci e merge sort erano illeggibili.
kwatford,

2
Se conosci linguaggi funzionali, dovresti sapere che i loop non sono possibili in tutte le lingue.
jalf

Piet è piuttosto diverso. :)

Risposte:


88

Le basi della maggior parte dei linguaggi procedurali sono praticamente le stesse.

Loro offrono:

  • Tipi di dati scalari: generalmente booleani, numeri interi, float e caratteri
  • Tipi di dati composti: matrici (stringhe sono casi speciali) e strutture
  • Costrutti di codice di base: aritmetica su scalari, accesso ad array / struttura, assegnazioni
  • Strutture di controllo semplici: if-then, if-then-else, while, per i loop
  • Pacchetti di blocchi di codice: funzioni, procedure con parametri
  • Ambiti: aree in cui gli identificatori hanno significati specifici

Se lo capisci, hai una buona conoscenza del 90% delle lingue del pianeta. Ciò che rende queste lingue leggermente più difficili da comprendere è l'incredibile varietà di strana sintassi che le persone usano per dire le stesse cose di base. Alcuni usano la notazione concisa che coinvolge la punteggiatura dispari (APL è un estremo). Alcuni usano molte parole chiave (COBOL è un rappresentante eccellente). Non importa molto. Ciò che conta è se la lingua è abbastanza completa da sola per svolgere compiti complessi senza farti strappare i capelli. (Prova a codificare un serio hacking di stringa nello script della shell di Windows DOS: è capace di Turing ma è davvero pessimo in tutto).

Offrono linguaggi procedurali più interessanti

  • Ambiti nidificati o lessicali, spazi dei nomi
  • Puntatori che consentono a un'entità di fare riferimento a un'altra, con allocazione dinamica della memoria
  • Imballaggio del codice correlato: pacchetti, oggetti con metodi, tratti
  • Controllo più sofisticato: ricorsione, continuazioni, chiusure
  • Operatori specializzati: operazioni su stringhe e array, funzioni matematiche

Sebbene non sia tecnicamente una proprietà del linguaggio, ma una proprietà dell'ecosistema in cui vivono tali lingue, sono le biblioteche che sono facilmente accessibili o fornite con il linguaggio come parte dello strumento di sviluppo. Avere una vasta gamma di funzioni di libreria semplifica / accelera la scrittura di applicazioni semplicemente perché non è necessario reinventare ciò che fanno le librerie. Mentre Java e C # sono ampiamente ritenuti buoni linguaggi in sé e per sé, ciò che li rende veramente utili sono le enormi librerie che ne derivano e le librerie di estensioni facilmente ottenibili.

Le lingue più difficili da comprendere sono quelle non procedurali:

  • Linguaggi puramente funzionali, senza assegnazioni o effetti collaterali
  • Linguaggi logici, come Prolog, in cui avvengono il calcolo simbolico e l'unificazione
  • Linguaggi di corrispondenza dei modelli, in cui si specificano forme che corrispondono al problema e spesso le azioni vengono attivate da una corrispondenza
  • Vincoli linguistici, che consentono di specificare le relazioni e risolvere automaticamente le equazioni
  • Linguaggi di descrizione dell'hardware, in cui tutto viene eseguito in parallelo
  • Linguaggi specifici del dominio, come SQL, reti di Petri colorate, ecc.

Esistono due principali stili di rappresentazione per le lingue:

  • Basato su testo, in cui gli identificatori denominano entità e flussi di informazioni sono codificati implicitamente in formule che utilizzano gli identificatori per denominare le entità (Java, APL, ...)
  • Grafico, in cui le entità vengono disegnate come nodi e le relazioni tra entità vengono disegnate come archi espliciti tra tali nodi (UML, Simulink, LabView)

I linguaggi grafici spesso consentono lingue secondarie testuali come annotazioni nei nodi e sugli archi. I linguaggi grafici di Odder consentono ricorsivamente grafici (con testo :) nei nodi e sugli archi. Linguaggi grafici davvero strani consentono ai grafici di annotazione di puntare ai grafici che vengono annotati.

La maggior parte di queste lingue si basa su un numero molto limitato di modelli di calcolo:

  • Il calcolo lambda (base per Lisp e tutti i linguaggi funzionali)
  • Sistemi postali (o tecniche di riscrittura di stringhe / alberi / grafici)
  • Turing machine (modifica dello stato e selezione di nuove celle di memoria)

Data l'attenzione della maggior parte dell'industria su linguaggi procedurali e strutture di controllo complesse, sei ben servito se impari bene una delle lingue più interessanti in questa categoria, specialmente se include un qualche tipo di orientamento agli oggetti.

Consiglio vivamente di apprendere Scheme, in particolare da un libro davvero meraviglioso: Struttura e interpretazione dei programmi per computer . Questo descrive tutti questi concetti di base. Se conosci queste cose, le altre lingue sembreranno piuttosto semplici, tranne per la sintassi sciocca.


3
Bella risposta! Come follow-up (c'è un modo per porre una domanda di follow-up in SO?), C'è una lingua che potrei padroneggiare e pretendere di comprendere tutti i concetti nel software di programmazione? Sarebbe Lisp (o un dialetto come Scheme)?

@Anirudh: non esiste un meccanismo formale di follow-up, ma potresti aprire una nuova domanda. Se contiene una logica e un link a questa domanda, potrebbe anche non essere chiuso. ;) Per rispondere al tuo seguito, credo fermamente che non ci sia una sola lingua, dal momento che i paradigmi sono troppo diversi.

@Anirudh: d'accordo con John Y, non ce n'è solo uno. Ma se sei relativamente nuovo nel settore, dovresti spendere molta energia per padroneggiare il paradigma procedurale (considero OO solo una specializzazione). Non sarebbe male guardare altri paradigmi (logica, vincolo, flusso di dati) per avere un'idea di come funzionano, ma per la maggior parte del lavoro industriale quotidiano, i linguaggi procedurali sono praticamente i re.
Ira Baxter,

1
Proprio come con le lingue naturali, "più difficile da capire" è soggettivo e dipende dalla prima lingua che impari.
NullUserException il

1
@NullUserException: questo suggerisce che dovresti scegliere attentamente la tua prima lingua, per massimizzare la comprensione degli altri. Questo è il punto di Scheme, e in particolare il libro SICP.
Ira Baxter,

6

I linguaggi di descrizione dell'hardware sono linguaggi di programmazione, ma concettualmente sono molto diversi. Prova VHDL o Verilog per dimensioni. Sono comuni per la programmazione di FPGA. (Ok, quindi non sono processori, ma sono dispositivi informatici di uso generale. E questi dovrebbero essere considerati hardware valido per argomenti di informatica.) Devi fare esplicitamente accadere le cose in serie. È un modello completamente diverso. Hai pensato alle cose che accadono in parallelo come la regola non l'eccezione. Per i loop in verilog espandersi in hardware parallelo. Quindi il comportamento "previsto" potrebbe non essere quello che ti aspetti.


È un buon punto. Cercherò Verilog / VHDL.

Ho sempre pensato che i linguaggi di programmazione convenzionali fossero solo modi davvero scadenti per codificare programmi che erano naturalmente paralleli, come VHDL. Quando inizi come progettista hardware, questa parte di tutto ciò che accade in modo seriale sembra incredibilmente goffa. (Stiamo insegnando i linguaggi di programmazione sbagliati alle persone come primo linguaggio: dovrebbe essere Verilog!).
Ira Baxter,

4

Dipende da cosa intendi per "sostanzialmente". Tutte le lingue di qualsiasi flessibilità sono complete di Turing. In questo senso: sì, sono praticamente tutti uguali.

A basso livello, eseguono tutti sequenze simili di operazioni e tutte le cose di Windows X, Linux e (recente) OS X vengono eseguite su processori compatibili Intel utilizzando gli stessi set di istruzioni. In tal modo sono sostanzialmente uguali.

Mi rendo conto che hai definito "sostanzialmente" la tua domanda, ma per rispondere davvero, quella definizione dovrà essere molto più raffinata. In molti modi sono tutti uguali. In molti modi sono distinti. È fin troppo facile dire "dipende". Se prendi uno dei due estremi, la domanda probabilmente non risponderà a ciò che intendi, quindi dove è disegnata quella linea è cruciale per rispondere alla tua domanda come la intendi.


3

Direi che una lingua codifica il significato. Se il significato ha un senso in qualche contesto, allora tutte le lingue che potrebbero esprimere il significato potrebbero essere considerate equivalenti limitate dal significato e dal contesto.

Se si limita quel contesto a una macchina Von Neumann standard, si potrebbe dire che l'origine dei significati computazionali di cambiare memoria e elaborazione in una CPU sia forse l'unico significato che tutte le lingue hanno in comune. Tutte le altre cose sono astrazioni basate su queste.


1
John von Neumann. E NON è pronunciato come "newman", più come "noyman".

Grazie per la correzione - pronuncio è come hai detto però.
Preet Sangha,

Quando qualcuno suggerisce una correzione, puoi semplicemente modificare il tuo post per rifletterlo.
Phil Miller,

2

I linguaggi di programmazione sono anche strumenti per pensare. Con un'altra prospettiva di pensiero, alcuni problemi scompaiono o si trasformano in tipi diversi e più gestibili (ad esempio, molti modelli di design in stile C ++ scompaiono solo quando si pensa in Lisp (vedere ad esempio questa presentazione di Peter Norvik ), ed Erlang ti libera dal pensare di alcuni concorrenti di basso livello o costrutti di calcolo distribuito e ti consente di concentrarti solo sulla logica dell'applicazione).

Si noti, tuttavia, che a volte i "nuovi" paradigmi possono essere parzialmente applicati a linguaggi di programmazione "più vecchi", il che spiega perché ad esempio abbiamo libri che insegnano la programmazione funzionale per i programmatori Java . Ma sostenere e integrare in modo nativo un paradigma più potente a livello linguistico consente un'applicazione più naturale del paradigma (e di conseguenza rende impossibile comprendere programmi in una lingua a supporto di paradigmi non familiari, come suggerito da altre risposte - @Ira Baxter che elenca i linguaggi non procedurali e @kwatford riferendosi a Paul Graham ).


2
+++++++[>+++++++++++<-]>+.<+++++++++++[>+++<-]>.>>+++++++[>++++++<-]>++++.

Al livello più basso, ogni linguaggio di programmazione è lo "stesso", ma ciò non significa che siano gli stessi al livello in cui interagisci effettivamente. Astraggono problemi per te; ciò non significa che astraggano gli stessi problemi o che astraggano ogni problema allo stesso modo.


1

Le lingue mature generalmente hanno alcuni obiettivi e fanno compromessi dove sacrificano una cosa per un'altra. Un linguaggio generico può essere utilizzato per qualsiasi cosa, ma nessun linguaggio può mai eccellere in ogni area. Alcuni esempi:

C tenta di essere un linguaggio di programmazione di sistemi ideale. A tal fine sacrifica la leggibilità e la sicurezza per il controllo e la velocità di basso livello.

Python mira ad essere un linguaggio di scripting ideale. A tal fine, sacrifica la velocità e la verificabilità per la produttività e la portabilità.

Haskell tenta di essere un linguaggio sicuro, matematicamente puro. A tal fine sacrifica l'apprendimento e le convenzioni per verificabilità e affidabilità.

Questi sacrifici e benefici fanno un'enorme differenza nella lingua. Sì, la maggior parte dei linguaggi di programmazione può essere utilizzata per tutto ciò che può essere fatto da un computer, ma nessuno di quegli stessi linguaggi dovrebbe essere usato per tutto. Tutte le lingue sopra sono quelle che sceglierei per determinati compiti ma non per altri. Se stessi programmando un sistema operativo, sceglierei C. Se stessi scrivendo un backend per un sito Web, userei Python. E se scrivessi un sistema finanziario userei Haskell.

Alla fine, la tua scelta come programmatore è lo strumento giusto per il lavoro.

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.