Quali sono i problemi per i linguaggi stack oriented adatti e poco adatti?

7

La programmazione orientata allo stack è un paradigma piuttosto non ampiamente utilizzato (beh, PostScript viene usato sotto il cofano un po 'qua e là). Tenendo presente questo, quali sono i problemi con i linguaggi orientati allo stack? Cosa farebbero meglio di [paradigma]? Inoltre, per quali problemi sono una cattiva scelta?

La programmazione orientata allo stack è solo un paradigma di nicchia?

    
posta Anto 10.04.2011 - 21:55
fonte

4 risposte

15

Il problema principale con i linguaggi di programmazione stack-orient è che sono concettualmente abbastanza difficili da comprendere per gli umani. Il vantaggio è che è molto facile per i computer valutare e generare .

Ecco perché è stato scelto per PostScript. Non è passato molto tempo da quando le stampanti avevano solo una piccola quantità di memoria e CPU molto poco potenti. Quindi, dando loro programmi in un linguaggio che fosse facile da interpretare e facile da generare, non hai bisogno di un super-computer all'interno della tua stampante per valutare.

Ricorda inoltre che molte lingue oggi, anche se non sono orientate allo stack, in realtà vengono compilate in un bytecode stack-oriented (si pensi a Java e .NET). Di nuovo, il motivo per cui l'elaborazione stack-oriented è molto facile da ragionare su un computer.

    
risposta data 10.04.2011 - 22:17
fonte
6

Thorbjørn ha già fatto il punto sulla compilazione - se non ricordo male, il bytecode Java è un esempio di linguaggio orientato allo stack. Anche se questo non è universale. LLVM usa una cosa "assegnazione singola statica" che ha sicuramente uno stack, ma in cui gli accessi variabili locali e la valutazione delle espressioni usano un tipo di modello di registro virtuale scrivibile una volta-poi-immutabile. Per i dati mutabili, queste cose contengono fondamentalmente un puntatore immutabile.

In ogni caso, un linguaggio orientato allo stack può fare qualsiasi cosa che un Lisp -like o ALGOL -come il linguaggio può fare, a livello computazionale. Lo stack può anche avere metadati impliciti, facendo cose approssimativamente equivalenti all'infertimento di tipo in ML , ad esempio - valutato al momento della compilazione, senza eseguire una singola operazione di esecuzione o pop.

Il vero problema è la leggibilità, quindi la domanda è quale di questi trovi più leggibile ...

a * b + c * d
(+ (* a b) (* c d))
a b * c d * +

In linea di principio, la cosa con prefisso simile a Lisp poteva essere fatta senza parentesi - ma avrebbe dovuto usare un numero fisso di argomenti per operatore (proprio come postfix e infisso) per farlo. Penso che ci sia del vero nella vecchia battuta "Un sacco di parodie infuriate e stupide", ma che potrebbe essere evitata pur mantenendo l'ordinamento che viene prima dall'operatore. In altre parole, potresti scrivere un compilatore che accetti ...

+ * a b * c d

Su ciò che è più leggibile, è chiaramente discutibile. Infix è più familiare per i neofiti, ma non ci vuole molto per sentirsi a proprio agio con nessuno di questi moduli.

Personalmente, non sono nemmeno convinto che ciò sia considerato un paradigma. È solo una notazione, con poco o nessun impatto semantico. Ad esempio, tutte e tre le forme possono essere gestite utilizzando una Yacc grammatica - tutte e tre utilizzando esattamente lo stesso AST modulo, in modo che l'analisi semantica e la generazione del codice non abbiano nemmeno bisogno di sapere se la sintassi sembra essere" stack oriented ".

Modifica

Oops - Penso che il punto di base sia sopra, ma suppongo che dovrei dichiarare esplicitamente la mia risposta. Che è fondamentalmente IMO non c'è nessun problema particolare che favorisce nessuna di quelle notazioni. Le persone possono preferire l'una o l'altra, ma questa è una cosa diversa.

Ciò che i programmatori Lisp faranno notare, però, è che la metaprogrammazione funziona abbastanza bene con una notazione simile a Lisp. Si tratta più delle parentesi che di dove appare l'operatore, tuttavia - una variante di Forth che consentiva ...

(1 2 3 4 +)

... sarebbe altrettanto buono. Il vantaggio in entrambi i casi è la notazione semplice da manipolare usando il codice - la stessa ragione per cui le lingue intermedie orientate allo stack (bytecode, ecc.) Sono popolari. Sebbene si possa ragionevolmente, manipolare la forma AST agnostica per l'ordinamento può essere fatto abbastanza facilmente - questo è un po 'come l'abbinamento di modelli fa in Haskell e ML.

EDIT - Un chiarimento ...

Usare un modulo postfix / stack significa semplicemente questo. Ad esempio, non implica alcun cambiamento nell'ordine degli argomenti. I seguenti esempi possono essere tutti equivalenti, tranne la sintassi utilizzata per esprimerli ...

(< 1 2)
(1 < 2)
(1 2 <)

Nota: non è necessario scambiare l'ordine di 1 e 2 solo perché l'operatore è postfix

(if (< a b) (handle a_smaller) (handle b_smaller_or_equal))

((a b <) (a_smaller handle) (b_smaller_or_equal handle) if)
((a_smaller handle) (b_smaller_or_equal handle) (a b <) if)

Forse vorresti mantenere la condizione vicino al if , forse non lo faresti. O va bene.

Forth non esprime un if uno di questi modi, ma non c'è alcun motivo per cui un linguaggio postfix / stack oriented non possa farlo. Forth ha consentito solo numeri interi nello stack (almeno in origine), ma il Lisp consente di passare le espressioni con effetto collaterale come parametri non ha nulla a che fare con l'essere prefisso anziché postfix. Un linguaggio postfix potrebbe consentire il passaggio del codice come argomenti (ovvero, inserito nello stack).

    
risposta data 10.04.2011 - 22:48
fonte
2

Ho usato un paio di lingue orientate allo stack nel corso degli anni.

All'università, ho avuto alcuni divertenti amministratori di sistema confusi con programmi PostScript minuscoli che sembravano prendere una quantità coordinata di tempo per rendere solo una pagina di output. Sì, la stampante laser a cui avevamo accesso aveva più potenza in virgola mobile rispetto ai mini computer su cui ci avevano dato account, quindi era fantastico per fare mandelbrots .

Ho anche lavorato con transputers . Questi erano processori altamente ottimizzati per le prestazioni per transistor. Ogni bit di silicio aveva bisogno di tirare il suo peso, quindi aveva un set di istruzioni Huffman codificato (le istruzioni più comuni erano codificate in un singolo byte) e invece di avere un registro tradizionale aveva un paio di pile. Uno stack era a bassa priorità, l'altro alto, il che significava che aveva un tempo di commutazione di contesto (processo a priorità bassa alta) misurato in microsecondi anziché millisecondi, ottimo per una risposta veloce agli interrupt nei controller del robot che abbiamo creato.

Ho anche lavorato su alcuni sistemi robotici che utilizzavano processori Forth integrati che gestivano Forth praticamente come una macchina codice. Ricordo che avremmo acquistato il doppio delle CPU necessarie e le avremmo suddivise in base alle prestazioni, selezionando la metà migliore da inserire nei sistemi, perché era più economico acquistare più chip non classificati che acquistare un singolo chip valutato alla velocità avevamo bisogno che loro corressero. * 8' )

    
risposta data 12.04.2011 - 01:49
fonte
0

Forth è quasi morto, penso. C'è J, tuttavia, non so se abbia un'influenza notevole. Postscript non è realmente usato per la programmazione da parte degli umani, vero? Quindi direi che i linguaggi stack oriented virtualmente non esistono più.

Per quanto vedo, sono utili come sostituti per l'assemblatore su architetture hardware orientate allo stack. Firmware e cose del genere. Ma non sono sicuro che tale hardware esista più nell'area post processore a 16 bit.

    
risposta data 10.04.2011 - 22:12
fonte

Leggi altre domande sui tag