2014-09-29 58 views
3

我們可以看到,我們可以使用reduce/foldl1作爲函數by which we can define other higher order functions such as map, filter and reverse爲什麼fold和reduce被認爲是根本性的 - 當然,所有的東西都是根據cons和car定義的?

(defn mapl [f coll] 
    (reduce (fn [r x] (conj r (f x))) 
      [] coll)) 

(defn filterl [pred coll] 
    (reduce (fn [r x] (if (pred x) (conj r x) r)) 
      [] coll)) 

(defn mapcatl [f coll] 
    (reduce (fn [r x] (reduce conj r (f x))) 
      [] coll)) 

我們也似乎能夠按照foldr的方式做到這一點。根據foldr from Rich Hickey's Transducers talk在17:25,這裏是mapfilter

(defn mapr [f coll] 
    (foldr (fn [x r] (cons (f x) r)) 
     () coll)) 

(defn filterr [pred coll] 
    (foldr (fn [x r] (if (pred x) (cons x r) r)) 
     () coll)) 

現在,我們可以定義mapfoldlreduce)和foldrfirstrestconscarcdrcons)方面:

(defn foldr [f z xs] 
    (if (null? xs) 
     z 
     (f (first xs) (foldr f z (rest xs))))) 

(defn foldl [f z xs] 
    (if (null? xs) 
     z 
     (foldl f (f z (first xs)) (rest xs)))) 

(defn map [f lst] 
    (if (null? lst) 
     '() 
     (cons (f (first lst)) (map f (rest lst))))) 

我的問題是爲什麼foldreduce被認爲是根本性的 - 當然一切都按照cons,cdrcar這是不是在看錯級別的東西?

+2

([與香蕉,鏡頭 信封和鐵絲網函數式編程] http://wwwhome.ewi.utwente.nl/~fokkinga/mmf91m.pdf )似乎相關。我也懷疑是否有不止一種「基本」的觀察方式 - Clojure的實現方式的確如此,但是也有一種描述事物的數學方法。 – 2014-09-29 12:06:15

+0

我真的很感激這個評論馬特 - 我只是想知道是否有一些我們可以分類的「積木開始的地方」。有人說Lisp是麥克斯韋軟件方程http://www.michaelnielsen.org/ddi/lisp-as-the-maxwells-equations-of-software/ - 但這個問答的主題是,這僅限於'lists',有時候你想用'fold'來轉換非列表結構。 – hawkeye 2014-09-29 22:20:01

+0

請注意,'cons','car'和'cdr'在客觀意義上不是原始的:您可以用'lambda'來定義它們。那麼爲什麼要求把這一切都歸結爲這三種特定的原始操作,而不是其他的操作呢?這都是相對的。 – amalloy 2014-09-29 23:56:25

回答

6

我以爲Rich Hickey正是在他的talk about transducers中解釋過的。

他認爲folds是轉變的基本概念。它不需要知道它在做什麼結構以及如何操作這個結構。

您剛剛根據自身定義foldcdr,carrest。 Rich所爭辯的是,fold本身就是一個抽象的概念,與它所操作的數據結構分開,只要我們提供某些實際在數據結構上運行的函數,它就能按預期工作。

所以最終都是關於顧慮和可重用性的分離。

0

摺疊是一種統一的原則性數據處理框架,因爲它們對應于歸納數據定義。他們不是特設的。 cons/car/cdr是創建數據(和代碼)的基石,但是以無原則的方式(我們可以做任何事情,並且專門處理它)。摺疊更高層次,更有紀律,更可預測,更容易推理。

鑑於map,filter,mapcat爲列表的臨時實現,我們可以看到它們中有類似的東西 - 遵循數據結構的代碼結構(列表,由cons節點構成,列表對應於組合函數的兩個參數)。這是摺疊。

在那次演講中,Rich Hickey抽象出了階梯函數。但他並沒有對數據進行抽象。用於摺疊標記樹的任何組合函數都需要三個參數,而不是兩個。所以他的功能仍然是從概念上摺疊列表,只是它們對列表的具體實現進行了抽象 - 無論是作爲單元格,哈希陣列樹,不管。

+0

是的 - 當'不是所有東西都是列表'時,對Lispers(和我一樣)感到震驚 - 而且你需要一個可以轉換非列表數據結構的HOF。真的很感謝這個答案。 – hawkeye 2014-09-30 22:58:46

+0

您還需要一個HOF來轉換列表數據。 (我的意思是「更高層次」*某種方式......)摺疊在概念上與數據類型直接對應。 [教會編碼](https://en.wikipedia.org/wiki/Church_encoding#Represent_the_list_using_right_fold)是一個摺疊。順便說一下,這是一個非常有趣的成就,這種分離以及像*抽象*這樣簡單的基本工具。 Abelson和Sussman可以引以爲傲。 :)這是一個衆所周知的問題,在Haskell例如所有數據類型都是具體的。 – 2014-09-30 23:11:13

0

大多數使用lispy語言的操作員都會有一個可以用來定義它的合作伙伴,反之亦然。這個屬性被稱爲「metacircularity」。沒有一個特定的基本操作符集合,這是允許該語言給出的全部可編程性的基本最小值。

你可以閱讀更多的文章: http://home.pipeline.com/~hbaker1/MetaCircular.html

+0

迷人的要求。這個問題會不同意這個假設http://stackoverflow.com/questions/3482389/how-many-primitives-does-it-take-to-build-a-lisp-machine-ten-seven-or-five 你鏈接的文章提到了,catch和標籤。無論如何,我認爲沒有人會認爲這些都是根本。也許你可以爲你的申請提供額外的參考資料? – hawkeye 2014-10-01 22:36:10

+0

嗯,對comp.lang.lisp討論應定義爲基礎運營商(爲macroexpand'和代碼步行者的'目的,辯論,設置運營商與通信從ANSI標準的編輯器。不知道如何找到它在這一點上,但你可以看看「特種作戰」的列表中ANSI Common Lisp的標準,如果你想證明一個決定了。 您參考不討論什麼是根本的問題,而什麼是包括在原來的Lisp。 – 2014-10-21 01:07:53

相關問題