[英]What is the difference between an atom in Common Lisp and an atom in Clojure?
[英]What is atom in LISP?
我想清楚地了解一下,LISP 中的“Atom”是什么? 由於 lispworks,“atom - 任何不是缺點的 object。”。 但是這個定義對我來說還不夠清楚。
例如,在下面的代碼中:
(cadr
(caddar (cddddr L)))
“L”是原子嗎? 一方面,L 不是原子,因為它是 cons,因為它是列表(如果我們談論的是 object,它與符號 L 相關聯)。 另一方面,如果我們談論“L”本身(不是關於它的內容,而是關於符號“L”),它是一個原子,因為它不是一個缺點。
我試過將 function 稱為“原子”,
(atom L) => NIL
(atom `L) => T
但我仍然不知道......請幫忙!
所以最后一個問題:在上面的代碼中,“L”是不是原子?
PS 我問這個問題是因為我大學的 LISP 課程,我們有一個“簡單表達式”的定義 - 它是一個表達式,它是一個或兩個原子參數的原子或 function 調用。 因此我想知道表達式(cddddr L)
是否簡單,這取決於 'L' 是否是原子參數。
一方面,L 不是原子,因為它是 cons,因為它是列表(如果我們談論的是 object,它與符號 L 相關聯)。
您在這里談論的是正在執行的代碼的含義及其語義。 這里的L
代表一個值,就是你測試中的一個列表。 在運行時,您可以檢查值並詢問它們的類型。
另一方面,如果我們談論“L”本身(不是關於它的內容,而是關於符號“L”),它是一個原子,因為它不是一個缺點。
在這里,您正在查看構成代碼語法的值的類型,以及在評估(或編譯)之前如何表示它。 您正在操縱一棵符號樹,其中一個是L
。 在源代碼中,這是一個符號。 除了作為一個名字之外,它本身沒有任何意義。
Lisp 可以很容易地使用語言本身的值來表示源代碼,並且可以很容易地一次操作代碼片段以構建稍后執行的代碼。 這通常被稱為同源性,認為這是一個有點敏感的詞,因為人們並不總是認為定義足夠精確以至於有用。 另一種說法是“代碼就是數據”,大多數語言設計者和程序員都會同意這一點。
Lisp 代碼可以在運行時構建如下( >
是 REPL 的提示符,后面是評估結果):
> (list 'defun 'foo (list 'l) (list 'car 'l))
(DEFUN FOO (L) (CAR L))
結果形式恰好是有效的 Common Lisp 代碼,而不僅僅是一個通用的值列表。 如果您使用(eval *)
評估它,您將定義一個名為FOO
的 function,它采用某個列表L
的第一個元素。
注意。 在 Common Lisp 中,星號*
在 REPL 中綁定到成功返回的最后一個值。
通常你不會像那樣構建代碼,Lisp閱讀器會將 stream 個字符變成這樣一棵樹。 例如:
> (read-from-string "(defun foo (l) (car l))")
(DEFUN FOO (L) (CAR L))
但是在 REPL 中也隱含地調用了讀者(首字母縮寫詞中的 R)。
在這樣的符號樹中, L
是一個符號。
當您在定義 FOO 后調用 function FOO
時,您是在L
綁定到某個值的上下文中評估FOO
的主體。 評估一個符號的規則是查找它綁定的值,然后返回它。 這是代碼的語義,由運行時為您實現。
如果您使用的是簡單的解釋器,那么符號L
可能會在運行時出現在某處,並且會查找它的綁定。 通常代碼不是那樣解釋的,可以在編譯期間以有效的方式對其進行分析和轉換。 編譯的結果這里可能不再操作符號了,它只是操作CPU寄存器和memory。
在所有情況下,此時詢問L
的類型是根據語義的定義,只是詢問類型在它出現的上下文中綁定到L
的任何值。
實際上, atom
的定義並不比這更復雜。 語言中不是cons-cell的值稱為原子。 這包括數字、字符串和一切。 有時你評估一棵恰好是代碼的符號樹,但同樣的規則適用。
PS 我問這個問題是因為我大學的 LISP 課程,我們有一個“簡單表達式”的定義 - 它是一個表達式,它是一個或兩個原子參數的原子或 function 調用。 因此我想知道表達式 (cddddr L) 是否簡單,這取決於 'L' 是否是原子參數。
在該課程中,您正在編寫分析代碼的函數。 給你一個 Lisp 值,你必須決定它是否是一個簡單的表達式。
您對給定值的任何特定解釋不感興趣,在任何時候您都不會遍歷該值,查看一個符號並嘗試將其解析為一個值:您正在檢查語法是否是有效的簡單表達式.
另請注意,您課程中的定義可能與任何特定現有風格的定義略有不同(這不一定是 Common Lisp 或 Scheme,而是玩具 LISP 方言)。 優先遵循課程中的定義。
您的 Lisp 課程對“簡單表達式”的私人定義幾乎可以肯定是完全植根於語法的。 “原子參數”的概念意味着它不是復合表達式。 它可能與運行時值無關!
因此,我猜,這些是簡單的表達式:
(+ 1 2)
42
"abc"
而這些不是:
(+ 1 (* 3 4)) ;; (* 3 4) is not an atomic parameter
(+ a b c) ;; parameters atomic, but more than two
(foo) ;; not simple: fewer than one parameter, not "one or two"
鑒於最后一個反例,他們可能需要修改他們的定義。
假設我們有一個謂詞,它告訴我們 object 是否不是數字:
(not-number-p 3) -> NIL
(not-number-p "string") -> T
(let ((foo "another string))
(not-number-p foo)) -> T
(not-number '(1 2 3)) -> T
(not-number (first '(1 2 3)) -> NIL
我們可以將其定義為:
(defun not-number-p (object)
(not (numberp object))
以上與NUMBERP
正好相反。
NUMBERP
-> T
如果 object 是一個數字NOT-NUMBER-P
-> NIL
如果 object 是一個數字現在想象我們有一個謂詞NOT-CONS-P
,它告訴我們 object 是否不是一個cons cell 。
(not-cons-p '(1 . 2)) -> NIL
(let ((c '(1 . 2)))
(not-cons-p c)) -> NIL
(not-cons-p 3) -> T
(let ((n 4))
(not-cons-p n)) -> T
(not-cons-p NIL) -> T
(not-cons-p 'NIL) -> T
(not-cons-p 'a-symbol) -> T
(not-cons-p #\space) -> T
function NOT-CONS-P
可以定義為:
(defun not-cons-p (object)
(if (consp object)
NIL
T))
或者更短:
(defun not-cons-p (object)
(not (consp object))
function NOT-CONS-P
在 Lisp 中傳統上稱為ATOM
。 在 Common Lisp 中,每個不是cons 單元的 object 都被稱為atom 。 function ATOM
是一個檢查它的謂詞。
請參閱 Common Lisp HyperSpec: Function Atom
假設我們有一個謂詞,它告訴我們 object 是否不是數字:
(not-number-p 3) -> NIL
(not-number-p "string") -> T
(let ((foo "another string))
(not-number-p foo)) -> T
(not-number '(1 2 3)) -> T
(not-number (first '(1 2 3)) -> NIL
我們可以將其定義為:
(defun not-number-p (object)
(not (numberp object))
以上與NUMBERP
正好相反。
NUMBERP
-> T
如果 object 是一個數字NOT-NUMBER-P
-> NIL
如果 object 是一個數字現在假設我們有一個謂詞NOT-CONS-P
,它告訴我們 object 是否不是CONS
單元格。
(not-cons-p '(1 . 2)) -> NIL
(let ((c '(1 . 2)))
(not-cons-p c)) -> NIL
(not-cons-p 3) -> T
(let ((n 4))
(not-cons-p n)) -> T
(not-cons-p NIL) -> T
(not-cons-p 'NIL) -> T
(not-cons-p 'a-symbol) -> T
(not-cons-p #\space) -> T
function NOT-CONS-P
可以定義為:
(defun not-cons-p (object)
(if (consp object)
NIL
T))
或者更短:
(defun not-cons-p (object)
(not (consp object))
function NOT-CONS-P
在 Lisp 中傳統上稱為ATOM
。
在 Common Lisp 中,每個不是cons 單元的 object 都稱為atom 。 function ATOM
是一個謂詞。
請參閱 Common Lisp HyperSpec: Function Atom
你的問題:
(cadr (caddar (cddddr L)))
Is 'L' an atom?
我們怎么知道呢? L
是一個變量。 L
的值是多少?
(let ((L 10))
(atom L)) -> T
(let ((L (cons 1 2)))
(atom L) -> NIL
(atom l)
回答了這個問題:
-> 是L
一個原子的值
(atom l)
沒有回答這個問題:
-> L
是原子嗎? L
是一個變量,在 function 調用中, L
的值被傳遞給 function ATOM
。
如果你想問符號L
是否是一個原子,那么你需要引用符號:
(atom 'L) -> T
(atom (quote L)) -> T
符號是原子。 實際上一切都是原子,cons cells除外。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.