2012-04-10 43 views
8

我是clojure的新手,我正在努力的主要事情是編寫可讀代碼。我經常結束如下的功能。管理clojure中的括號數

(fn rep 
    ([lst n] 
    (rep (rest lst) 
    n 
    (take n 
     (repeat (first lst))))) 
    ([lst n out] 
    (if 
     (empty? lst) 
     out 
     (rep 
     (rest lst) n 
     (concat out (take n 
      (repeat 
      (first lst)))))))) 

有很多末端括號的構建。什麼是最好的方法來減少或格式化它,以便更容易找到丟失的括號?

+1

這就是你的「Lisp-anese」。使用一個體面的編輯器,可以幫助支架匹配是一條可行的路線。 – 2012-04-10 19:39:32

+1

你總是可以將單括號放在他們自己的行上,並用左括號(如C#或Java的標準大括號語法)排列它們。一些鐵桿Lispers可能會在你身上發表猥褻的言辭:) – 2012-04-10 19:44:45

+7

我想我會介入作爲「鐵桿聽衆」,儘管我只用了兩年的lisp。把人們放在他們自己的路線上就像格式化的主要罪惡 - 沒有更糟糕的選擇,你可以做出。 lisp的許多方言都有(或多或少)以單一的編碼風格解決,因爲它的可讀性很好,不像C類語言,它們都具有激發聖戰的許多風格。不要因爲沒有掌握標準風格而放棄標準風格。 – amalloy 2012-04-10 20:40:08

回答

7

在這種情況下,爲括號着色的編輯器非常有用。例如,這裏是你的代碼在我的vim編輯器的內容(使用vimclojure):

Rainbow colors

既然你沒有說你使用的編輯器,你必須找到一個彩虹色的功能編輯適當。

+0

emacs看到這個問題:http://stackoverflow.com/questions/2413047/how-do-i-get-rainbow-parentheses-in-emacs – 2012-04-10 20:40:37

+0

我在emacs中使用了一段時間的彩虹parens。我現在不再這麼做了,主要是因爲我認爲這會鼓勵你實際進行手動/精神paren匹配,而不是讓paredit爲你做所有事情。但我承認,彩虹parens *看起來很酷,所以如果你只是爲了看起來,我不能真正爭辯。 – amalloy 2012-04-10 22:03:06

+0

@amalloy:您可以同時使用* paredit *和* rainbow-parens *嗎? – TacticalCoder 2012-04-11 14:35:44

15

使用Emacs的paredit模式(在其他一些編輯過仿真)意味着你一般是 - 除非你是複製/粘貼鼠標/強制非結構化的選擇 - 應對匹配括號/括號/括號和相關與縮進不需要計數。

帶有https://github.com/technomancy/emacs-starter-kit的Emacs(強烈推薦!)默認啓用了clojure的paredit。否則,請參見http://emacswiki.org/emacs/ParEdit

+0

用於paredit +1。沒有它我活不下去! – Gert 2012-04-10 21:40:05

+1

當我第一次開始使用emacs時,我討厭了信任。但是一旦我明白它爲我做了什麼,(http://www.emacswiki.org/emacs/PareitCheatsheet)我不能沒有它。 – 2012-04-11 18:35:57

+0

我選擇了另一個答案,因爲我是vim用戶,但是對於paredit – 2012-04-12 12:51:44

13

除了支持大括號匹配的編輯器之外,您還可以嘗試使代碼嵌套更少。我相信,你的函數可以被改寫爲:

(defn rep [coll n] (mapcat (partial repeat n) coll)) 

當然,這是一門藝術(工藝)而不是科學的,但一些指針(排名不分先後):上4clojure

  • 問題和通過頂部的用戶他們的解決方案(解決特殊問題後可見) - 我相信克里斯·豪澤是有CH的手柄chouser
  • 說起下 - 「的Clojure的喜悅」是一個非常有用的閱讀Clojure的
  • 瀏覽文檔。 C礦石 - 有很多有用的功能有
  • ->->>穿線宏壓扁嵌套代碼
  • 計算器非常有用 - 一些最聰明和最有幫助的人在世界上答題有;-)
+0

感謝您的提示!在可能的情況下,我一直在解決每個4輪問題,至少有一次是遞歸的,至少有一次是沒有的。這只是一個有很多括號的例子。您的提示以上無疑將是非常有用的,雖然 – 2012-04-11 12:42:09

3
(fn rep 
    ([lst n] 
    (rep lst n nil)) 
    ([lst n acc] 
    (if-let [s (seq lst)] 
     (recur (rest s) n (concat acc (repeat n (first s)))) 
     acc))) 

這更可讀,我想。注意:

  • 你應該使用復發時尾遞歸
  • 你應該seq測試 - 見http://clojure.org/lazy
  • 重複,可以採取數
  • CONCAT將下降爲零,從而節省了重複自己
  • 你不需要爲每個打開的文件開始新行

至於parens - 你的edito r/ide應該照顧這一點。我在這裏打字盲,所以請原諒我,如果它是錯誤的...

[RafałDowgird's code is short;我正在學習過...]

[更新:]之後重新閱讀「懶」的鏈接,我想我已經被錯誤處理懶序列,

+0

感謝您的提示,我會在將來考慮到他們。 – 2012-04-11 12:38:35

3

我不能呼應足夠強烈它是多麼的有價值使用paredit或其他編輯器中的某些類似功能。它可以讓你擺脫對關於parens的關懷 - 他們總是完美地匹配自己,而像「將(foo (bar x) y)轉換成(foo (bar x y))」這樣單調乏味,容易出錯的編輯任務變成了一次單擊操作。一個星期左右,paredit會讓你無法相信,因爲它會阻止你手動完成任務,但是一旦你學會了自動處理parens的方法,你將永遠無法回頭。

我最近聽到有人說,我認爲這大致準確,沒有paredit編寫lisp就像編寫沒有自動完成(可能,但不是很愉快)的java。

1

請始終使用由至少75%消費後材料製成的100%再循環圓括號;那麼你不必對使用這麼多東西感覺不好。

1

不管你喜歡什麼格式。編輯的工作是以讀者喜歡的任何風格顯示代碼。我喜歡C風格的分層樹形格式,它們各自有一個單獨的支架(所有LISPers在這方面都非常激動):))))))))))))

