用于动态范围? [英] uses for dynamic scope?

查看:71
本文介绍了用于动态范围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经被emacs lisp弄湿了,有时使我绊倒的一件事是动态范围.未来还有很多吗?我知道的大多数语言都使用静态作用域(或者已经转移到静态作用域,例如Python),可能是因为我更了解它,所以我倾向于使用它.在动态范围更有用的情况下,是否有特定的应用程序/实例或示例?

I've been getting my hands wet with emacs lisp, and one thing that trips me up sometimes is the dynamic scope. Is there much of a future for it? Most languages I know use static scoping (or have moved to static scoping, like Python), and probably because I know it better I tend to prefer it. Are there specific applications/instances or examples where dynamic scope is more useful?

推荐答案

对此问题的讨论很好这里.与您的问题有关的最有用的部分是:

There's a good discussion of this issue here. The most useful part that pertains to your question is:

动态绑定非常适合 修改子系统的行为. 假设您使用的是函数"foo" 使用打印"生成输出. 但是有时候你想 将输出捕获到您的缓冲区中 选择.有了动态绑定, 简单:

Dynamic bindings are great for modifying the behaviour of subsystems. Suppose you are using a function ‘foo’ that generates output using ‘print’. But sometimes you would like to capture the output in a buffer of your choosing. With dynamic binding, it’s easy:

(let ((b (generate-new-buffer-name " *string-output*"))))
    (let ((standard-output b))
      (foo))
    (set-buffer b)
    ;; do stuff with the output of foo
    (kill-buffer b))

(如果您使用过这种东西, 很多情况下,您会将其封装在一个宏中– 但幸运的是它已经完成了 "with-output-to-temp-buffer".)

(And if you used this kind of thing a lot, you’d encapsulate it in a macro – but luckily it’s already been done as ‘with-output-to-temp-buffer’.)

之所以可行,是因为'foo'使用了 动态绑定名称 标准输出",因此您可以 用你自己的绑定代替 名称以修改"foo"的行为 –以及所有"foo"功能 电话.

This works because ‘foo’ uses the dynamic binding of the name ‘standard-output’, so you can substitute your own binding for that name to modify the behaviour of ‘foo’ – and of all the functions that ‘foo’ calls.

在没有动态绑定的语言中, 您可能会添加一个可选的 "foo"的参数以指定缓冲区 然后"foo"会将其传递给任何 调用打印".但是如果"foo"电话 自己调用的其他功能 打印"您必须更改这些 以及功能.如果印刷品" 另一个选项,例如打印级", 您必须将其添加为可选 还有论点...或者,你 记得以前的价值 标准输出",替代您的新产品 值,请调用"foo",然后恢复 旧值.并记住要处理 使用投掷"的非本地出口.什么时候 完成此操作后,您将看到 您实施了动态 绑定!

In a language without dynamic binding, you’d probably add an optional argument to ‘foo’ to specify a buffer and then ‘foo’ would pass that to any calls to ‘print’. But if ‘foo’ calls other functions which themselves call ‘print’ you’ll have to alter those functions as well. And if ‘print’ had another option, say ‘print-level’, you’d have to add that as an optional argument as well… Alternatively, you could remember the old value of ‘standard-output’, substitute your new value, call ‘foo’ and then restore the old value. And remember to handle non-local exits using ‘throw’. When you’re through with this, you’ll see that you’ve implemented dynamic binding!

也就是说,在99%的情况下,词法绑定的恕我直言要好得多.请注意,现代Lisps不像Emacs lisp那样仅动态绑定.

That said, lexical binding is IMHO much better for 99% of the cases. Note that modern Lisps are not dynamic-binding-only like Emacs lisp.

  • 常见的Lisp支持两种绑定形式,尽管更多的是词汇形式
  • Scheme规范甚至没有指定动态绑定(仅是词法绑定),尽管许多实现都支持动态绑定.

此外,受Lisp启发的现代语言(如Python和Ruby)通常以直接方式支持词法绑定,而动态绑定也可用,但不太直接.

In addition, modern languages like Python and Ruby that were somewhat inspired by Lisp usually support lexical-binding in a straightforward way, with dynamic binding also available but less straightforward.

这篇关于用于动态范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