代码之家  ›  专栏  ›  技术社区  ›  Cam

方案传递参考

  •  8
  • Cam  · 技术社区  · 14 年前

    如何在方案中通过引用传递变量?

    我想要的功能示例:

    (define foo
      (lambda (&x)
        (set! x 5)))
    
    (define y 2)
    
    (foo y)
    
    (display y) ;outputs: 5
    

    还有,有没有一种方法可以通过引用返回?

    7 回复  |  直到 10 年前
        1
  •  10
  •   Jari    14 年前

    http://community.schemewiki.org/?scheme-faq-language 问题“有没有一种方法可以通过引用来模拟调用?”.

    总的来说,我认为这与方案的功能性相抵触,所以可能有更好的方法来构造程序,使其更像方案。

        2
  •  3
  •   erjiang    14 年前

    就像贾里说的,通常你想避免在计划中引用,因为它表明你滥用了副作用。

    但是,如果您希望,可以将要通过引用传递的任何内容包含在 cons 盒子。

    (cons 5 (void))
    

    将生成一个包含5个的框。如果将此框传递给将5更改为6的过程,则原始框也将包含6。当然,你必须记住 欺骗 car 在适当的时候。

    chez方案(可能还有其他实现)有一个名为 box (及其同伴) box? unbox )专门针对这种拳击/拆箱废话: http://www.scheme.com/csug8/objects.html#./objects:s43

        3
  •  2
  •   grettke    14 年前

    拉姆达!

    (define (foo getx setx)
      (setx (+ (getx) 5)))
    
    (define y 2)
    (display y)(newline)
    
    (foo
     (lambda () y)
     (lambda (val) (set! y val)))
    
    (display y)(newline)
    
        4
  •  2
  •   Davorak    14 年前

    Jari是对的,通过引用传递(至少是通过变量传递)有点不太切题。然而,通过使用闭包,您想要的行为总是以一种更像方案的方式被使用,并且经常被鼓励。 Pages 181 and 182 (谷歌图书)在经验丰富的计划中做得比我能解释的更好。

    这里有一个引用,它提供了一个宏,允许您使用类似C的语法“通过引用”。Olegs站点是有趣的阅读的金矿,因此如果您还没有,请务必对其进行预订标记。

    http://okmij.org/ftp/Scheme/pointer-as-closure.txt

        5
  •  2
  •   gcbenison    12 年前

    可以使用宏:

    scheme@(guile-user)> (define-macro (foo var)`(set! ,var 5))
    scheme@(guile-user)> (define y 2)
    scheme@(guile-user)> (foo y)
    scheme@(guile-user)> (display y)(newline)
    5
    
        6
  •  1
  •   user3446498    10 年前

    您可以从在外部上下文中定义的函数中影响外部上下文,这将给您传递引用变量的影响,即具有副作用的函数。

    (define (outer-function)
      (define referenced-var 0)
      (define (fun-affects-outer-context) (set! referenced-var 12) (void))
      ;...
      (fun-affects-outer-context)
      (display referenced-var)
    )
    (outer-function) ; displays 12
    

    这个解决方案限制了副作用的范围。

    除此之外,还有(定义x(框5)),(unbox x)等,如eli所述,与二江提出的cons解决方案相同。

        7
  •  0
  •   mathk    14 年前

    您可能使用了太多的C、PHP或其他东西。 在这个计划中,你不想做一些像pass-by-*这样的事情。 首先了解范围的含义以及不同的实现的行为(特别是尝试找出Lisp和Scheme之间的区别)。

    从本质上讲,纯函数编程语言没有副作用。因此,它意味着旁路参考不是一个功能概念。

    推荐文章