更改基元绑定而不会在scheme中丢失它们

更改基元绑定而不会在scheme中丢失它们,scheme,key-bindings,Scheme,Key Bindings,例如,如果我想将加法重新定义为乘法: (define + *) 但也将乘法重新定义为加法,而不丢失加法的绑定,我如何才能做到这一点?您可以使用require机制来重新定义标准过程。这些重新定义可以通过这种方式在Racket(R5RS实现)中实现。您可以要求standard+使用不同的名称(standard+): 因此,您可以根据自己的目的将+重新定义为一个新的 (define + (lambda args (if (not(null? args)) (apply

例如,如果我想将加法重新定义为乘法:

(define + *)

但也将乘法重新定义为加法,而不丢失加法的绑定,我如何才能做到这一点?

您可以使用require机制来重新定义标准过程。这些重新定义可以通过这种方式在Racket(R5RS实现)中实现。您可以要求standard+使用不同的名称(standard+):

因此,您可以根据自己的目的将+重新定义为一个新的

(define +
  (lambda args
    (if (not(null? args))
        (apply
         (cond
           (??? *)
           (else standard+))
         args)
        0)))

哪里???是您的布尔条件(或只是一个返回布尔值的函数),用于*而不是+。

您也可以使用简单的
let
,它将绑定之前定义的内容,而不考虑其他
let
定义。在博弈方案中:

> (* (+ 2 4) 2) ;; = 2 * (2 + 4)
12

> (let ((confusing #t)(+ *)(* +)) ;; Redefining operations
    (* (+ 2 4) 2))  ;; = 2 + (2 * 4)
10

通过导入,您可以在Scheme中切换顶级符号,它需要R6R或更高版本

#!r6rs
(import (except (rnrs base) + *)
        (rename (rnrs base) (* +) (+ *)))

(+ (* 2 3) 4) ; ==> 20
如果您不想使用相同的符号创建自己的语言,并且需要通过某些方法访问原始实现符号,则也可以使用前缀import:

#!r6rs
(import (prefix (rnrs base) base:))
(base:define * base:+)
(base:define + base:*)
(+ (* 2 3) 4) ; ==> 20
这个答案与莫德斯蒂诺的答案相似,只是他们的答案是关于敲诈语言而不是计划语言

由于这对R5R不起作用,您可能想看看,因为这是一个很好的解决方法。只需记住让let包装整个代码,它将作为R6RS重命名导入工作

#!r6rs
(import (prefix (rnrs base) base:))
(base:define * base:+)
(base:define + base:*)
(+ (* 2 3) 4) ; ==> 20