但是,使用這種樣式:

(fn rep 
    ([lst n] 
    (rep (rest lst) 
    n 
    (take n 
     (repeat (first lst))) ) ) ) 

這是在括號間隔傳統風格的更新(LOG 2科級)

我喜歡空間的原因是,我的視力很差,我根本看不懂密集的文本。所以對於即將告訴我按照傳統方式做事情的憤怒的LISPers,每個人都有自己的方式,放鬆一下,沒關係。

不能等人有人在Clojure寫一個像樣的編輯器,但這不是一個文本編輯器,而是一個表達式 **,那麼格式化的問題就會消失。我自己寫一篇,但需要時間。我們的想法是通過將函數應用於表達式來編輯表達式,然後使用拉鍊逐個表達式來導航代碼,而不是通過單詞或字符或行。代碼由您想要的任何顯示功能表示。

**是的,我知道有emacs/paredit,但我嘗試了emacs,並不喜歡它。

+1

只要你不與任何人分享你的代碼,沒關係。但通常我們在代碼上進行協作,然後像這樣深奧的格式化就成了一個大問題。 – 2012-04-11 10:35:38

+0

是的,但這就是我的觀點 - 如果格式化是通過算法完成的,那麼它就不是問題。代碼是一種結構,格式是另一種結構,每個人都有自己的看待事物的方式,這是一件好事。對另一個人來說,看起來合乎邏輯的東西看起來很醜。我們對宗教進行格式化的唯一原因是因爲我們使用老式的文本編輯器來查看代碼,實際上我們應該用適當的工具來可視化代碼。 – Hendekagon 2012-04-12 00:01:46

+0

我的論文是關於這個問題的,所以我有足夠的時間去認識所有錯誤的原因。我認爲文本文件是一個atavism的東西,但我不再那麼想。 – 2012-04-12 04:58:22