2011-08-19 54 views
4

我正在嘗試類似於Python的func(*lst),但使用Clojure,並且不使用apply函數。我確實有點傻的使用情況是:Clojure - 將列表元素作爲函數參數

{:k1 v1 (cond exp '(:k2 v2) :else '(:k3 v3))} 

所以,如果EXP是真實的,在字典將包含{:k1 v1 :k2 v2},否則{:k1 v1 :k3 v3}。我基本上想要一個Python風格的*適用於返回值cond。我嘗試使用',`和〜來玩數據/代碼模式,但沒有找到解決方案。我可以重複cond的個人參數到底層的hash-map,但是這種做法已經失敗了。

爲什麼?我只是覺得如果Clojure能夠輕鬆做到這一點會很酷。 :)

回答

8

不可以。單個表單只能是單一表單:它不能神奇地成爲其中的兩個。如果這是可能的,各種事情都會破裂。

在你的具體的例子,簡單的答案是

(apply hash-map :k1 v1 
       (cond exp '(:k2 v2) 
         :else '(:k3 v3)) 

做到這一點的唯一方法是適用,它變成一個函數參數到零個或多個功能參數,由他們擴大爲一個列表。它不能在源代碼級別工作,以用於像哈希文字這樣的東西。

編輯:我不知道太多的Python,但我很確定Python不能這樣做。您可以將函數調用到函數調用中,但不能直接插入源代碼中。你可以不寫

test_expr = ((x == 2), return x) 
if *test_expr 

或類似的東西 - 它只是是不可能的,因爲編譯器必須分析if,纔可以明白與test_expr做。同樣在Clojure中,編譯器必須先分析哈希文字,然後才能理解如何處理內部對象 - 它不知道你「想」它們以某種方式擴展到地圖表達式中。

+0

謝謝,我想。儘管應用函數最終不是那麼難看,但我只是喜歡大括號的形式。一個小的修正是,如果v2和v3是變量,它需要是'\'(:k2〜v2)' – Kevin

+1

如果這就是你想要的,當然;我修正了你的實際代碼,而不是解釋我認爲你的意思。 '\'(:k2〜v2)'可以工作,但是'[:k2 v2]'更容易,如果這是你想要的。 – amalloy

相關問題