#Julia言語
色々よく分かっていないあいだは、内部コンストラクタを定義しない方が無難だという話。
添付画像は
github.com/genkuroki/publ…
より。これの1つ前のコードでは赤枠部分の外部コンストラクタしか定義されていなかった。青枠部分は後で追加された。
続く
#Julia言語
struct Foo{T}
a::T
b::T
Foo(a::T) where T = new{T}(a, T(2)a)
end
と内部コンストラクタFoo(a)を定義すると、これ以外にFoo型のオブジェクトを作る方法が失われ、フィールドbは常にaの2倍になることになります。
この仕様を変更するにはコードの変更が必要になる。
#Julia言語 一方、
struct Bar{T}
a::T
b::T
end
Bar(a::T) where T = Bar{T}(a, T(2)a)
と内部コンストラクタを定義せずに、外部コンストラクタBar(a)を定義しているなら、デフォルトで定義されているBar(a, b)を使ってbをaの2倍以外の値に設定できます。
#Julia言語 添付画像のコードは最初赤枠部分の外部コンストラクタしか定義されてなかった。
赤枠のコンストラクタでは、ポテンシャル函数のみを与えたときに、そのgradientを自動微分を使って構成するようになっています。続く
#Julia言語 もしも赤枠のコンストラクタが内部コンストラクタになっていたとすると、struct ~ end 内にコードを追加せずに、ポテンシャル函数のgradientを別の方法で構成して利用することが不可能になってしまいます。
これが、内部コンストラクタを定義した場合の典型的なリスクです。
#Julia言語 青枠部分のコンストラクタは module My の内側で定義されている必要はありません。module My のコードを変更せずに自前で追加可能。
この追加は、gradientをSymbolics.jlを使った数式処理で構成するために必要でした。
その御利益はさらなる高速化!
#Julia言語 内部コンストラクタを定義することは、「この型の使用法として許されるのは俺が決めた使い方だけだ!」という主張をユーザーに押し付けるために役に立ちます。
ユーザー側が数学的な試行錯誤を自由にできるようにするためには、内部コンストラクタの定義は避けたほうがよいです。
#Julia言語
「この型の使用法として許されるのは俺が決めた使い方だけだ!」としたい理由があったり、自己参照オブジェクトが欲しい場合には内部コンストラクタを使わざるを得ない。
一方、ユーザーに試行錯誤のし易さを提供したいなら、内部コンストラクタの定義は避けた方が良さそうです。
Share this Scrolly Tale with your friends.
A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.