É possível que uma linguagem de programação baseada em pilha seja simultânea?


14

Eu tenho lido sobre linguagens de programação baseadas em pilha, como FORTH e Cat , e parece que, dada a sua natureza, elas podem executar apenas uma ação por vez, independentemente do seu paradigma (FORTH é imperativo enquanto Cat é funcional).

Uma linguagem imperativa modificaria a pilha, e uma linguagem puramente funcional, como Joy , retornaria uma nova pilha, mas o ponto é que apenas uma pilha é usada por vez.

Então, as linguagens de programação baseadas em pilha podem ser simultâneas? Eles poderiam obter simultaneidade usando várias pilhas ao mesmo tempo ou algo parecido?

É possível implementar a avaliação lenta em uma linguagem de programação baseada em pilha?

Corrija-me se não estiver entendendo nada sobre os idiomas e conceitos mencionados acima


5
Como qualquer linguagem imperativa pode ser simultânea?
Bergi


Você realmente quer dizer simultaneidade (que não é tão difícil de alcançar, basta usar vários threads em execução com pilhas independentes mais memória compartilhada) ou paralelismo?
Daniel Jour

@DanielJour Se bem entendi, paralelismo significa execução simultânea, enquanto simultaneidade significa execução independente; portanto, sim, quero dizer simultaneidade. Você poderia elaborar mais sobre as pilhas independentes para cada thread?
Armando H.

Respostas:


16

Então, as linguagens de programação baseadas em pilha podem ser simultâneas?

Certo.

Eles poderiam obter simultaneidade usando várias pilhas ao mesmo tempo ou algo parecido?

Já para idiomas normais, o multiencadeamento geralmente significa ter várias pilhas de "chamada". Seria completamente natural atribuir a cada thread sua própria pilha de dados. Seria fácil ter um ator, digamos, cujo corpo fosse implementado pelo código em uma linguagem baseada em pilha. O paralelismo explícito às paranotações do GHC deve ser razoavelmente direto. O principal problema com a execução de coisas em paralelo é que você não sabe qual será o efeito de pilha do código até executá-lo. No entanto, usando uma sintaxe do tipo Joy, pode-se imaginar [a b c] parcomo executandoa b ccontra uma pilha vazia ou uma cópia da pilha e mantendo apenas o elemento mais alto da pilha (ou pressionando algum valor fictício se a pilha estiver vazia). Você pode imaginar variações. Seria mais difícil fazer ingenuamente paralelismo implícito em comparação com, digamos, uma linguagem puramente funcional, mas certamente poderia ser feito também. O código compilado de um combinador definido pelo usuário geralmente não é muito diferente do código "normal".

É possível implementar a avaliação lenta em uma linguagem de programação baseada em pilha?

Efeitos de pilha desconhecidos são novamente a parte complicada. Se você projetar o idioma de modo que todos os efeitos da pilha possam ser determinados estaticamente, isso não parecerá muito desafiador. Se você tem preguiça de ser explícito, também parece relativamente direto e se pareceria com as citações de Joy e i. Uma linguagem que se autodenomina uma linguagem concatenativa preguiçosa parece fazer uma mistura das duas abordagens acima do que posso dizer. Eu realmente não vejo como uma linguagem concatenativa implicitamente preguiçosa funcionaria diante dos efeitos de pilha dinâmica, pelo menos não de uma maneira vagamente utilizável, mas isso pode ser apenas uma falta de imaginação da minha parte.

Aliás, não é incomum que os idiomas baseados em pilha tenham várias pilhas, por exemplo, a Forth possui uma pilha de dados e uma pilha de retorno na qual você também pode colocar dados arbitrários.


8

Eu sei um pouco sobre FORTH, então vou me limitar a isso. É uma linguagem de baixo nível, oferecendo a você como programador acesso a todos os recursos de hardware. Então você pode fazer o que quiser.

Concorrência

Para ter programas paralelos (edit: costumava dizer programas concorrentes reais), você precisa de pelo menos duas unidades de execução (CPU-s). Seria bastante trivial implementar uma palavra em FORTH dizendo, como exemplo, "execute esta palavra no processador 2 usando esses dois argumentos". A palavra alocaria as duas pilhas necessárias no processador 2 e começaria a executar a palavra. Você precisaria se restringir um pouco exatamente às construções que você pode usar nesse programa.

Se o número de programas simultâneos for maior que o número de unidades de execução, você deverá procurar programas "pseudo-paralelos". Basicamente, existem duas maneiras de fazer isso: corotinas ou multitarefa preemptiva. De qualquer forma, é possível (não fácil, mas bem descrito na literatura) como conseguir isso e o FORTH permite acessar todas as coisas de baixo nível necessárias.

Avaliação preguiçosa

Claro que você pode fazer isso no FORTH, como em praticamente qualquer linguagem de programação. Não será tão elegante ou "embutido" como em Haskell. Vou usar um exemplo muito ingênuo.

A idéia é que você defina uma "função" (usada livremente aqui) que retorne um conjunto de coisas. Um exemplo seria uma função que retorna todos os números inteiros. Você faz operações neste conjunto e, quando terminar, fornece o resultado. Como exemplo, você pode querer somar todos os números inteiros até que a soma seja maior que 1000. Uma avaliação não preguiçosa alocaria primeiro todos os números inteiros como um conjunto, o que é impossível, pois há um número infinito de números inteiros. Começaria então a trabalhar neste conjunto. Uma implementação lenta teria uma maneira de "fornecer o próximo valor no conjunto". Fazer isso realmente precisa apenas de uma variável na função "last value give".

Haskell faz as coisas dessa maneira. Obviamente, ele lida com situações mais complicadas, mas a idéia é a mesma. Ele reveste a avaliação de uma maneira que permite que você como programador se concentre no problema, não em como resolvê-lo.


4
"Para ter programas concorrentes reais, você precisa de pelo menos duas unidades de execução". Este é apenas um problema de implementação. Da perspectiva da linguagem de programação, quase não há diferença entre dois threads em execução em uma única CPU ou em duas. De certo modo, cada encadeamento pode ser considerado uma 'unidade de execução' própria.
Lagarto discreto

1
Às vezes, os detalhes da implementação devem ser levados em consideração. Um exemplo é ao fazer interface com o mundo real fora de um computador real. Em tempo real difícil, conforme "resposta correta tarde demais está errada", o tempo pode ser diferente quando você compara a execução em duas unidades de exeução com a execução misturada em uma unidade.
precisa saber é o seguinte

Às vezes nós fazemos. No entanto, duvido que seja esse o caso. Por exemplo, a pergunta não menciona os requisitos de agendamento em tempo real.
Lagarto discreto

3
"Concorrência"! = "Paralelismo". Pode-se dizer que vários threads em execução em uma máquina com uma CPU são executados simultaneamente entre si, mesmo que nenhum processamento paralelo esteja acontecendo.
Solomon Slow

Ponto de vista sobre concorrência versus paralelos. Vou mudar o texto
Ghellquist
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.