A cosa si riferisce specificamente il potere espressivo?


34

Il potere espressivo è definito da Wikipedia come:

.. l'ampiezza delle idee che possono essere rappresentate e comunicate in quella lingua.

Le "idee" si riferiscono alle cose (operazioni, strutture, algoritmi, ecc.?) Che possiamo comunicare alla macchina ? O si riferisce ai concetti "umani" che possono essere catturati e comunicati con la lingua ad altri umani?

Come viene valutata e misurata la potenza espressiva?

Ad esempio, se prendessimo una lingua come JavaScript e imponessimo una strana restrizione ai nomi delle variabili, come la variabile deve essere un numero di 8 cifre preceduto da un trattino basso, corrispondente/^_[0-9]{8}$/ , perderemmo il potere espressivo?

O sarebbe solo assurdo e fastidioso?


Chiarire:

Il potere espressivo è misurato dalle idee generali inerenti al linguaggio:

  • numeri interi e stringhe
  • loop
  • condizionali

O il numero di idee specifiche e uniche che la lingua può rappresentare:

  • gli interi 1, 2 ... 2 ^ 32
  • stringhe contenenti "cosa dice la volpe?" e "wha pah pah pah pah pah pow"
  • per ogni rana nella mia collezione di rane
  • se rana è verde o qualcosa allora fare qualcosa

3
Va notato che la limitazione di un programma a un massimo di 100 milioni di variabili in un determinato ambito impone un limite all'espressività. Ad esempio, potrebbe essere impossibile implementare Firefox. ;-)
R ..

1
Si noti che mentre si è taggati questi "linguaggi di programmazione", i linguaggi di programmazione non sono l'unico tipo di linguaggi per computer la cui potenza espressiva potrebbe essere discussa. In effetti, la pagina a cui ti colleghi ha Web Ontology Language come primo esempio.
Jon Hanna,

Risposte:


39

Il documento di riferimento sull'espressività è Il potere espressivo dei linguaggi di programmazione di Matthias Felleisen (1991) . Contiene una definizione matematicamente rigorosa dell'espressività del linguaggio.

Intuitivamente, se ogni programma che può essere scritto nella lingua A può anche essere scritto nella lingua B con solo trasformazioni locali, ma ci sono alcuni programmi scritti nella lingua B che non possono essere scritti nella lingua A senza cambiare la loro struttura globale (cioè non solo con puramente trasformazioni locali), allora il linguaggio B è più espressivo di lingua A .

Una bella proprietà di questa definizione è che ammette la possibilità che ci siano coppie di lingue in cui vi sono programmi in X che non possono essere espressi in Y e programmi in Y che non possono essere espressi in X , e quindi le lingue sono distinte, ma nessuna delle due il linguaggio è più espressivo dell'altro. Ciò si sposa bene con la nostra esperienza nel mondo reale in cui ci sono alcune lingue che sono brave in alcune cose e alcune che sono brave in altre cose, e nessuna delle due è generalmente "migliore" dell'altra.


Quindi, (non avendo ancora guardato il giornale) l'espressività riguarda ciò che puoi esprimere alla macchina rispetto ai lettori della fonte? È una misura di ciò che puoi istruire l'hardware a fare? Non è una misura di quante idee "umane" puoi conservare o comunicare in codice? ... Forse devo fare un'altra domanda; ma, in tal caso, in cosa differisce dalla "funzionalità" di cui parliamo?
svidgen,

Forse il mio esempio nell'OP è negativo. Considera le lingue A e B, entrambe con array; ma anche la lingua A ha delle strutture. In entrambe le lingue posso rappresentare una serie di Point's usando una matrice di array 2D. Ma A ha il vantaggio di lasciarmi esprimere un Pointconcetto più leggibile dall'uomo. A è più espressivo?
svidgen,

