Scheme 根据条件变量对变量的引用

Scheme 根据条件变量对变量的引用,scheme,lisp,Scheme,Lisp,我们可以根据条件选择一个运算符: (let ((x 10)) (display ((if (< 0 1) - +) x)) (newline) ) ; output -10 目的是清理这段代码: (define-macro (inc x n) `(set! ,x (+ ,x ,n)) ) define hmap (make-hash-table 50)) (hashq-set! hmap 'foo "bar") (hashq-set! hmap

我们可以根据条件选择一个运算符:

(let ((x 10))
    (display ((if (< 0 1) - +) x))
    (newline)
)
; output -10
目的是清理这段代码:

(define-macro (inc x n)
    `(set! ,x (+ ,x ,n))
)
define hmap (make-hash-table 50))
(hashq-set! hmap 'foo "bar")
(hashq-set! hmap 'bar "foo")
(hashq-set! hmap 'baz 42)
(let ((n 0) (n-strings 0) (n-numbers 0))
    (hash-fold
        (lambda (key value seed)
            (inc n 1)
            (if (string? value)
                (inc n-strings 1)
                (if (number? value)
                    (inc n-numbers 1)
                )
            )
        )
        0 hmap
    )
    (format #t "The map contains ~a elements: ~a are strings and ~a are numbers\n"
        n n-strings n-numbers
    )
)

如何以更优雅的方式实现它?

您可以用这种方式读取变量,因为读取变量的结果只是一个普通值。但是变量本身并不是一流的:您不能以允许您写入的方式存储
(if(<0 1)x y)
的结果。

您可以用这种方式读取变量,因为读取变量的结果只是一个普通值。但是变量本身不是一流的:您不能以允许您写入的方式存储
(if(<0 1)x y)
的结果。

我想您可以,但是
设置不会。我不确定下面的宏是否完全正确,但我认为它可能是正确的。不过我只是在球拍上测试过

(define-syntax st!
  (syntax-rules (if cond)
    [(_ (if test a b) v)
     (if test
         (st! a v)
         (st! b v))]
    [(_ (cond
          [test a]
          ...) v)
     (cond
       [test (st! a v)]
       ...)]
    [(_ var val)
     (set! var val)]))
然后

>(let((x0)(y0))
(st!(如果(<01)x y)1)
(显示x)(换行)
(显示y)(换行符))
1.
0

请注意,您需要对希望它进入的所有内容进行特殊处理,而且我对
语法规则中的整个文字部分也有点不确定(我确实是一个穴居人CL人,所以我只对由泥和碎饼干组成的宏系统感到非常舒服)。

我想您可以,但是
设置不会。我不确定下面的宏是否完全正确,但我认为它可能是正确的。不过我只是在球拍上测试过

(define-syntax st!
  (syntax-rules (if cond)
    [(_ (if test a b) v)
     (if test
         (st! a v)
         (st! b v))]
    [(_ (cond
          [test a]
          ...) v)
     (cond
       [test (st! a v)]
       ...)]
    [(_ var val)
     (set! var val)]))
然后

>(let((x0)(y0))
(st!(如果(<01)x y)1)
(显示x)(换行)
(显示y)(换行符))
1.
0

请注意,您需要对希望它进入的所有内容进行特殊处理,而且我对
语法规则中的整个文字部分也有点不确定(我确实是一个穴居人CL人,所以我只对由泥和碎饼干组成的宏系统感到非常舒服)。

也就是说!,我对它进行了一些修改,以使其工作正常,谢谢!!(哎呀,你复制了答案,你可以删除另一个)@DavidRanieri:哎呀,不知道我是怎么做到的!如果你需要一个专门的操作符来设置一个
If
,你最好做一个
(设置If!条件然后放置else放置新值)
@Kaz:好吧,这是一个玩具示例来说明你可以做到这一点:我认为这不是我在现实生活中真正想要的东西。然而,在Racket中,编写一个只提供
st设置为
设置
,这意味着使用此模块的任何东西都将获得
集合的特殊魔力。太多的魔法==>不透明和不可维护的代码,完全不能编写这样的代码可能会更好。:)错误的经济性不是优雅的:在示例操作代码中使用嵌套ifs的正确方法是将它们转换为一个cond表达式/就是这样!,我对它进行了一些修改,以使其工作正常,谢谢!!(哎呀,你复制了答案,你可以删除另一个)@DavidRanieri:哎呀,不知道我是怎么做到的!如果你需要一个专门的操作符来设置一个
If
,你最好做一个
(设置If!条件然后放置else放置新值)
@Kaz:好吧,这是一个玩具示例来说明你可以做到这一点:我认为这不是我在现实生活中真正想要的东西。然而,在Racket中,编写一个只提供
st设置为
设置
,这意味着使用此模块的任何东西都将获得
集合的特殊魔力。太多的魔法==>不透明和不可维护的代码,完全不能编写这样的代码可能会更好。:)错误的经济性不是优雅的:在示例操作代码中使用嵌套ifs的正确方法是将它们转换为一个cond表达式/旁注:这将是虚假的优雅。只需重新编写嵌套的if作为条件。最好不要编写脆弱、复杂、难以更改的代码。我们的目标是让代码不言而喻地正确。因此,它必须清晰、简单,这将是虚假的优雅。只需重新编写嵌套的if作为条件。最好不要编写脆弱、复杂、难以更改的代码。我们的目标是让代码不言而喻地正确。为此,它必须清晰、简单。
(define-syntax st!
  (syntax-rules (if cond)
    [(_ (if test a b) v)
     (if test
         (st! a v)
         (st! b v))]
    [(_ (cond
          [test a]
          ...) v)
     (cond
       [test (st! a v)]
       ...)]
    [(_ var val)
     (set! var val)]))
> (let ((x 0) (y 0))
    (st! (if (< 0 1) x y) 1)
    (display x) (newline)
    (display y) (newline))
1
0