更具体地说,你可以重载内置的Scheme程序显示吗?
更一般地说,如何重载Scheme中的任何过程?
答案 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