尾部递归语言的有效堆栈分配

C. Hanson
{"title":"尾部递归语言的有效堆栈分配","authors":"C. Hanson","doi":"10.1145/91556.91603","DOIUrl":null,"url":null,"abstract":"The Scheme dialect of Lisp [9] is properly tail-recuraiwit relies entirely on procedure calls to express iteration. In Scheme, a tail-recursive procedure call (that is, a call in which the calling procedure does not do any further processing of the returned due) is essentially a goto that passes arguments, sa was first pointed out by Steele [13]. In a prop erly tail-recursive language, there is no need for any explicit iteration constructs such as do or vhile; these can all be defined in terms of ordinary procedure calls. As elegant as tail-recursion may be from the perspective of the programmer or the theoretician, it poses challenges for the compiler designer. One of the crucial decisions in the design of a compiler is the formation of a strategy for memory allocation and deallocation. An important aspect of this strategy is the treatment of memory locations used to hold the bindings of local variables. Because local variables play a significant role in most computer languages, their treatment can have a noticeable impact on a program’s execution speed and run-time space requirements. Compilers for many block-structured languages use a simple strategy when allocating local variables: stack allocation. This strategy is supported by hardware on many computers, and by software mechanisms such as the aceem link and the display. However, the standard methods for implementing stack allocation assume that the language is not tail-recursive, and a straightforward application of these methods to a tailrecursive language can result in non-tail-recursive compiled code.’ This paper describes stack-allocation techniques for compiling tail-recursive languages. We do not claim that these are the only techniquea that can be used to solve the prob lem, nor do we compare them to other techniques. Instead, we use our techniques as a concrete example to demonstrate that it is possible to implement stack allocation of local variables without sacrificing tail recursion, which to our knowledge has not previously been shown. We have implemented these techniques in the MIT","PeriodicalId":409945,"journal":{"name":"LISP and Functional Programming","volume":null,"pages":null},"PeriodicalIF":0.0000,"publicationDate":"1990-05-01","publicationTypes":"Journal Article","fieldsOfStudy":null,"isOpenAccess":false,"openAccessPdf":"","citationCount":"29","resultStr":"{\"title\":\"Efficient stack allocation for tail-recursive languages\",\"authors\":\"C. Hanson\",\"doi\":\"10.1145/91556.91603\",\"DOIUrl\":null,\"url\":null,\"abstract\":\"The Scheme dialect of Lisp [9] is properly tail-recuraiwit relies entirely on procedure calls to express iteration. In Scheme, a tail-recursive procedure call (that is, a call in which the calling procedure does not do any further processing of the returned due) is essentially a goto that passes arguments, sa was first pointed out by Steele [13]. In a prop erly tail-recursive language, there is no need for any explicit iteration constructs such as do or vhile; these can all be defined in terms of ordinary procedure calls. As elegant as tail-recursion may be from the perspective of the programmer or the theoretician, it poses challenges for the compiler designer. One of the crucial decisions in the design of a compiler is the formation of a strategy for memory allocation and deallocation. An important aspect of this strategy is the treatment of memory locations used to hold the bindings of local variables. Because local variables play a significant role in most computer languages, their treatment can have a noticeable impact on a program’s execution speed and run-time space requirements. Compilers for many block-structured languages use a simple strategy when allocating local variables: stack allocation. This strategy is supported by hardware on many computers, and by software mechanisms such as the aceem link and the display. However, the standard methods for implementing stack allocation assume that the language is not tail-recursive, and a straightforward application of these methods to a tailrecursive language can result in non-tail-recursive compiled code.’ This paper describes stack-allocation techniques for compiling tail-recursive languages. We do not claim that these are the only techniquea that can be used to solve the prob lem, nor do we compare them to other techniques. Instead, we use our techniques as a concrete example to demonstrate that it is possible to implement stack allocation of local variables without sacrificing tail recursion, which to our knowledge has not previously been shown. We have implemented these techniques in the MIT\",\"PeriodicalId\":409945,\"journal\":{\"name\":\"LISP and Functional Programming\",\"volume\":null,\"pages\":null},\"PeriodicalIF\":0.0000,\"publicationDate\":\"1990-05-01\",\"publicationTypes\":\"Journal Article\",\"fieldsOfStudy\":null,\"isOpenAccess\":false,\"openAccessPdf\":\"\",\"citationCount\":\"29\",\"resultStr\":null,\"platform\":\"Semanticscholar\",\"paperid\":null,\"PeriodicalName\":\"LISP and Functional Programming\",\"FirstCategoryId\":\"1085\",\"ListUrlMain\":\"https://doi.org/10.1145/91556.91603\",\"RegionNum\":0,\"RegionCategory\":null,\"ArticlePicture\":[],\"TitleCN\":null,\"AbstractTextCN\":null,\"PMCID\":null,\"EPubDate\":\"\",\"PubModel\":\"\",\"JCR\":\"\",\"JCRName\":\"\",\"Score\":null,\"Total\":0}","platform":"Semanticscholar","paperid":null,"PeriodicalName":"LISP and Functional Programming","FirstCategoryId":"1085","ListUrlMain":"https://doi.org/10.1145/91556.91603","RegionNum":0,"RegionCategory":null,"ArticlePicture":[],"TitleCN":null,"AbstractTextCN":null,"PMCID":null,"EPubDate":"","PubModel":"","JCR":"","JCRName":"","Score":null,"Total":0}
引用次数: 29

