web-dev-qa-db-ja.com

Clojureの隠された機能

Clojureのあまり知られていないが便利な機能のうち、使用しているものはどれですか?ちょっとしたトリックやイディオムを自由に共有してください。ただし、CoreとContribに限定してください。

私はこれらの同様の質問への回答でいくつかの本当に興味深い情報を見つけました:

他の言語の「隠し機能」の質問は他にもたくさんあるので、Clojureにも質問があるといいと思いました。

27
danlei

Clojureには不変の永続キューデータ型PersistentQueueがありますが、リテラルリーダー構文またはClojureラッパー関数が(まだ?)ないため、Javacall。Queuesを介して作成する必要があります。 conj(Push)を後部に押し込み、前部からポップしてパフォーマンスを向上させます。

user> (-> (clojure.lang.PersistentQueue/EMPTY)
          (conj 1 2 3)
          pop)
(2 3)

接続詞を前面にリストし、前面からポップします。ベクトルは後部に接続し、後部からポップします。そのため、キューがまさに必要な場合があります。

user> (-> ()
          (conj 1 2 3)
          pop)
(2 1)
user> (-> []
          (conj 1 2 3)
          pop)
[1 2]
23
Brian Carper
(defn foo [a & [b c]] ...)

残りの引数を分解できます。

更新:

Gitリポジトリへの最新のコミット(29389970bcd41998359681d9a4a20ee391a1e07c)により、次のような連想破壊を実行できるようになりました。

(defn foo [a & {b :b c :c}] ...)

これの明らかな使用法は、キーワード引数です。このアプローチは、キーワード引数と残りの引数の混合を防ぐことに注意してください(これは非常に頻繁に必要になる可能性が高いものではありません)。

(defn foo [a & {:keys [b c] :or {b "val1" c "val2"}] ...)

キーワード引数のデフォルト値が必要な場合。

13
dnolen

読み取り評価リーダーマクロ:#=

(read-string "#=(println \"hello\")")

このマクロは、ユーザー入力にreadが使用されている場合、セキュリティリスクをもたらす可能性があります(これ自体はおそらく悪い考えです)。 *read-eval*falseに設定すると、このマクロをオフにできます。

11
Arthur Ulfeldt

関数を無限の引数シーケンスにapplyすることができます。例えば

(apply concat (repeat '(1 2 3)))

1,2,3,1,2,3 ...のレイジーシーケンスを生成します。もちろん、これが機能するためには、関数も引数リストに関してレイジーである必要があります。

8
Rafał Dowgird

ますます優れたClojureDocsサイトから、juxthttp://clojuredocs.org/clojure_core/clojure.core/juxt を使用したイディオム


;juxt is useful for forking result data to multiple termination functions
(->> "some text to print and save to a file"
  ((juxt
     println
     (partial  spit "useful information.txt"))))
6
Alex Stoddard