@svidgen Poiché tutte le lingue complete di Turing sono equivalenti dal punto di vista computazionale, l'insieme dei possibili programmi che possono essere scritti è teoricamente lo stesso per tutti. Secondo la definizione sopra, il linguaggio B è più espressivo di A se un programma scritto in B deve essere riorganizzato per adattarsi ad A. (Non solo cambiando la sintassi riga per riga, ma introducendo nuove classi, loop ecc. Pensa a riscrivere un Python programma in Java 7 che utilizza lambda, map, filter, di prima classe tipi / metodi / funzioni, magari un po ' eval, per non parlare di magia metaclasse o tipi creati dinamicamente ecc
marczellm

@marczellm, quindi, le "idee" a cui si riferisce l'espressività sono il linguaggio stesso? Ad esempio, un condizionale è un'idea? Un ciclo è un'idea? Una stringa? Numero? Eccetera.?
svidgen,

1
@ Jörg Puoi dare un esempio nella tua risposta? È una definizione carina, ma in realtà non fa molto per rispondere alla domanda.
svidgen,

10

Il potere espressivo è definito da Wikipedia come:

Diamo una nuova lettura a quella pagina. Una delle prime cose da notare è che dice "linguaggio", non "linguaggio di programmazione", e la maggior parte dei suoi esempi non sono linguaggi di programmazione, ad esempio il primo esempio dato è un confronto di OWL2 EL e OWL2 RL, che sono entrambi ontologia le lingue.

Si può applicare il concetto ai linguaggi di programmazione, ma anche linguaggi di corrispondenza dei pattern, linguaggi di markup, linguaggi di query, linguaggi di fogli di stile visivi, espressioni regolari (e tutti i linguaggi regolari a cui si riferiscono) e così via. Si può persino fare riferimento al potere espressivo delle lingue naturali come l'inglese, che viene spesso fatto in modo molto informale, ma con maggiore serietà quando si considerano i problemi relativi all'elaborazione del linguaggio naturale.

Le "idee" si riferiscono alle cose (operazioni, strutture, algoritmi, ecc.?) Che possiamo comunicare alla macchina? O si riferisce ai concetti "umani" che possono essere catturati e comunicati con la lingua ad altri umani?

Si riferisce a ciò che può essere espresso in quella lingua, considerata puramente come una cosa in sé.

Ad esempio, (userò javascript in tutto per i miei esempi, perché la tua domanda indica che è una delle lingue che conosci) considera l'istruzione javascript:

var x = 3 + 4;

Ciò rappresenta che viene calcolata la somma dei valori di 3 e 4 e il valore associato a un'etichetta xall'interno di un determinato ambito dello spazio dei nomi.

Se distruggessimo tutti i computer del mondo e scrivessimo quel codice su un pezzo di carta, rimarrebbe che in javascript avesse ancora lo stesso significato; non saremmo in grado di eseguire tale codice su nulla, ma la definizione astratta del linguaggio è ancora qualcosa di cui potremmo parlare.

Questo può sembrare pedante, ma in realtà è abbastanza importante che le lingue siano cose su cui si possa ragionare in astratto senza considerare i computer reali. Per prima cosa, il ragionamento delle persone sui punti teorici dei linguaggi informatici che non erano ancora fattibili nella pratica è una delle cose che ci ha portato dove siamo oggi; i computer hanno bisogno dell'informatica, ma l'informatica non ha bisogno dei computer, solo l'idea di un calcolo.

Certo, usiamo i computer nel mondo reale e oggigiorno ci sono molte persone che li usano in pratica piuttosto che alcuni specialisti che ne discutono in teoria. La pagina a cui ti sei collegato dice:

Il termine potere espressivo può essere usato con una serie di significati. Può significare una misura delle idee esprimibili in quella lingua:

  • indipendentemente dalla facilità (espressività teorica)

  • concisamente e prontamente (espressività pratica)

Il primo senso domina in aree della matematica e della logica che si occupano della descrizione formale delle lingue e del loro significato, come la teoria del linguaggio formale, la logica matematica e l'algebra dei processi.

Nelle discussioni informali, il termine si riferisce spesso al secondo senso, o ad entrambi. Questo è spesso il caso di discutere dei linguaggi di programmazione. Sono stati compiuti sforzi per formalizzare questi usi informali del termine

Di questi due usi del termine, l'impatto pratico del primo riguarda esclusivamente ciò che può essere trasmesso al computer.

