[英]Recursion runtime implementation Java vs. other/functionals languages?
我喜歡遞歸,但在Java,你在某個時刻遇到了死胡同。 例如,我有一個大約100K迭代的遞歸不起作用的情況(StackOverflowError)。 糟糕的是,我不得不為這個運行時堆棧限制原因切換到惱人的“命令性循環”。
我想知道其他(特別是功能性)語言如何在運行時繞過堆棧溢出? 我想特別是函數式語言運行時更好地處理這個問題,因為遞歸是核心概念......
有人有一些信息或外部資源嗎?
這是@Ronald Wildenberg回答的后續內容:
我不確定所有javac實現是否都實現了尾遞歸。 它不是規范要求的東西。
簡短的回答是他們不支持它。
更長的答案是,由於JVM設計,尾遞歸優化在Java中是一個棘手的問題。 閱讀John Rose @ Oracle撰寫的這篇博客文章 ,他談到了這個問題。 博客條目的主旨是提出字節碼擴展以支持“硬”尾調用。 但最后一段暗示為什么實現“軟”(即透明)尾調用很難。 尾調用優化會干擾JVM捕獲堆棧跟蹤的能力,這對Java安全體系結構具有“影響”。
此Sun Bug數據庫條目提供了有關該問題的更多詳細信息。 閱讀評論。
似乎在當前JVM上實現尾遞歸的方法是在編譯器前端實現它。 顯然Scala做到了這一點。
“使用~100K迭代進行遞歸”是應該避免的,而不僅僅是Java。 它僅適用於尾部調用優化,但這並不總是可行的。 因此,最好不要首先養成過度遞歸的習慣。
遞歸是人們在第一次學習它們時往往會過度使用的概念之一,因為它似乎太酷了,不能到處展示......
正如其他人所提到的,支持正確的尾遞歸有幫助。 但是它本身並不足以支持深度遞歸。 盡管BLUB程序員可能會想到,深度遞歸自然適合某些任務,例如處理深度遞歸的數據結構。
支持深(非尾)遞歸的策略通常包含在支持一流延續的策略中。 您可能會發現有關First-Class Continuations的實施策略 (Clinger等人)很有意思。
我的頭腦中有一些策略:
您可以使用以下命令增加Java堆棧大小
java -Xss1024k MyProgram
(將java的堆棧大小增加到1024 KB。)但通常使用深度遞歸不是一個好主意。 嘗試制作迭代解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.