【问题标题】:scheme and set!计划和设置!
【发布时间】:2009-11-10 12:50:51
【问题描述】:

如何通过使用 lambda 参数的函数更改变量的值? 即:

;;definitions
(define test "fails")
(define (experiment input) (set! input "works"))

;;interactions
> test
"fails"
> (experiment test)
> test
"fails"

这似乎失败了..

问候

【问题讨论】:

    标签: variables lisp scheme


    【解决方案1】:

    你不能——Scheme“按值”传递所有值,所以在上面的experiment 函数只是修改了它自己的输入参数。为了让这样的事情正常工作,你可以使用一个盒子,它是一个明确可变的值容器:

    (define test (box "fails"))
    (define (experiment input) (set-box! input "works"))
    (unbox test)
    (experiment test)
    (unbox test)
    

    如果你真的想改变一个变量的值,你可以使用宏:

    (define-syntax-rule (experiment input) (set! input "works"))
    

    这会将experiment 创建为一个宏,这意味着每个(experiment foo) 表单都将被重写为(set! foo "works")。这可能会产生微妙的后果,因此除非您知道自己在做什么,否则使用它不是一个好主意。 (例如,(experiment 2) 会以一种“有趣”的方式失败。)在 Scheme 中编写宏很容易,但编写好的宏仍然比编写新的函数定义更困难。

    [请注意,我假设您在此答案中使用 PLT 方案。但是如果需要,这两个部分都可以转换为“标准”方案——例如,第一个使用可变的cons 单元格,第二个使用define-syntaxsyntax-rules。]

    【讨论】:

    • 这也可以通过参数来完成:srfi.schemers.org/srfi-39/srfi-39.html
    • 是的,参数是另一种可变的容器(PLT 还有更多,比如thread-cell)。但是它们的语义可能与普通的全局略有不同。例如,一个参数对每个线程都有一个唯一值(更准确地说,每个延续都有一个唯一值)。
    【解决方案2】:

    如果您在 Python 中考虑相同的代码,也许会更有意义:

    test = "fails"
    def experiment(input):
      input = "works"
    
    >>> test
    'fails'
    >>> experiment(test)
    >>> test
    'fails'
    

    【讨论】:

    • 这如何回答这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2010-10-20
    • 2011-01-19
    相关资源
    最近更新 更多