そのような機能はありません。自由に実装して、好きなように使用してください。
(defn args [& args] args)
(set (map type (apply map args [[1 2 3][4 5 6][7 8 9]])))
=> #{clojure.lang.ArraySeq}
なぜまだ利用できないのですか?
これはめったに実りのない質問です: 実装者の心の中で何が起こっているのかを知らないだけでなく、彼らが何かをしなかった理由を正当化または文書化するよう依頼することは実際的ではありません. この機能を追加することは考えられていましたか? どうすれば知ることができますか?本当に理由があるのですか、それとも単に起こったのですか?
一方、args
既存の不変シーケンスを通過するため、よりシンプルに感じることに同意します。倹約のためだけなら、そもそも引数を永続的なリストとして変換しないほうがよいと思われる場合も理解できます。
しかし、これは実装方法ではなく、使用のオーバーヘッドlist
は本当に無視できます (また、 のインスタンスから構築する場合に特殊ArraySeq
化されます)。インターフェイスにコーディングし、カーテンの後ろを決して見ないようにする必要があり、この観点からは、同じ結果が返されなくてもlist
同等args
です。
怠惰についてのコメントを追加しましたが、そのとおりです。可変引数関数から引数を取得し、シーケンスで動作する関数に渡す必要がある場合、 のバージョンlist
は指定されたすべての引数を消費しますが、消費しargs
ません。場合によっては、(apply list (range))
文字通り無限の数の引数を渡す のように、永久にハングアップする可能性があります。
その観点から、この小さなargs
関数は興味深いものです。潜在的な問題を引き起こすことなく、引数から実際のシーケンスに移行できます。ただし、このケースが実際にどのくらいの頻度で発生するかはわかりません。実際、引数リストの遅延が問題となるユースケースを見つけるのに苦労していargs
ます。結局のところ、無限のシーケンスを渡すには、apply を使用する (?) しか方法がありません。
(apply f (infinite))
のユースケースを持つためにはargs
、引数リストから単一のリストに変換して、別の関数gが次のようにシーケンスとして使用できるようにする必要があることを意味します。
(g (apply args (infinite)))
しかし、その場合、直接呼び出すことができます:
(g (infinite))
あなたの例では、 insideg
を表しますが、入力で指定されているため、直接書き込むことはできません。したがって、この例は の真の使用例のように見えますが、指定したスニペットが非常に複雑であるため、関数を詳しく文書化する必要があります。私は、関数に無制限の数の引数を与えることはコードのにおいだと考える傾向があります:与えられたシーケンスが実際には無限である可能性があるため、シグネチャを持つすべての関数はすべての引数を消費することを避けるべきでしょうか? 意図を明確にするために、引数リスト全体ではなく、単一の引数をこの種の使用法 (および必要に応じて渡す) の遅延シーケンスにすることをお勧めします。しかし、結局のところ、私はどちらの使用にも強く反対しているわけではありません。cons
lazy-map
f
(cons (map ...) ...)
args
[& args]
lazy-map
identity
args
結論として、Rich Hickey にコア関数として追加するよう説得できない限り、args
これだけを行う外部ライブラリに依存したいと思う人はほとんどいないと確信しています1。 . 唯一の報酬は、ほとんどの場合費用がかからない小さな変換ステップをスキップできることを知ることです. 同様に、ベクターとリストのどちらを選択する必要があるかについて心配する必要はありません。実際にはコードに影響を与えず、必要であることが証明できれば後でコードを変更できます。怠惰に関しては、リストまたはベクトルで引数をラップすると、無制限の引数リストで問題が発生する可能性があることに同意しますが、実際に問題が実際に発生するかどうかはわかりません。
1 . もちろん、それが に到達した場合clojure.core
、誰もがすぐにそれが最も有用で間違いなく慣用的な基本的な操作であると言うでしょう</cynic>