当前位置:  开发笔记 > 开发工具 > 正文

什么是"向下的funargs"?

如何解决《什么是"向下的funargs"?》经验,为你挑选了4个好方法。

Jamie Zawinski在他的(1997)文章"java sucks"中使用了这个术语,好像你应该知道这意味着什么:

我真的很讨厌缺乏向下的乐趣; 匿名类是一个蹩脚的替代品.(我可以没有长寿的闭包,但我发现缺少功能指针是一个巨大的痛苦.)

它似乎是Lisper的俚语,我可以在这里找到以下简短的定义,但不知何故,我想我仍然没有得到它:

许多闭包只在它们引用的绑定范围内使用; 这些在Lisp的说法中被称为"向下的funargs".

如果不是Steve Yegge,我现在感觉很愚蠢,但似乎可以问:

Jamie Zawinski是一位英雄.一个活生生的传奇 [...] 一个人可以使用"向下的funargs"一词,然后瞪着你,只是敢于要求他解释它,你克里汀.

- XEmacs死了,XEmacs万岁

那么在这里有一个Lisper可以为我这样的C风格程序员编译吗?



1> Konrad Rudol..:

向下funargs是本地函数,不返回或以其他方式保留其声明范围.它们只能从当前范围向下传递给其他函数.

两个例子.这是一个向下的乐趣:

function () {
    var a = 42;
    var f = function () { return a + 1; }
    foo(f); // `foo` is a function declared somewhere else.
}

虽然这不是:

function () {
    var a = 42;
    var f = function () { return a + 1; }
    return f;
}


重点是当执行f时,a在堆栈上,因此不需要将其存储在其他地方(通常与堆中的f一起在所谓的闭包中).所以"向下的funarg"是"funarg"的简单部分.

2> Gareth Rees..:

为了更好地理解术语的来源,您需要了解一些历史.

旧Lisp黑客之所以可能将向下的 funargs与funargs 区分开来的原因是,在传统的Lisp中很容易实现向下的funargs,它缺少词汇变量,而一般情况很难.

传统上是一个局部变量是在一个Lisp解释通过添加实现结合(该变量的符号名,它的值配对)的环境.使用关联列表可以很容易地实现这样的环境.每个函数都有自己的环境,以及指向父函数环境的指针.通过查看当前环境来解析变量引用,如果没有在那里找到,则在父环境中解决,依此类推环境堆栈直到达到全局环境.

在这样的实现中,局部变量会影响具有相同名称的全局变量.例如,在Emacs Lisp中,print-length是一个全局变量,它指定在缩写之前要打印的列表的最大长度.通过在函数调用周围绑定此变量,您可以更改该函数中print语句的行为:

(defun foo () (print '(1 2 3 4 5 6))) ; output depends on the value of print-length

(foo) ; use global value of print-length
  ==>  (1 2 3 4 5 6)

(let ((print-length 3)) (foo)) ; bind print-length locally around the call to foo.
  ==>  (1 2 3 ...)

您可以看到,在这样的实现中,向下的 funargs实际上很容易实现,因为在函数环境中创建的变量在评估时仍然会在函数的环境中.

像这样的变量称为特殊变量或动态变量,您可以使用special声明在Common Lisp中创建它们.



3> Rainer Joswi..:

在Common Lisp中:

(let ((a 3))
  (mapcar (lambda (b) (+ a b))
          (list 1 2 3 4)))

->  (4 5 6 7)

在上面的形式中,lambda函数向下传递.当由高阶函数MAPCAR(它获取函数和值列表作为参数,然后将函数应用于列表的每个元素并返回结果列表)调用时,lambda函数仍然引用变量来自LET表达的'a'.但它发生在LET表达式中.

比较以上版本:

(mapcar (let ((a 3))
          (lambda (b) (+ a b)))
        (list 1 2 3 4))

这里从LET返回lambda函数.向上一点.然后它被传递给MAPCAR.当MAPCAR调用lambda函数时,其周围的LET不再执行 - 仍然该函数需要从LET引用变量'a'.



4> Ólafur Waage..:

在Wiki上有一篇非常具有描述性的文章称为Funarg问题

"当函数实际上没有执行时,向下的funarg也可以引用函数的状态.但是,因为根据定义,在创建函数的函数的执行中包含向下funarg的存在,函数的激活记录通常仍然可以存储在堆栈中."

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有