Pytanie Co to naprawdę oznacza, że ​​język programowania nie ma żadnych powiązań?


Zgodnie z tą odpowiedzią

https://stackoverflow.com/questions/551950/what-stackless-programming-languages-are-available/671296#671296

wszystkie te języki programowania są w trybie stackless

  • Stackless Python
  • PyPy
  • Seplenienie
  • Schemat
  • Tcl
  • Lua
  • Parrot VM

Co to naprawdę znaczy dla nich, że nie mają dostępu do stacków? Czy to oznacza, że ​​nie używają stosu połączeń? Jeśli nie używają stosu wywołań, czego używają?


14
2018-04-28 04:23


pochodzenie


Zobacz odpowiedź na stackoverflow.com/questions/1016218/... - Ira Baxter
Strona nie istnieje stackoverflow.com/questions/551950/... - Seti Volkylany


Odpowiedzi:


Co to naprawdę znaczy dla nich, że nie mają dostępu do stacków? Czy to oznacza, że ​​nie używają stosu połączeń?

Tak, to jest w porządku.

Jeśli nie używają stosu wywołań, czego używają?

Dokładna implementacja będzie oczywiście różnić się w zależności od języka. W Stackless Pythonie istnieje narzędzie uruchamiające, które uruchamia interpreter języka Python za pomocą najwyższej ramki i jej wyników. Interpreter przetwarza kody operacji w razie potrzeby po kolei, aż osiągnie wartość CALL_FUNCTION opcode, sygnał, który masz zamiar wprowadzić w funkcję. To powoduje, że dyspozytor buduje nową ramkę z odpowiednimi informacjami i wraca do dyspozytora z flagą odwijania. Stamtąd dyspozytor rozpoczyna od nowa, wskazując tłumacza na najwyższą ramkę.

Języki stosowe unikają stosów wywołań z wielu powodów, ale w wielu przypadkach są używane w taki sposób, że niektóre konstrukcje programistyczne stają się łatwiejsze do wdrożenia. Kanoniczny jest kontynuacje. Kontynuacje są bardzo potężnymi, bardzo prostymi strukturami kontrolnymi, które mogą reprezentować dowolne ze znanych struktur kontrolnych, które prawdopodobnie już znasz (while, do, if, switchi in.).

Jeśli jest to mylące, możesz spróbować owijać głowę wokół artykułu w Wikipedii, a zwłaszcza o krojach Kontynuacja analogii kanapek:

Powiedzmy, że jesteś w kuchni przed lodówką, myśląc o kanapce. Bierzesz kontynuację i trzymasz ją w kieszeni. Potem wyjmujesz z lodówki indyka i chleb i robisz sobie kanapkę, która teraz siedzi na ladzie. Wzywasz do kontynuacji w kieszeni i znów stoisz przed lodówką, myśląc o kanapce. Ale na szczęście na blacie stoi kanapka, a wszystkie materiały użyte do jej wykonania zniknęły. Więc jesz to.


14
2018-04-28 04:32





Nie używają stosu wywołań, ponieważ działają w systemie styl kontynuacji przejścia. Jeśli nie znasz optymalizacji połączeń końcowych, jest to prawdopodobnie dobry pierwszy krok do zrozumienia, co to oznacza.

Aby emulować tradycyjne wywoływanie / zwracanie w tym modelu, zamiast przesuwać adres zwrotny i oczekiwać, że pozostała część ramki pozostanie niezmieniona, wywoływacz zamyka się na pozostałej części kodu i zmiennych, które są nadal potrzebne (pozostałe są zwalniane). Następnie wykonuje wywołanie ogłaszające do kręgu, przekazując tę ​​kontynuację jako argument. Kiedy użytkownik "wraca", robi to, wywołując tę ​​kontynuację, przekazując wartość zwracaną jako argument do niej.

Tak dalece jak powyżej, to tylko skomplikowany sposób wykonywania funkcji. Generalizuje on jednak bardzo ładnie bardziej złożone scenariusze:

  1. bloki wyjątków / finally / etc są bardzo łatwe do modelowania - jeśli możesz przekazać jedną "powrót" jako argument, możesz równie dobrze przekazać 2 (lub więcej). selekcje "warunkowe" w lisp-y (które mogą, ale nie muszą zwracać kontroli do osoby dzwoniącej) są również łatwe - przekazują kontynuację dla pozostałej części tej funkcji, która może, ale nie musi być wywołana.
  2. Wielokrotne wartości zwracane są podobnie łatwe - prześlij kilka argumentów do kontynuacji.
  3. Zwroty tymczasowe / kopiowanie nie są już inne niż przekazywanie argumentów funkcji. To często ułatwia eliminowanie tymczasowych.
  4. Optymalizacja rekursji ogona jest banalna - osoba dzwoniąca po prostu przekazuje otrzymaną kontynuację "powrotu", a nie przechwytuje nową.

10
2018-04-28 04:51