gpt4 book ai didi

functional-programming - 'parametrize'在DrScheme中做什么?

转载 作者:行者123 更新时间:2023-12-04 08:41:09 26 4
gpt4 key购买 nike

我试图弄清示例代码here(在“示例”下面)。我不了解参数构造。它的文档是here,但是它们没有帮助。它有什么作用?

最佳答案

parameterize用于具有“动态范围”的值。您可以使用make-parameter获得参数。参数本身就是一个函数:不带任何输入即可调用它,您会得到它的值,带一个值调用它,然后它将设置该值。例如:

> (define p (make-parameter "blah"))
> (p)
"blah"
> (p "meh")
> (p)
"meh"

许多函数(包括许多原始函数)使用参数作为自定义其行为的方式。例如, printf将使用 current-output-port参数值的端口打印内容。现在,假设您有一些可以打印某些内容的函数:
> (define (foo x) (printf "the value of x is ~s\n"))

通常,您可以调用此函数并在屏幕上看到打印的内容-但在某些情况下,您想使用它来将内容打印到文件或其他内容。您可以这样做:
(define (bar)
(let ([old-stdout (current-output-port)])
(current-output-port my-own-port)
(foo some-value)
(current-output-port old-stdout)))

这样做的一个问题是这样做很繁琐,但是使用宏很容易解决。 (实际上,PLT仍然具有在某些语言中可以执行此操作的结构: fluid-let。)但是这里还有更多问题:如果对 foo的调用导致运行时错误会发生什么?这可能会使系统处于故障状态,所有输出都进入端口(并且您甚至都不会看到问题,因为它不会打印任何内容)。一种解决方案( fluid-let也使用该方法)是使用 dynamic-wind保护参数的保存/恢复,以确保如果有错误(更多信息,如果您知道延续性),则该值仍会被恢复。

因此,问题是拥有参数而不是仅使用globals和 fluid-let有什么意义?仅全局变量不能解决另外两个问题。一种是当您有多个线程时发生的情况-在这种情况下,临时设置该值将影响其他线程,这些线程可能仍要打印到标准输出。参数通过为每个线程提供特定的值来解决此问题。发生的情况是,每个线程都“继承”了创建它的线程的值,并且一个线程中的更改仅在该线程中可见。

另一个问题更加微妙。假设您有一个带有数字值的参数,并且要执行以下操作:
(define (foo)
(parameterize ([p ...whatever...])
(foo)))

在Scheme中,“尾部调用”很重要-它们是创建循环等的基本工具。 parameterize做了一些魔术,使它可以临时更改参数值,但仍保留这些尾调用。例如,在上述情况下,您将得到一个无限循环,而不是堆栈溢出错误-发生的是,每个 parameterize表达式都可以某种方式检测何时有一个较早的 parameterize不再需要进行清理。

最后, parameterize实际上使用PLT的两个重要部分来完成其工作:它使用线程单元来实现每个线程的值,并且使用连续标记来保留尾调用。这些功能中的每一个本身都是有用的。

关于functional-programming - 'parametrize'在DrScheme中做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1870350/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com