Il secondo riguarda più la comprensione umana sia nella lettura che nella scrittura, sebbene il grado in cui lo fa, differisce molto tra gli usi, poiché sono informali e come tali non sono rigorosamente definiti.

Ad esempio, se prendessimo una lingua come JavaScript e imponessimo una strana restrizione ai nomi delle variabili, come la variabile deve essere un numero di 8 cifre preceduto da un trattino basso, corrispondente /^_[0-9]{8}$/, perderemmo il potere espressivo?

Per definizione formale, non abbiamo perso alcun potere espressivo: siamo limitati a 100.000.000 di variabili, ma se davvero ne avessimo bisogno potremmo aggirare il problema creando oggetti per contenere più variabili all'interno dello spazio dei nomi appena creato. Pertanto, qualsiasi programma scritto oggi in javascript potrebbe essere riscritto in questa nuova forma, quindi sono ugualmente espressivi.

Secondo la definizione informale, ne abbiamo perso un po ', ma quanto dipende da quanto siamo informali, il che varierà perché di nuovo non si può dire quale sia la "regola" su un uso informale. Potremmo dire di aver perso una piccola quantità, perché i programmi con più di 100.000.000 di variabili nello stesso spazio dei nomi devono essere riscritti oltre una semplice sostituzione. Un uso ancora più informale si riferirebbe all'impatto mentale di nomi così sgraziati e variabili sull'essere umano completo.

Vale anche la pena notare che le persone prenderanno in considerazione in modo informale cose che non fanno assolutamente parte della lingua. Considera le modifiche in Javascript dalla sua creazione fino ad oggi.

Secondo la definizione più formale, l'espressività è rimasta pressoché invariata; dopo tutto, era Turing completo.

Con una definizione più informale, è diventato considerevolmente più espressivo in certe cose come la manipolazione di array, la gestione delle eccezioni e (forse soprattutto) nell'inclusione di espressioni regolari. Questi non fanno nulla che prima non si potesse fare in javascript, anche se spesso possono fare qualcosa in poche righe e un tempo di esecuzione inferiore al secondo che richiederebbe kilobyte di codice per scrivere in javascript1.0 e molto tempo per essere eseguito.

