È possibile che un linguaggio di programmazione basato su stack sia simultaneo?


14

Ho letto dei linguaggi di programmazione basati su stack, come FORTH e Cat , e sembra che, data la loro natura, possano eseguire solo un'azione alla volta indipendentemente dal loro paradigma (FORTH è un imperativo mentre Cat è funzionale).

Un linguaggio imperativo modifica lo stack e un linguaggio puramente funzionale, come Joy , restituisce un nuovo stack, ma il punto è che viene utilizzato solo uno stack alla volta.

Quindi, i linguaggi di programmazione basati su stack possono essere simultanei? Potrebbero raggiungere la concorrenza usando più stack contemporaneamente o qualcosa di simile?

È possibile implementare la valutazione pigra in un linguaggio di programmazione basato su stack?

Per favore, correggimi se sto fraintendendo qualcosa sulle lingue e sui concetti sopra menzionati


5
Come può un linguaggio imperativo essere simultaneo?
Bergi,


Intendi davvero concorrenza (che non è così difficile da ottenere, basta usare più thread in esecuzione con stack indipendenti più memoria condivisa) o parallelismo?
Daniel Jour,

@DanielJour se ho capito bene, parallelismo significa esecuzione simultanea mentre concorrenza significa esecuzione indipendente, quindi sì, intendo concorrenza. Potresti approfondire le pile indipendenti per ogni thread?
Armando H.

Risposte:


16

Quindi, i linguaggi di programmazione basati su stack possono essere simultanei?

Sicuro.

Potrebbero raggiungere la concorrenza usando più stack contemporaneamente o qualcosa di simile?

Già per le lingue normali il multi-threading di solito significa avere più stack di "chiamata". Sarebbe del tutto naturale assegnare a ogni thread il proprio stack di dati. Sarebbe semplice avere un attore, per esempio, il cui corpo è stato implementato dal codice in un linguaggio basato su stack. Il parallelismo esplicito alle parannotazioni del GHC dovrebbe essere ragionevolmente semplice. Il problema principale con l'esecuzione di cose in parallelo è che non sai quale sarà l'effetto stack del codice fino a quando non lo eseguirai. Tuttavia, usando una sintassi simile a quella di Gioia, si potrebbe immaginare [a b c] pardi eseguirea b co contro uno stack vuoto o una copia dello stack e mantenendo solo l'elemento più in alto dello stack al completamento (o spingendo un valore fittizio se lo stack è vuoto). Potresti immaginare variazioni. Il parallelismo implicito sarebbe più difficile da fare in modo ingenuo rispetto, per esempio, a un linguaggio puramente funzionale, ma certamente potrebbe anche essere fatto. Il codice compilato di un combinatore definito dall'utente spesso non è troppo diverso dal codice "normale".

È possibile implementare la valutazione pigra in un linguaggio di programmazione basato su stack?

Gli effetti stack sconosciuti sono di nuovo la parte difficile. Se si progetta il linguaggio in modo tale che tutti gli effetti dello stack possano essere determinati staticamente, non sembra troppo impegnativo. Se hai la pigrizia sia esplicita, allora sembra anche relativamente semplice e sembrerebbe approssimativamente come le citazioni di Joy e i. Una lingua che si definisce un linguaggio concatenativo pigro sembra fare una miscela di entrambi gli approcci sopra da quello che posso dire. Non vedo davvero come un linguaggio concatenativo implicitamente pigro funzionerebbe di fronte a effetti di stack dinamici, almeno non in alcun modo vagamente utilizzabile, ma potrebbe essere solo una mancanza di immaginazione da parte mia.

Per inciso, non è raro che i linguaggi basati su stack abbiano più stack, ad esempio Forth ha uno stack di dati e uno stack di ritorno su cui è anche possibile posizionare dati arbitrari.


8

Conosco un po 'FORTH, quindi mi limiterò a questo. È un linguaggio di basso livello che ti offre come programmatore l'accesso a tutte le risorse hardware. Quindi puoi fare quello che vuoi.

Concorrenza

Per avere programmi paralleli (modifica: usato per dire programmi simultanei reali) sono necessarie almeno due unità di esecuzione (CPU). Sarebbe piuttosto banale implementare una parola in FORTH dicendo, ad esempio, "esegui questa parola sul processore 2 usando questi due argomenti". La parola allocerebbe le due pile necessarie sul processore 2 e inizierebbe a eseguire la parola. Dovresti limitarti in qualche modo esattamente a quali costrutti puoi usare in quel programma.

Se il numero di programmi simultanei è maggiore del numero di unità di esecuzione andresti per programmi "pseudo paralleli". Fondamentalmente ci sono due modi per farlo: coroutine o multitasking preventivo. In ogni caso è possibile (non facile, ma ben descritto in letteratura) come raggiungere questo obiettivo e FORTH ti consente di accedere a tutte le cose di basso livello di cui hai bisogno.

Valutazione pigra

Ovviamente puoi farlo in FORTH come in quasi tutti i linguaggi di programmazione. Non sarà elegante o "integrato" come dice Haskell. Userò un esempio molto ingenuo.

L'idea è che tu definisca una "funzione" (usata vagamente qui) che restituisce un insieme di cose. Un esempio potrebbe essere una funzione che restituisce tutti i numeri interi. Quindi fai le operazioni su questo set e quando hai finito dai il risultato. Ad esempio, potresti voler sommare tutti i numeri interi fino a quando la somma è maggiore di 1000. Una valutazione non pigra assegnerebbe innanzitutto tutti i numeri interi come un insieme, il che è impossibile in quanto vi è un numero infinito di numeri interi. Avrebbe quindi iniziato a lavorare su questo set. Un'implementazione pigra avrebbe un modo di "darmi il prossimo valore nel set". Per fare ciò è necessario solo una variabile nella funzione "ultimo valore dare".

Haskell fa le cose in questo modo. Ovviamente gestisce situazioni più complicate ma l'idea è la stessa. Confina la valutazione in un modo che ti consente come programmatore di concentrarti sul problema, non su come risolverlo.


4
"Per avere veri programmi simultanei sono necessarie almeno due unità di esecuzione". Questo è solo un problema di implementazione. Dal punto di vista del linguaggio di programmazione, non vi è quasi alcuna differenza tra due thread in esecuzione su una singola CPU o su due. In un certo senso, ogni thread può essere considerato una 'unità di esecuzione' a sé stante.
Lucertola discreta

1
A volte, i dettagli di attuazione devono essere presi in considerazione. Un esempio è quando ci si interfaccia con il mondo reale al di fuori di un computer reale. In tempo reale, come per "la risposta giusta troppo tardi è sbagliata", i tempi possono essere diversi se si confronta la corsa su due unità di esecuzione con la corsa mescolata su una unità.
ghellquist,

A volte lo facciamo. Tuttavia, dubito che sia un caso del genere. Ad esempio, la domanda non menziona i requisiti di pianificazione in tempo reale.
Lucertola discreta

3
"Concurrency"! = "Parallelismo". Si può dire che più thread in esecuzione su una macchina a CPU singola vengano eseguiti contemporaneamente, anche se non si verifica alcuna elaborazione parallela.
Solomon Slow

Punto preso in considerazione sulla concorrenza contro i parallelismi. Cambierò il testo.
ghellquist,
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.