更改原始绑定而不会在方案中丢失它们

时间:2013-09-18 04:22:30

标签: scheme key-bindings

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

(define + *)

但是重新定义乘法作为加法而不会丢失加法的绑定,我该怎么办呢?

3 个答案:

答案 0 :(得分:0)

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

#lang racket
(require
 (rename-in racket/base (+ standard+))
 )

所以你可以为你的目的重新定义+作为新的

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

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

答案 1 :(得分:0)

您还可以使用简单的let,它将按照之前的定义绑定事物,而不管其他let定义。在Gambit计划中:

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

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

答案 2 :(得分:0)

使用导入,您可以在Scheme中切换顶级符号,它需要R6RS或更高版本。

#!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

这个答案类似于Modestino的答案,除了答案是针对球拍语言而不是计划语言。

由于这不适用于R5RS,您可能需要查看Valentin's answer,因为这是一个很好的解决方法。请记住让let包装整个代码,它将作为R6RS重命名导入。