![]() |
1
26
因为在计算机科学理论和实践的最初概念中,函数和子程序实际上彼此没有任何关系。 Fortran通常被认为是实现这两种语言并展示其区别的第一种语言。(早期的Lisp在这方面也有一些相反的作用,但在学术界之外几乎没有影响)。 从数学的传统(CS仍然是60年代的一部分)来看,函数仅被视为参数化数学计算的封装,其目的仅仅是将值返回到更大的表达式中。你可以称之为“裸”(f=azimuth(seconds))只是一个微不足道的用例。 另一方面,子程序被看作是命名一组具有某种效果的语句的一种方法。参数极大地提高了它们的可用性,允许它们返回修改后的参数值的唯一原因是,它们可以在不依赖全局变量的情况下报告它们的状态。 所以,除了封装和参数,它们实际上没有概念上的连接。 真正的问题是:“那么多开发人员是如何看待它们的呢?” 答案是C。 当K+R最初为PDP-11设计其高级宏汇编程序类型语言时(可能已在PDP-8上启动?)他们没有硬件独立的幻想。实际上,该语言的每个“独特”特性都反映了PDP机器语言和体系结构(参见i++和--i)。其中之一是实现函数和子例程可以(并且始终)在PDP中以相同的方式实现,除非调用方刚刚忽略子例程的返回值(r0[,r1])。 因此诞生了空指针,在C语言接管了整个编程世界之后,人们错误地认为这个硬件/操作系统实现工件(尽管在随后的每个平台上都是这样)与语言语义相同。 |
![]() |
2
3
在纯或效果类型的设置中,存在一个差异的世界,因为显然,“不返回任何内容”的方法只对它们的副作用有用。 这类似于表达式和语句之间的区别,后者可以分解语言并消除一类通常是错误的程序(当然,这也是C不这样做的原因;)。
举个小例子,当你清楚地区分表达式和语句时,
在一种用单子来封装效果的语言中,重要的区别在于:
|
![]() |
3
0
对不起,我回答了一个两岁大的问题,尤其是用我自己的语言费利克斯特有的语言。 http://felix-lang.org 但不管怎么说,这里是:) 在Felix中,函数和过程是基本不同的,不仅过程有副作用,而且在语句中被调用,而函数没有副作用,并且在表达式中使用(因为Felix也有生成器,它们是具有副作用的函数)。:) 不,执行模型从根本上是不同的,主要是出于性能原因,但不是完全不同。模型是:
这通常是低效的,为什么要这样做?答案是:Felix程序都是潜在的共同程序(纤维)。他们可以通过访问一个通道将控制切换到另一个过程。这会导致控制权的交换。
操作系统通常将堆栈指针交换为线程,这是相当快的,但在线性地址机上有一个基本问题:要么将堆栈的最大大小限制为一个非常小的值,要么将线程数限制为一个非常小的值。在32位机器上,没有足够的地址空间来考虑这个解决方案。在64位机器上,堆栈交换具有更大的潜力,但当然,用户的需求总是在释放后的3天增长到超过硬件。:) Felix只是将一个指针交换到基于堆的堆栈,因此上下文切换速度非常快,浪费的地址空间非常少。 当然,成本是过程调用的堆分配。 在编译器中,许多理论模型的体系结构都是在“假设”的基础上进行优化的,因此实际的性能和实现可能与理论模型有很大的不同,前提是编译器能够证明您不能分辨出不同之处。除了被剥夺了悠闲地喝一杯咖啡的机会之外:) 因此,对于为什么函数和过程可能被不同地对待,您有不同的答案。 |
![]() |
dallin · 数组中的逗号运算符是否有名称? 11 年前 |