方案:重载内置程序,一般重载

时间:2013-04-09 02:19:44

标签: scheme overloading

更具体地说,你可以重载内置的Scheme程序显示吗?

更一般地说,如何重载Scheme中的任何过程?

2 个答案:

答案 0 :(得分:2)

Scheme没有基于Java / C ++类型的重载,它是动态类型的,因此没有意义。

你可以做一些事情:

您可以根据参数的结构重载:

(define overload1
    (case-lambda
        ((x y) (+ x y))
        ((x y z) (+ (- x y) z))))

这并没有真正帮助你,因为display无论如何只会采取一个论点。

(define (overload-kinda x)
    (cond
        ((list? x) (do-list x))
        ((symbol? x) (do-sym x))
        ;etc
        ))

哪个是hacky但有时是必要的。

我通常的方法是更高阶函数和案例lambda

(define my-display
    (case-lambda
        ((x) (display x))
        ((x f) (display (f x)))))

现在,如果我们需要特殊处理来显示任何东西,我们会传递一个函数来渲染它。

答案 1 :(得分:0)

接受的答案不会重载函数,只会定义具有相同行为的不同函数。

Scheme 通常允许覆盖 bultin 函数,因此要重载函数(例如 display),您可以使用名为 Monkey Patch 的东西:

(define display (let ((orig display))
                  (lambda (x . rest)
                     (let ((port (if (null? rest)
                                     (current-output-port)
                                     (car rest))))
                       (if (number? x)
                           (orig (string-append "#<" (number->string x 16) ">") port)
                           (orig x port))))))

现在显示与数字的工作方式不同。您还可以使用自定义类型,例如以特定方式显示不同类型的记录。这是如何在任何允许修改原始绑定的语言中覆盖 bultin 函数的一般示例。您将原始函数保存在变量中,重新定义函数,如果您调用原始函数,则使用保存原始函数的变量。

代码可以抽象为通用宏,该宏将重新定义函数并在特定类型的参数上运行您的代码,因此它会像在 Java 中一样正确重载,而不仅仅是基于 {{1} 中的参数数量}.

以下是此类宏的示例(使用 lisp 类型宏):

case-lambda