2017-04-21 69 views
0

我試着用遞歸Clojure中創建階乘函數現在的Clojure,試圖調用未FN

(defn fac[x] (if (= x 1) 1 (* x (fac (- x 1))))) 

,當我嘗試調用函數

(fac 5)

我得到的異常

java.lang.IllegalStateException: Attempting to call unbound fn: #'sandbox11355/fac 

這是否意味着它是不可能使用易復發在使用defn關鍵字定義函數時使用sion嗎?

此外,我將如何最有效地擁抱這個功能語法,因爲我已經習慣了勢在必行的思維/ OOP方式?以相反的順序輸入所有內容感覺很尷尬。通過程序範式,思維的連續性直接映射到改變值的新代碼行。隨着功能的語法,每一步操作的電流值,我必須包裝新功能周圍的表達,這是很難掌握的括號和範圍的。我是否應該學會以相反的順序思考程序模型,以便在功能方面進行流暢的編碼?

我理解的沒有可變狀態和純函數(更少的錯誤)的好處,但很難相信這是值得不失輕鬆編寫程序代碼的。就目前而言,所有這些似乎都是過分誇大的無組織混亂,但也許它開始有意義。

+2

我無法重現您所看到的例外,我希望它的工作。 lisp語法需要幾天時間才能習慣 - 確保使用編輯器來爲您排列對齊,而不是編寫長的單行表達式,並且它會更清晰。 – Lee

+0

我會繼續 - 這應該很好。你正在使用哪個版本的Clojure? –

+0

你的'defn'沒有問題。您正在編譯的文件是否爲該編輯的最新版本? – Thumbnail

回答

5

您對功能和過程的編程關注如下一些信息。這不是特別原創,但也許會讓你開始思考如何去思考這個新東西。

函數式編程是不反向過程編程。這是一個更高層次的抽象,我們與之交互的大多數東西都可以被看作是一種抽象;否則,我們永遠不會得到任何有用的東西,因爲我們會非常關心我們處理的每一件小事情的細節。同樣,任何語言的所有代碼最終都會成爲對CPU的一系列指令,這些指令是「必要的」或「程序性」的縮影。問題就變成了:「爲了解決我的問題,我需要多少控制才能解決極低的細節問題?」

一種方式一些數字加在一起,是非常明確的(只是僞代碼,希望的意圖十分明顯):

int nums[10] = {0,1,2,3,4,5,6,7,8,9}; 
int i = 0; 
int acc = 0; 

start_loop: 
    if (i >= 10) goto done_loop; 

    int num_address = (nums + i); 
    int num_value = *num_address; 
    acc = acc + num_value; 
    i = i + 1; 
    goto start_loop; 

done_loop: 
    return acc; 

這是乏味的,但不作爲彙編代碼的繁瑣。抽象出一些循環的細節,C/JAVA /等提供控制結構稱爲for循環:

int nums[10] = {0,1,2,3,4,5,6,7,8,9}; 
int acc = 0; 

for (int i = 0; i < 10; i++) 
    acc += nums[i]; 

return acc; 

這似乎是完全正常的,當然,當你定期編寫代碼勢在必行。您可以反覆思考,並瞭解如何在每個基底偏移處訪問數組的細節。然而,這也可以被認爲是乏味的。爲什麼我應該關心如何訪問陣列的每個成員的細節?任何功能語言提供的進一步抽象被稱爲reduce。把它看作是一種類似的方式提供的工具,for提供給C/java/etc程序員。這看起來很奇怪,很多相同的方式for語法會裝配程序員看到它的第一次:

(reduce + (range 10)) 

因此,所有我們在這裏所做的環路的細節抽象出來到如此地步,我們真的不太關心實際發生的循環。我們還抽象出創造數字的明確範圍的細節,只是說:「給我從0(含)〜10(不含)的整數」。它只是抽象出細節。結果通常能夠更專注於手頭的問題。

對於添加數字,或思考更高層次,編程的功能性的方式通常可以使我們的工作效率,用更少的代碼,而我們讓編譯器的各級處理繁瑣的細節對我們。然而,如果問題水平很低,那麼我們可能希望用更適合我們問題的語言構造。關鍵是始終使用正確的工具來完成正確的工作。

當然,它不是一個完美的世界,並經常用Clojure我們被迫寫底層細節處理比特和字節,同步並行代碼,循環等等。但是總體來說,是聲明,並說明你想做的事,而不是更加明確如何做什麼,有很多好處。

4clojure問題,給它一兩個月纔開始真正有意義,並讓你的思想從變異變量轉變爲評估表達式。有一個非常高的概率,你會非常喜歡,而且最壞的情況是,你可以擴大你的視野。祝好運並玩得開心點!