📁Clojure Expression Problem

📁Clojure Expression Problem


主にデータと操作の抽象を扱う.

Clojureでは,

  • データ抽象として
    • deftype
    • defrecord
  • 操作の抽象として
    • defprotocol
    • multimethod

という仕組みが用意されている.

Clojureにおける大きなテーマのひとつなので必要に応じてサブメモにわける.

cf. Javaではデータ抽象としてクラス, 操作の抽象としてインタフェースがある.

if/when/cond/case #

条件分岐の複雑さを解くための抽象が必要かどうかをまず見極める. 必要がなければif/cond/caseあたりのより簡単なシンタックスで済ます.

ref. Clojure Flow Basic Syntax(if/when/cond/case)

条件分岐としては基本的な文法で十分であることをここで強調したい.

分岐もたいした複雑さがないならばポリモーフィズムは導入するべきでない. 個人開発でさくっとプロトタイプをつくるときなどこりすぎても多様さが不必要なことがおおい. 🏷YAGNI

cf. if文やswitch文のおばけをウンコードという.

defun: パターンマッチマクロ #

multimethod よりもより気軽に書けるかもしれない.

see. defun: Clojureでのパターンマッチマクロ

💡Clojure multimehod vs protocols 比較 #

どちらもExpression Problemのための操作抽象であり, 同じことが実現できるところがややこしいところなのでココで整理しておく.

基本方針としてはたいていはprotocolsでいい, multimethodはより表現力があるもののコストがかかるので必要なときに限りmultimethodを選ぶ.

ref. Clojure multimethods vs. protocols - Stack Overflow-

protocolsははじめの引数の型によるdispatch, multimethodはそれより汎用的な複数の引数や型に応じたdispatch.

Protocols provide efficient polymorphic dispatch based on the type of the first argument. Because the is able to exploit some very efficient JVM features, protocols give you the best performance.

Multimethods enable very flexible polymorphism which can dispatch based on any function of the method’s arguments. Multimethods are slower but very flexible.

In general, my advice is to use protocols unless you have a specific case that requires multimethods.

protocolsでたいていは十分でありmultidispatchは複数条件による分岐が必要なとき.

use protocols when they are sufficient but if you need to dispatch based on the phase of the moon as seen from mars then multimethods are your best choice.

multimehodは遅いのか? #

muitlmethodはおそいのか?だからcondやprotocolがいい?

まあcondやprotocolsと比べると遅い事実はあるものの気にするレベルかはその時のの状況による. たいていはperformanceよりも解決するべき問題を大事にするべきだ, と Alex Miller はいっている.

ref. Performance of multimethod vs cond in Clojure - Stack Overflow

速度が必要ならそもそもそこだけJavaでリフレクションを避けつつ最適化を考慮して書くとかもできる.

Clojure: Data Types #

Clojure データ型. Java クラスの代替.

protocolで規定された抽象化の実装を作るのに使う.

ref: Clojure - Datatypes: deftype, defrecord and reify

話題がおおきいのでレコードはこっちへ.

📝Clojure: レコード | Records

Active Recalls #

ClojureのプロトコルはJavaにおけるなんの代替ですか? #

Java インタフェース

Clojureのプロトコルを宣言するためのシンタックスはなんですか? #

defprotocol

ClojureのRecordで定義したレコードのコンストラクタと属性へのgetterのSyntaxSuggerは? #

コンストラクタが ->, 属性は(:keyword x)

(def foo (->Foo a b))
(:hello foo)

Clojureのマルチメソッドとはなんですか?また宣言で用いる2つのシンタックスはなんですか?

:ANKI_NOTE_ID: 1642413642883

メソッドに与えられた引数の型によってその処理内容を変化させる方法. defmulti, defmethod.

Clojureのマルチメソッドとプロトコルの違いはなんですか? #

マルチメソッドは,単一のメソッドに対する複数の挙動を実装する. プロトコルは,グループ化されたメソッドに対する挙動を実装する.

Clojureのマルチメソッドやプロトコルを利用しないことによる複雑さを一般的になんといいますか? #

Expression Problem.

if文のような条件分岐を多用することでコードが複雑になる. 抽象度をあげた記述ができることが利点のLispの特性が活かせない.