"Quale espressività utile sarà impossibile in una lingua in cui un'espressione non è una dichiarazione?"
Nessuno.
Le definizioni di "espressione" e "affermazione" sono in gran parte arbitrarie. Diverse lingue li definiscono in modo diverso. Non conosco alcun linguaggio di programmazione il cui modo di definire questi termini renda ogni particolare impossibile da esprimere. In alcune lingue, alcuni costrutti potrebbero essere un po 'più scomodi; in altri, potrebbe essere più semplice scrivere codice difficile da leggere perché una singola istruzione dipende da più effetti collaterali.
Quasi tutti i linguaggi di programmazione sono Turing-complete e sono in grado di esprimere gli stessi comportamenti di qualsiasi altra lingua completa di Turing .
Due buoni esempi sono Pascal e C.
In Pascal, un compito è un'affermazione, non un'espressione. Una subroutine può essere una procedura (che non restituisce un valore) o una funzione (che lo fa). Una chiamata di procedura è un'istruzione e non può far parte di un'espressione. Una chiamata di funzione è un'espressione e non può apparire in un'istruzione se non si fa esplicitamente qualcosa con il risultato, ad esempio assegnandolo a una variabile. Le dichiarazioni possono contenere espressioni, ma le espressioni non possono contenere dichiarazioni.
In C, un compito è un'espressione. Tutte le subroutine sono funzioni; le funzioni che non restituiscono alcun valore sono dichiarate con un tipo di ritorno di void
. Una chiamata di funzione è un'espressione; può essere trasformato in una dichiarazione aggiungendo un punto e virgola. Il risultato di una chiamata di funzione o di qualsiasi espressione può essere scartato in modo silenzioso. Qualsiasi espressione può essere trasformata in una dichiarazione aggiungendo un punto e virgola. Come in Pascal, le istruzioni possono contenere espressioni, ma le espressioni non possono contenere istruzioni (ma gcc fornisce espressioni di istruzioni come estensione di lingua).
Ecco un tipico costrutto C che dipende dalla capacità di trattare i compiti come espressioni ( item
è un tipo arbitrario e last_item
è una costante di quel tipo):
item x;
while ((x = get_next_item()) != last_item) {
do_something_with(x);
}
In Pascal, puoi implementare esattamente lo stesso comportamento come questo (se ricordo correttamente la sintassi):
var
x: item;
done: boolean = false;
begin
while not done do
begin
x := Next_Item;
if x = last_item then
done := true
else
do_something_with(x);
end;
end;