在Common Lisp中似乎有许多不同的方法来引用一个函数:
通过符号,其中符号显示(未引用)为(1+ 2) => 3
中表单的汽车,或(mapcar '1+ '(1 2 3)) => (2 3 4)
中的功能参数位置;
通过函数对象,其中(解释或编译的)函数对象可以出现在(mapcar #'1+ '(1 2 3)) => (2 3 4)
或(mapcar (symbol-function '1+) '(1 2 3)) => (2 3 4)
中的函数参数位置,但不能作为(#'1+ 2) => error
中的形式的汽车出现{1}}或((symbol-function '1+) 2) => error
;
通过lambda表达式,其中lambda表达式显示为((lambda (x) (1+ x)) 2) => 3
中lambda形式的汽车,或(mapcar (lambda (x) (1+ x)) '(1 2 3)) => (2 3 4)
中的函数参数位置[但是,{{3}无法将lambda表达式识别为“函数指示符”]。
在这三种“方式”中,对我而言,第一种似乎有些不合适,因为它似乎使Common Lisp运算符只评估其参数一次的基本准则复杂化。如果在上面的示例中,'1+
被计算,它将生成符号1+
,而不是符号命名的函数。在这种情况下,必须有一个额外的评估,可能是symbol-function
来获取函数对象。显然,这只是一种便利,但它似乎打破了一致性。 (一致的形式#'1+
几乎一样简单。)我的问题是'是否有任何示例需要使用符号作为函数(除了作为表单的汽车 - 尽管即使这不是必需的,给定lambda表达式),这样就不能完全避免上面第1项中的表达式了吗?。
答案 0 :(得分:7)
符号作为对象的名称:指示符
通常,符号是对象的名称,可以用来代替这些对象。
在Common Lisp a designator中调用类似符号(或字符串,字符)之类的东西的概念。{/ p>
指示符的一些示例:
功能代号:
from sklearn.datasets import load_iris
import pandas as pd
from scipy.spatial import distance
# Load data
X = pd.DataFrame(load_iris().data, columns = load_iris().feature_names, index = map(lambda x:"iris_%d"%x, range(150)))
# Get distance matrix (labeled)
DF_dism = 1 - X.T.corr()
DF_dism.shape
(150, 150)
# Index the matrix to get a pairwise distance between 2 labeled objects
print(DF_dism.loc["iris_5","iris_140"])
# 0.410805649878
# Condense into squareform
distance.squareform(DF_dism)
# Now it's not labeled and I can't index it
# array([ 4.00133876e-03, 2.60889537e-05, 1.83154822e-03, ...,
# 4.29187441e-03, 5.53987884e-03, 8.41229000e-05])
用于命名类的类或符号:
Python= 3.6.0 |Anaconda 4.3.0 (x86_64)| (default, Dec 23 2016, 13:19:00)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
Pandas= 0.19.2
SciPy= 0.18.1
包装代号:
(funcall 'list 1 2 3)
<->
(funcall (symbol-function 'list) 1 2 3)
字符串指示符:
(make-instance 'my-class)
<->
(make-instance (find-class 'my-class))
(package-use-list 'cl-user)
<->
(package-use-list (find-package 'cl-user))
<->
(package-use-list "CL-USER")
的第一个参数因此未定义为函数,而是定义为函数指示符。在这种情况下,可以是函数对象,也可以是符号。如果是符号,则检索全局符号函数。
历史上,Lisp使用符号作为各种对象的名称。这在后来的一些方言或派生语言中不那么突出。
函数对象与调用命名函数与调用符号函数
(string-upcase 'f)
<->
(string-upcase (symbol-name 'f))
<->
(string-upcase #\f)
上面调用名为FUNCALL
的词法函数。如果没有词法函数foo,则调用...(funcall (function foo) 1 2 3)...
...(funcall #'foo 1 2 3)...
的符号函数。 Lisp文件编译器可能会假设这是同一文件中的相同命名函数。
foo
上面调用名为foo
的词法函数。如果没有词法函数foo,则调用...(foo 1 2 3)...
的符号函数。 Lisp文件编译器可能会假设这是同一文件中的相同命名函数。
foo
以上调用foo
的全局符号函数。因此,将通过符号进行查找。