Con una definizione molto più informale, la modifica dal primo utilizzo di javascript nei browser (in grado di cambiare i valori degli input del modulo, document.writementre la pagina viene prima analizzata e spostata in una nuova posizione o tornare indietro o avanti nella cronologia, ma piuttosto nient'altro) a quello di oggi (in grado di cambiare praticamente qualsiasi cosa sulla pagina, anche sulla base dei dati dalle chiamate del server) è assolutamente immenso, anche se la maggior parte non si riferisce a javascript ma ai modelli di oggetti e API realizzati disponibile, piuttosto che la lingua (ad esempio vbscript in IE ha beneficiato di tali cambiamenti allo stesso modo).

A mio avviso, quell'ultimo uso è così informale da non essere realmente corretto, ma questo è il problema con le definizioni informali.

Per definizione formale, in realtà non è diventato affatto più espressivo.


2
"I computer hanno bisogno dell'informatica, ma l'informatica non ha bisogno dei computer" Mi piace
chbaker0

Per quanto riguarda la limitazione della denominazione variabile, la capacità di fare riferimento a idee esterne (nomi in lingua nativa per cose) non è correlata alla capacità del linguaggio di rappresentare idee? ... Forse più alla radice della domanda: le idee di cui stiamo parlando esprimono solo i costrutti del linguaggio generale ? Ad esempio, addizione, sottrazione, negazione, matrici, classi, ecc.? Al contrario delle idee particolari che possiamo esprimere con la lingua? Ad esempio, array chiamato fishiesdi tipoFish .
svidgen,

Puoi vedere la mia modifica per ulteriori chiarimenti. ... Sembra quasi che tu stia dicendo che sono entrambi (riferendosi alla mia modifica); ma che il primo elenco è "formale" e il secondo elenco è "informale". In tal caso, esiste una norma per il modo in cui viene utilizzato in modo non qualificato nelle conversazioni? Oppure ... tendi semplicemente a chiedere chiarimenti?
svidgen,

4

Non penso che le regole di denominazione variabile catturino davvero ciò che si intende per "espressività". Penso che "espressività" si riferisca a cose più fondamentali. Consideriamo C # con Linq contro C # prima di Linq, per esempio. Dopo l'aggiunta di Linq, è diventato possibile scrivere query simili a SQL direttamente nel C #. Questo è molto più elegante rispetto alle alternative precedenti, ad esempio mettere SQL in string letterali e poi passarlo al server o iterare su una raccolta usando "for".

Un altro buon esempio potrebbe essere le lingue con ereditarietà basata sui prototipi. In quelle lingue, è possibile semplicemente aggiungere nuovi metodi a un'istanza o persino a una classe (con qualunque nome una "classe" possa andare in una determinata lingua ...) in fase di esecuzione. Non puoi farlo in C ++ o C #. Mancano questo grado di espressività rispetto ai linguaggi basati su prototipi. (C # ha il concetto di metodi di estensione, e si potrebbe certamente dire che aggiungono espressività.)


0

Come riferito dall'articolo di Wikipedia, il potere espressivo si riferisce all'insieme di programmi che possono essere espressi nella lingua. Tutto ciò che pensi come un "linguaggio di programmazione" (JavaScript, LISP, C #, Perl, ecc.) È essenzialmente Turing completo, nel senso che può esprimere qualsiasi cosa che si dice sia "calcolabile".

Tuttavia, dovrebbe essere abbastanza chiaro che le espressioni regolari non sono espressive come il normale linguaggio di programmazione. Inoltre, i caratteri jolly della shell sono in qualche modo meno espressivi delle espressioni regolari.

Una versione di SQL con espressioni di tabella comuni è più espressiva di una versione senza perché i CTE consentono di rappresentare query ricorsive che altrimenti sarebbero impossibili da esprimere in SQL.


0

Esiste un modo più semplice e diretto per comprendere il potere espressivo, ma prima dobbiamo stabilire cosa intendiamo per lingue. Esistono due discipline che studiano le lingue: linguistica e automi. Entrambi concorderebbero sul fatto che il linguaggio sia un insieme di parole (sequenze finite) costruite da un alfabeto finito usando la concatenazione. Tipicamente, le lingue interessanti (per interessante intendo tali lingue che possiamo interpretare in modo utile) hanno anche un insieme di regole che regolano quali parole sono nella lingua e quali no. Nota che l'espressività può esistere solo quando c'è interpretazione.

Per interpretazione intendo l'esistenza di una funzione che ha dato una parola in una lingua seleziona un oggetto da un insieme di oggetti (questo è ovviamente discutibile per i linguaggi naturali).

Non essere fuorviato dall'uso di "parola" però. Un programma Java è una parola nel linguaggio Java (sebbene possa estendersi su più file contenenti più stringhe di caratteri separati da spazi).

Sarebbe controproducente usare linguaggi così complicati come i moderni linguaggi di programmazione per affrontare questo concetto relativamente semplice, per questo motivo preferirei usare formule matematiche.

  • Definiamo la lingua A come tutte le formule che prevedono l'aggiunta di numeri interi.

  • Definiamo la lingua B come la lingua di tutte le formule che implicano la moltiplicazione di numeri interi.

In entrambi i casi non è consentito l'uso dell'elemento identità. Pertanto la lingua A contiene le parole "1 + 1", "1 + 2", "1 + 3", "2 + 3" e così via. La lingua B contiene le parole "2 * 2", "2 * 3", "2 * 4", "3 * 4" e così via. Assegniamo anche le consuete interpretazioni a "*" e "+" (aggiunta di numeri interi e moltiplicazione di numeri interi) ai rispettivi simboli. Quindi, l'interpretazione di "1 + 1" è 2 e l'interpretazione di "2 * 2" è 4.

Ora osserva che la lingua A è strettamente più espressiva della lingua B, poiché in numeri interi è vero che la moltiplicazione può essere lanciata come aggiunta ripetuta, ma non esiste un modo per rappresentare l'addizione come moltiplicazione in generale.


Riassumendo: si può dire che la lingua A è più espressiva della lingua B quando le loro funzioni di interpretazione condividono un co-dominio, ma l'immagine della funzione di interpretazione di B è un sottoinsieme proprio dell'immagine della funzione di interpretazione di A.


-1

TLDR: se una caratteristica è mancante ma può essere espressa in altri modi, non è una mancanza di espressività. Se riesci a immaginare un algoritmo nella tua mente o addirittura implementarlo in una lingua, ma un'altra lingua è in qualche modo strutturata in un modo che rende impossibile implementare l'algoritmo, è un problema di espressività *.

Le restrizioni alla denominazione delle variabili non riducono l'espressività (a meno che non ci siano così pochi nomi che non si possano più esprimere tutti gli algoritmi e non si possano falsificare le variabili con qualcosa come array + indici).

Un semplice esempio di mancanza di potere espressivo è questo: devi do_homeworke bring_down_trash. Questo è facilmente scritto nel codice:

do_homework();
bring_down_trash();

Questa soluzione sembra piuttosto semplice ma in realtà do_homeworke bring_down_trashnon sono ordinate, si potrebbe anche scrivere:

bring_down_trash();
do_homework();

Il che è ugualmente impreciso perché non esprime che non intendevamo far rispettare un ordine. Inoltre, non vogliamo utilizzare i thread. Vogliamo dire qualcosa del genere:

compiler_or_interpreter_pick_one(
    {
        do_homework();
        bring_down_trash();
    },
    {
        bring_down_trash();
        do_homework();
    }
);

Per quanto ne so, è molto difficile da esprimere in qualsiasi linguaggio di programmazione.

Un esempio che mi dà fastidio è che in Java è impossibile avere una matrice di oggetti. È possibile creare una serie di puntatori agli oggetti ma che non ha lo stesso layout di memoria (efficienza vocale).

Prendendo un esempio da un'altra risposta : C ++ non supporta l'aggiunta di metodi a una classe o un'istanza . Questo è vero, tuttavia, non limita l'espressività del C ++.

struct Extensible{
    std::vector<std::function<void(Extensible *)>> instanceExtensions;
    static std::vector<std::function<void(Extensible *)>> classExtensions;
};

Questa è una classe alla quale è possibile aggiungere, rimuovere e chiamare un numero arbitrario di funzioni membro per le istanze e la classe. Tecnicamente il C ++ è probabilmente più espressivo in questo senso rispetto ai linguaggi di programmazione che supportano effettivamente questa funzione perché in C ++ puoi scegliere come memorizzare le funzioni (vettore vs array vs forward_list).

* Alcune lingue hanno una mancanza di espressività come caratteristica. In genere rendono impossibile scrivere infiniti loop. Ciò può rendere risolvibile il problema di arresto e consentire prove automatiche per la correttezza.


2
Sono abbastanza sicuro che questo non sia corretto - almeno non è quello che capisco che sia. Scrivere binari grezzi su disco è espressivo da questa definizione, che è assurda.
Telastyn,

1
@Telastyn Perché sarebbe assurdo? Ovviamente solo scrivere un binario crudo su disco non è espressivo, ma un linguaggio che può farlo è più espressivo di uno che non può, tutto il resto è uguale.
nwp,

Voglio dire, il "linguaggio" che usa un'interfaccia hardware per scrivere bit grezzi sul computer è un esempio del linguaggio più espressivo, dal momento che può per definizione fare tutto ciò che il computer può fare. Può esprimere qualsiasi caratteristica mancante in altri modi. Trovo assurdo che per la vostra definizione, che è un linguaggio espressivo.
Telastyn,

@Telastyn Perché sarebbe il linguaggio più espressivo? Non può esprimere la lettura dei dati o il calcolo di qualcosa o la visualizzazione di grafici o thread. Un linguaggio che può solo scrivere bit in memoria e su disco ha una espressività così scarsa che metto in dubbio che ha un uso.
nwp,

1
"In genere rendono impossibile scrivere loop infiniti. Questo può rendere risolvibile il problema di arresto" - se non si può avere un ciclo infinito, per definizione, il programma deve arrestarsi.
Patrick Collins,
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.