Analizzare un linguaggio di programmazione


10

In SICP , gli autori dichiarano ( Sezione 1.1 ) che esistono tre "meccanismi" di base dei linguaggi di programmazione:

  • espressioni primitive , che rappresentano le entità più semplici di cui la lingua si occupa

  • mezzo di combinazione , mediante il quale gli elementi composti sono costruiti da elementi più semplici

  • mezzi di astrazione , mediante i quali gli elementi composti possono essere nominati e manipolati come unità

Come posso analizzare un linguaggio di programmazione tradizionale (Java, ad esempio) in termini di questi elementi o meccanismi?


Hai già guardato in formato Backus-Naur esteso, EBNF o Backus-Naur Form, BNF prima? Può abbattere una grammatica simile a questi tre concetti, anche se non sono davvero sicuro di quali siano le tue intenzioni, quindi non so se sarà di aiuto o meno.
Jetti,

@Jetti - sì, ho, e no, non è quello che mi interessa. Sto davvero cercando di analizzare la semantica (domanda: è davvero la parola che sto cercando?) Dei linguaggi di programmazione, non le loro forme scritte (es. sintassi).

Risposte:


1

La distinzione tra espressioni primitive, mezzi di combinazione e mezzi di astrazione è utile quando si modellano i linguaggi di programmazione. Nota che questa non è una proprietà intrinseca del linguaggio: non puoi puntare su nessuna definizione di linguaggio e dire "questa caratteristica è inequivocabilmente un'espressione primitiva, quella caratteristica è inequivocabilmente un mezzo di combinazione". La distinzione è una proprietà del modello e modelli complessi possono resistere alla classificazione.

Un esempio da manuale di questi tre concetti è il calcolo lambda , che ha esattamente uno di ciascuno:

  • Le variabili x , y , ... sono le uniche espressioni primitive.
  • L'applicazione delle funzioni MN è l'unico mezzo di combinazione.
  • Astrazione lambda λx.M è l'unico mezzo di astrazione.

Quando si arriva a lingue con più funzioni, la modellazione può diventare più ambigua. In generale, un'espressione primitiva è quella che non puoi o non vuoi scomporre in componenti primitive. Ma è come l' atomo : è primitivo finché la scienza non avanza. Ad esempio, esiste una variante del calcolo lambda in cui le variabili usano numeri anziché nomi ( indici de Bruijn ), il che è particolarmente conveniente quando si modellano termini lambda per prove informatiche; e nelle prove informatiche, i numeri interi sono suddivisi in parti costitutive . Quindi in questi modelli, dopo tutto, le variabili non sono espressioni primitive.

