- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在阅读“为什么 FUNARG 问题应该称为环境问题”之后,我问了自己一个问题:如果我们禁止定义一个无法创建闭包的函数,会发生什么,即
(define (foo x) (+ a x))
不会在顶层被允许(因为没有环境可以关闭,包含a),而
(define (bar a) (lambda (x) (+ a x)))
是允许的,因为返回的 lambda 可以创建闭包。这里有两个问题:
1. 这会如何影响语言的表达能力?是否有某些功能因此类限制而变得不可用?有人可以举个例子,用自由变量定义函数时有用吗?
2. 这是否意味着闭包中的所有环境变量现在都具有静态和可预测的偏移量?
最佳答案
正如 Will Ness 和 tfb 所说,存在一个全局环境。在您的表达式中,+
和 a
都是自由变量。重要的是当您定义f
时,a
是否存在于您的全局环境中。此外,“自由”或“束缚”是一个相对的概念。
引用未在任何环境中绑定(bind)的词法 变量没有什么意义。我能想到的唯一示例与元编程相关,但这并不真正相关,因为在那种情况下您只是将代码作为数据进行操作。当你最终生成一个表单并编译或评估它时,你仍然有一个词法范围,然后你的所有符号都必须解析为一个已知变量。对于 Common Lisp 中的 special 变量,或 Emacs 的默认动态作用域变量,引用自由变量是有意义的。在 Emacs 中,您甚至可以在没有警告的情况下引用未声明的变量。
How this may affect the expressiveness of the language?
因此,如果您不允许自由变量(未绑定(bind)在任何词法范围内),您基本上就是不允许具有动态范围的变量(在 Common Lisp 中,它们被定义为具有无限范围和动态程度)。你失去了表达能力。例如,OCaml 就是这种情况。但是,您仍然可以定义一个库来模拟它们,如 Delimited Dynamic Binding 中所示。及其 implementation .
OCaml 提供了一个 hyper-static global environment ,它不仅使用词法作用域,而且禁止更改现有绑定(bind)。
# let a = 10;;
val a : int = 10
# let f () = a;;
val f : unit -> int = <fun>
# let a = 20;;
val a : int = 20
# f ()
- : int = 10
上面第二个 a
隐藏了前一个,但是 f
仍然引用前一个 a
。 函数也是如此,这就是为什么有rec
关键字来定义递归和相互递归函数的原因。这是一种不同于 Lisp 的方法,后者值得注意的是允许在运行时重新定义大部分内容。
Does this mean that all environment variables in closures have static and predictable offsets now?
词法作用域允许将变量编译到固定位置。这是否完成取决于您的工具。例如,在解释器中,您的环境可能保存在运行时数据结构中。
关于lambda - 没有自由变量的语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37896091/
这是我正在调试的函数: boolean adin_memory(char* buffer, int size_chunck, int end_flag){ global_buffer = my
我正在尝试为具有自由 float 底座的机器人计算末端执行器空间速度雅可比行列式。由于自由 float 基数,雅可比应该包含一个基数组件和一个操纵器注释(参见 https://spart.readth
procedure FreeListObjects( l : TStrings); var i : integer; BEGIN FOR i := 0 TO l.Count -1 DO BEG
我正在探索 Haskell 中的选项,这些选项可以让我将业务逻辑与底层系统的技术实现分开。例如,在 Web 服务器的上下文中,将 Web 服务器处理其接收的信息的方式与其读取和写入数据库的方式分开。要
我的目标是使用来自 ActiveMQ 的 WebSphere Liberty Appserver(完整的 Java EE 标准)使用消息。不幸的是,我不知道如何配置 WebSphere Liberty
我以这种方式分配了一个非方阵,但我不确定我是否正确使用了释放 float **matrix_alloc(int m /* rows */, int n /* columns */) { int
我在阅读 refuting the notion 之后的第 13.5 节内置运算符不参与重载决议,并注意到没有关于 operator->* 的部分。它只是一个通用的二元运算符。 它的兄弟operato
我正在尝试使用 Libelf 库来获取有关某些 elf 文件的一些信息。但我不断收到这些“对 [...] 的 undefined reference ”。我从 synaptic 安装了 libelf(
我有创建动态结构数组的波纹管代码。 #include #include #include typedef struct { int flag; char* ip; } ip_mo
我是 StackOverflow 的新人。我现在正在学习C指针。 这是我的代码: #include #include int alloc(int* p){ p = (int*) mallo
我是 StackOverflow 的新人。我现在正在学习C指针。 这是我的代码: #include #include int alloc(int* p){ p = (int*) mallo
我正在用 C 编写一个程序,我需要读入一个文件并打印出每个至少 4 个字符长的字符串。我在分配要使用的内存时遇到问题。字符串可以任意长。我试图将缓冲区分配给文件的大小,然后在最后释放它,但我显然错过了
我尝试用 C 语言编写 ls 命令,但 -R 选项有问题。 输出: /Applications/Atom.app/Contents/Resources/app/apm/node_modules/es5
我正在编写一个 shell,但在执行内存检查时遇到问题,因为 valgrind 无法正常运行。 我遇到了这样的错误(我自己杀死了它): ==19703== Memcheck, a memory err
我有这样一段代码: void *write_parallel(void *num_for_chunk) { struct rusage *sum = (struct rusage*) mall
当使用包含 200-300 个整数(以空格分隔)的输入 .txt 文件运行此代码时,我在使用 fprintf 语句的 for 循环之前收到错误。 我不确定 qsort 是否导致了此错误或为什么会发生此
我试图告诉 Websphere Liberty 我的 log4j2.xml 文件在哪里,但它不起作用。 在我的文件 jvm.options 中,我配置: -Dlog4j.configurationFi
从 websphere liberty 16 迁移到 19.0.0.1 我遇到以下异常:运行存储过程后关闭连接,出现以下异常: EJB threw an unexpected (non-declare
当对大小为 210*8 的种子数据集运行此代码时,我在预测函数中的 qsort() 行之后收到错误。它不在 qsort() 之后执行。 我不确定 qsort 是否导致了此错误或为什么会发生此错误,但如
这个问题已经有答案了: Facing an error "*** glibc detected *** free(): invalid next size (fast)" (2 个回答) 已关闭 9
我是一名优秀的程序员,十分优秀!