Scheme 球拍:用一个函数改变两个常数

Scheme 球拍:用一个函数改变两个常数,scheme,constants,racket,Scheme,Constants,Racket,我想用一个函数同时更改两个常量,但不知怎么的,它不起作用: (define p 1) (define q 1) (define (change p q) (set! p (+ p 1)) (set! q (+ q 1))) 这将有助于: #lang racket (define p 1) (define q 1) (define (increment-p-and-q) (set! p (+ p 1)) (set! q (+ q 1))) (display (list

我想用一个函数同时更改两个常量,但不知怎么的,它不起作用:

(define p 1)
(define q 1)

(define (change p q)
  (set! p (+ p 1))
  (set! q (+ q 1))) 
这将有助于:

#lang racket
(define p 1)
(define q 1)

(define (increment-p-and-q)
  (set! p (+ p 1))
  (set! q (+ q 1)))


(display (list p q)) ; displays (1 1)
(newline)
(increment-p-and-q)  ; mutates p and q
(display (list p q)) ; displays (2 2)
(newline)

当调用与全局变量具有相同绑定的过程时,它会被隐藏。如果你
设置更改的是本地绑定,而不是全局绑定。

@sylvester对您的问题给出了一个很好的字面回答。另一个字面上的答案是,如果你想让一个函数改变它的参数(像C++中的引用参数一样对待它们),请使用。例如:

(define (change p)
  (set-box! p (+ (unbox p) 1)))

(define p (box 1))

(for/list ([i 3])
  (change p)
  (unbox p))
; => '(2 3 4)

然而,像这样使用变异在球拍中并不常见,也不受鼓励。尽管您可以做到这一点,但我们鼓励使用更实用的方法,甚至可以。

很可能您使用的语言在过程体中没有隐式的
begin
,所以让我们尝试显式编写它:

(define p 1) ; declare variables as global, so they 
(define q 1) ; can be modified inside a procedure

(define (change-vars) ; don't pass them, they won't get modified inside proc
  (begin ; use begin to evaluate expressions sequentially from left to right
    (set! p (+ p 1))
    (set! q (+ q 1)))) ; value of last expression is returned, here's #<void>
您可以使用宏(在本例中定义语法规则),这样您可以将变量作为参数传递:

#lang racket

(define p 1)
(define q 1)

(define-syntax-rule (change p q)
  (begin
    (set! p (+ p 1))
    (set! q (+ q 1))))

(display (list p q)) ; displays (1 1)
(newline)
(change p q)  ; mutates p and q
(display (list p q)) ; displays (2 2)
(newline) 

@JimBoy我用一个完整的例子更新了代码。这对您不起作用吗?我一直收到以下错误消息:define:函数体应该只有一个表达式,但找到了1个额外的表达式part@JimBoy我的代码使用左下角的
从源代码确定语言
,第一行是
#lang racket
,但您没有使用它,是吗?如果您使用的是不同的语言(DrRacket支持几十种语言),您需要将其包含在您的问题中,我们将更新我们的答案。谢谢您,Sylvester。如上所述。这两种解决方案的问题是,如果只想更改一个常数,它们都可以正常工作,但是如果试图更改两个常数,程序就会中断。非常感谢,奥斯卡!我不知道“开始”解决了这个问题。这个函数确实可以工作,只是不能按你认为应该的方式工作。所发生的是,你有两个p的界和两个q的界。此函数更改作为其形式参数的p和q的值,但不更改全局范围内的p和q。
#lang racket

(define p 1)
(define q 1)

(define-syntax-rule (change p q)
  (begin
    (set! p (+ p 1))
    (set! q (+ q 1))))

(display (list p q)) ; displays (1 1)
(newline)
(change p q)  ; mutates p and q
(display (list p q)) ; displays (2 2)
(newline)