In (un tipico modello di) Java, le espressioni primitive sono principalmente costanti e variabili. Mezzi di combinazioni includono i numerosi operatori; più precisamente, "espressione additiva" è un mezzo di combinazione con due fessure (il lato sinistro e il lato destro) o con tre fessure (i due lati più l'operatore) se si includono sia A + B che A - B sotto quel nome (nel qual caso gli operatori +e -sarebbero costrutti primitivi a sé stanti). Altri mezzi di combinazione includono sequenze di istruzioni I ; J , costrutti di loopwhile (…) {…}, e così via. Quindi hai costrutti come dichiarazioni di variabili, definizioni di funzioni, definizioni di classe e così via che sono entrambi mezzi di combinazioni (combinano nomi e tipi di parametri, corpi, inizializzatori, ...) e mezzi di astrazione (perché definiscono i nomi per il riutilizzo). È infatti abbastanza comune che i mezzi di astrazione siano anche mezzi di combinazione: combinano un nome con la sua definizione.


Bella risposta; hai avuto i problemi con cui stavo lottando - l'ambigua distinzione tra primitivi, combinazioni, ecc.

Cosa intendi esattamente per "variabile"? Non possono essere descritti come mezzi di astrazione perché hanno un nome?
morbidCode

@morbidCode Il concetto di variabile è complicato e la parola ha un significato diverso ma correlato nel calcolo lambda e in Java. Una variabile può essere considerata una "astrazione" poiché si riferisce a un valore non specificato. Tuttavia, non è un mezzo di astrazione: non crea il riferimento, è semplicemente un modo di usare l'astrazione esistente. Un'astrazione lambda crea un modo per utilizzare un blocco di codice come oggetto che può essere manipolato.
Gilles 'SO- smetti di essere malvagio' il

4

Pugnale ruvida:

Le espressioni sono proprio questo; ciò che costituisce un'espressione in Java. Non so se questo si espanderebbe per includere dichiarazioni o meno.

Le combinazioni includono espressioni composte, (variabili ?,) istruzioni, metodi, meccanismo di classe e pacchetti. Anche i moduli, una volta che sono nella lingua.

In Java, il mezzo più semplice di astrazione è una classe: nulla può esistere al di fuori di una classe. Esistono, forse, "strati" di astrazione: un metodo statico è probabilmente più semplice di un metodo di istanza, perché non richiede un'istanza.

I generici offrono un ulteriore livello di astrazione (e frustrazione).


@MattFenwick Un'espressione può consistere in una singola primitiva, le combinazioni di primitive e altre entità formano un'espressione composta (ancora un'espressione, ma non un'istruzione).
Dave Newton,

@MattFenwick Non lo sono, non sto dicendo che un'espressione sia una primitiva, sto dicendo che un'espressione può consistere in una sola primitiva. Non è possibile che una stringa sia una primitiva solo perché il linguaggio fornisce zucchero sintattico per essa, a meno che tu non voglia distinguere tra una stringa immediata e il riferimento che crea. Direi + è, perché non può essere agito in alcun modo.
Dave Newton,

Per quanto riguarda la tua parte: c'è un problema con l'implementazione di generici di Java?
Steven Evers,

2

Ecco la mia categorizzazione di base. Sto cercando di disegnare un parallelo con LISP.

Espressioni primitive

  • Tutti i valori primitivi, cose che puoi rappresentare usando valori letterali (numeri, valori booleani, ...)

Parallelo in LISP : atomi, numeri ed elenchi.

Mezzi di combinazione (modi in cui è possibile costruire strutture dati composte)

  • Array
  • Oggetti / strutture.

Parallelo in LISP : celle contro, elenchi

Mezzi di astrazione

  • Sintassi del flusso di controllo (if, while for)
  • Tutti gli operatori builtin ( +, -, *, /, ...)
  • Tutte le funzioni (in questa categoria includiamo classi e metodi)

Parallelo in LISP : funzioni, zucchero sintattico come let,define


Bella risposta! Pensavo che forse alcuni dei costrutti del flusso di controllo si sarebbero adattati ai mezzi di combinazione, comunque. Bei parallelismi con LISP, che aiutano molto.

Non proprio. Le matrici e gli oggetti giocano a un livello diverso, fanno parte della rappresentazione dei dati, non del linguaggio stesso. Gli inizializzatori di array fanno parte del linguaggio e sono un mezzo di combinazione. Gli operatori e i costrutti del flusso di controllo non sono mezzi di astrazione, perché non "immagazzinano" nulla per il riutilizzo. I mezzi di astrazione di solito danno un nome a un'entità per un futuro riutilizzo sotto quel nome.
Gilles 'SO- smetti di essere malvagio' il

0

Un linguaggio di programmazione è generalmente definito dalla sua sintassi e dalla sua semantica . Entrambi questi saranno definiti negli standard per la lingua.

La sintassi delinea come scrivere un programma valido e la semantica definisce cosa significa quel programma valido.

Nei tuoi casi, la sintassi ti dirà quali sono i tuoi primitivi, come li combini e come li astraggi. La semantica ti dirà cosa significano le combinazioni e le astrazioni.

Ad esempio, la sintassi ti dirà come scrivere un forciclo valido . La semantica ti dirà cosa fa il ciclo for.

Se vuoi davvero iniziare ad analizzare un linguaggio di programmazione, prendi una copia dello standard e vedi cosa c'è dentro. Vorrei davvero iniziare con un linguaggio semplice, come C, prima di approfondire Java. Vorrei anche leggere il resto del libro. Imparare perché i linguaggi di programmazione funzionano nel modo in cui funzionano mi ha reso un programmatore migliore, anche se non implemento i compilatori.


1
Aspetta cosa? "Semplice come C prima di approfondire Java." Mi hai perso in "Semplice come C".
corsiKa

Matt, credo di non capire davvero cosa stai facendo allora. Il libro che hai citato parla di entrambe queste cose, indipendentemente dal fatto che gli autori le chiamino esplicitamente sintassi e semantica o meno.
mpdonadio,

In effetti, la "sintassi" descrive precisamente le cose "più semplici" nelle lingue, gli atomi da cui è composta.
Ira Baxter,

La sintassi non cattura completamente ciò che è un programma valido, tutt'altro. Ad esempio, un programma sintatticamente corretto potrebbe non riuscire a controllare il tipo. Il programma AC che esegue l'istruzione x = ++x;non è valido anche se un tipico compilatore lo accetterebbe.
Gilles 'SO- smetti di essere malvagio' il

0

Non so se sia corretto, ma il modo in cui capisco la divisione è il seguente:

espressioni primitive , Questi sarebbero, cose come >>, +, *, /, int, booleano, variabili, metodi ecc.

mezzo di combinazione, questo può essere discutibile, o le sue cose come + e concact, o il parlare di idee più avanzate come eredità vs composizione e i metodi per farlo. Iniezione, nuovo operatore, estensione ecc.

mezzi di astrazione, questa sarebbe la sintassi usata per nominare variabili e metodi, nonché mezzi per creare interfacce, classi, classi statiche, metodi di sovraccarico ecc.

Tuttavia, è possibile che tu debba darci maggiori informazioni dal libro in modo da sapere esattamente cosa si intende lì.


Il libro è online gratuitamente; un link è indicato nel PO. In un certo senso mi sono sentito allo stesso modo means of combination: è difficile capire esattamente cosa appartiene lì. Bella risposta, però.

Sai di quali altri capitoli parla di combinazioni e astrazioni?
Bob,
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.