wan*_*kai 2 lisp scheme clojure
我知道在Scheme中我可以这样写:
(let ((+ *)) (+ 2 3)) => 6
Run Code Online (Sandbox Code Playgroud)
除此之外,在Clojure中:
(let [+ *] (+ 2 3)) => 6
Run Code Online (Sandbox Code Playgroud)
我知道这可以解决问题,但是感觉很奇怪。我认为在任何语言中,数学运算符都是预定义的。C ++和Scala可以执行运算符重载,但是事实并非如此。
这不会引起混乱吗?为什么Lisp允许这样做?
这不是Lisp的常规功能。
在Common Lisp中,绑定核心语言功能的效果未定义。这意味着开发人员不应期望它可移植代码中工作。一个实现也可以发出警告或错误的信号。
例如,SBCL编译器将发出此错误信号:
; caught ERROR:
; Lock on package COMMON-LISP violated when
; binding + as a local function while
; in package COMMON-LISP-USER.
; See also:
; The SBCL Manual, Node "Package Locks"
; The ANSI Standard, Section 11.1.2.1.2
; (DEFUN FOO (X Y)
; (FLET ((+ (X Y)
; (* X Y)))
; (+ X Y)))
Run Code Online (Sandbox Code Playgroud)
我们可以+
在Common Lisp中拥有自己的组件,但是必须将它放在另一个包中(=符号名称空间):
(defpackage "MYLISP"
(:use "CL")
(:shadow CL:+))
(in-package "MYLISP")
(defun foo (a b)
(flet ((+ (x y)
(* x y)))
(+ a b)))
Run Code Online (Sandbox Code Playgroud)
免责声明:这是从Clojure的角度来看。
+
只是另一个功能 您可以将其传递并编写sum
,具有部分应用程序,请阅读有关它的文档,...:
user=> (apply + [1 2 3])
6
user=> (reduce + [1 2 3])
6
user=> (map (partial + 10) [1 2 3])
(11 12 13)
user=> `+
clojure.core/+
user=> (doc +)
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
Returns the sum of nums. (+) returns 0. Does not auto-promote
longs, will throw on overflow. See also: +'
Run Code Online (Sandbox Code Playgroud)
因此,您可以+
在不同的命名空间中有很多。默认情况下,核心一键的“使用”已为您使用,但您可以自己编写。您可以编写自己的DSL:
user=> (defn + [s] (re-pattern (str s "+")))
WARNING: + already refers to: #'clojure.core/+ in namespace: user, being replaced by: #'user/+
#'user/+
user=> (+ "\\d")
#"\d+"
user=> (re-find (+ "\\d") "666")
"666"
Run Code Online (Sandbox Code Playgroud)
它不是特殊形式,与其他任何功能都没有什么不同。因此,在建立了该名称之后,为什么不应该允许它被覆盖?