摘要

Lisp的Scheme方言[9]是正确的尾部递归,完全依赖于过程调用来表达迭代。在Scheme中,尾部递归过程调用(即调用过程不对返回的due进行任何进一步处理的调用)本质上是传递参数的goto,这是由Steele[13]首先指出的。在完全尾部递归的语言中,不需要任何显式的迭代结构,如do或while;这些都可以根据普通过程调用来定义。从程序员或理论家的角度来看,尾递归可能是优雅的,但它对编译器设计者提出了挑战。编译器设计中的一个关键决策是形成内存分配和释放策略。该策略的一个重要方面是处理用于保存局部变量绑定的内存位置。由于局部变量在大多数计算机语言中扮演着重要的角色,因此它们的处理方式会对程序的执行速度和运行时空间需求产生明显的影响。许多块结构语言的编译器在分配局部变量时使用一种简单的策略:堆栈分配。许多计算机上的硬件和软件机制(如aceem链接和显示)都支持这种策略。但是,实现堆栈分配的标准方法假定语言不是尾递归的,并且将这些方法直接应用于尾递归语言可能会产生非尾递归的编译代码。本文描述了用于编译尾递归语言的堆栈分配技术。我们并不声称这些是唯一可以用来解决问题的技术,我们也不将它们与其他技术进行比较。相反,我们使用我们的技术作为一个具体的例子来证明,在不牺牲尾部递归的情况下实现局部变量的堆栈分配是可能的,据我们所知,这在以前没有显示过。我们已经在MIT实现了这些技术
本文章由计算机程序翻译,如有差异,请以英文原文为准。
查看原文
分享 分享
微信好友 朋友圈 QQ好友 复制链接
本刊更多论文
Efficient stack allocation for tail-recursive languages
The Scheme dialect of Lisp [9] is properly tail-recuraiwit relies entirely on procedure calls to express iteration. In Scheme, a tail-recursive procedure call (that is, a call in which the calling procedure does not do any further processing of the returned due) is essentially a goto that passes arguments, sa was first pointed out by Steele [13]. In a prop erly tail-recursive language, there is no need for any explicit iteration constructs such as do or vhile; these can all be defined in terms of ordinary procedure calls. As elegant as tail-recursion may be from the perspective of the programmer or the theoretician, it poses challenges for the compiler designer. One of the crucial decisions in the design of a compiler is the formation of a strategy for memory allocation and deallocation. An important aspect of this strategy is the treatment of memory locations used to hold the bindings of local variables. Because local variables play a significant role in most computer languages, their treatment can have a noticeable impact on a program’s execution speed and run-time space requirements. Compilers for many block-structured languages use a simple strategy when allocating local variables: stack allocation. This strategy is supported by hardware on many computers, and by software mechanisms such as the aceem link and the display. However, the standard methods for implementing stack allocation assume that the language is not tail-recursive, and a straightforward application of these methods to a tailrecursive language can result in non-tail-recursive compiled code.’ This paper describes stack-allocation techniques for compiling tail-recursive languages. We do not claim that these are the only techniquea that can be used to solve the prob lem, nor do we compare them to other techniques. Instead, we use our techniques as a concrete example to demonstrate that it is possible to implement stack allocation of local variables without sacrificing tail recursion, which to our knowledge has not previously been shown. We have implemented these techniques in the MIT
求助全文
通过发布文献求助,成功后即可免费获取论文全文。 去求助
来源期刊
自引率
0.00%
发文量
0
期刊最新文献
Partial evaluation applied to numerical computation Computing with coercions Trap architectures for Lisp systems Reasoning with continuations II: full abstraction for models of control A module system for scheme
×
引用
GB/T 7714-2015
复制
MLA
复制
APA
复制
导出至
BibTeX EndNote RefMan NoteFirst NoteExpress
×
×
提示
您的信息不完整,为了账户安全,请先补充。
现在去补充
×
提示
您因"违规操作"
具体请查看互助需知
我知道了
×
提示
现在去查看 取消
×
提示
确定
0
微信
客服QQ
Book学术公众号 扫码关注我们
反馈
×
意见反馈
请填写您的意见或建议
请填写您的手机或邮箱
已复制链接
已复制链接
快去分享给好友吧!
我知道了
×
扫码分享
扫码分享
Book学术官方微信
Book学术文献互助
Book学术文献互助群
群 号:481959085
Book学术
文献互助 智能选刊 最新文献 互助须知 联系我们:info@booksci.cn
Book学术提供免费学术资源搜索服务,方便国内外学者检索中英文文献。致力于提供最便捷和优质的服务体验。
Copyright © 2023 Book学术 All rights reserved.
ghs 京公网安备 11010802042870号 京ICP备2023020795号-1