函数

时间:2017-03-05 18:53:40

标签: function lambda common-lisp

在Common Lisp中似乎有许多不同的方法来引用一个函数:

  1. 通过符号,其中符号显示(未引用)为(1+ 2) => 3中表单的汽车,或(mapcar '1+ '(1 2 3)) => (2 3 4)中的功能参数位置;

  2. 通过函数对象,其中(解释或编译的)函数对象可以出现在(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;

  3. 通过lambda表达式,其中lambda表达式显示为((lambda (x) (1+ x)) 2) => 3中lambda形式的汽车,或(mapcar (lambda (x) (1+ x)) '(1 2 3)) => (2 3 4)中的函数参数位置[但是,{{3}无法将lambda表达式识别为“函数指示符”]。

  4. 在这三种“方式”中,对我而言,第一种似乎有些不合适,因为它似乎使Common Lisp运算符只评估其参数一次的基本准则复杂化。如果在上面的示例中,'1+被计算,它将生成符号1+,而不是符号命名的函数。在这种情况下,必须有一个额外的评估,可能是symbol-function来获取函数对象。显然,这只是一种便利,但它似乎打破了一致性。 (一致的形式#'1+几乎一样简单。)我的问题是'是否有任何示例需要使用符号作为函数(除了作为表单的汽车 - 尽管即使这不是必需的,给定lambda表达式),这样就不能完全避免上面第1项中的表达式了吗?。

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的全局符号函数。因此,将通过符号进行查找。