Nimのprocとmethodとfunc
from Nim
proc
docs
Static Dispatchになる
だから、overloadができる
monkey-nimのnewError関数でも使っている
method
docs
Dynamic Dispatchで関数を定義したい場合はmethodを使う
多重ディスパッチもできる
overrideする関数には{.base.}Pragmaを付ける
overrideされる側である親クラスのメソッドにのみに書くのかな
他の言語のようにmethodがclassにbindされているのはデメリットがある
開発者の管理下に無いクラスにメソッドを追加したいときに不可能もしくは、複雑になる
メソッドがどのクラスに属しているのか不明確になる
overrideに書いたコードをNimに書き直したもの
code:nim
type
Parent = ref object of RootObj
Child = ref object of Parent
method hoge(e: Parent) {.base.} = echo "Parent" # ①
method hoge(e: Child) = echo "Child" # ②
# 型はParent, 実体もParent
var p: Parent = Parent()
p.hoge() # -> Parent
# 型はParent, 実体はChild
var c: Parent = Child()
c.hoge() # -> Child
このコードのmethodの部分をprocに書き直すと(もちろんpragmaも消して)、②のhogeはunusedになり、結果は両方とも「Parent」と出力される
変数cはParent型なので、②が使われていない
overrideではなく、overloadが起こっている
pとcを定義時に型を指定しなければ、上のコードのときと同じ結果になる
Nimにはvtableは使われていない代わりに、dispatch treeが生成される
Performance note: Nim does not produce a virtual method table, but generates dispatch trees. This avoids the expensive indirect branch for method calls and enables inlining. However, other optimizations like compile time evaluation or dead code elimination do not work with methods. ref
func
docs
副作用のないprocもしくは、iteratorを定義する
methodは?副作用のないmethodってある #??
副作用があるとコンパイルエラーになる
ただし、引数がポインタ(var, ptr)や参照型(ref)の場合は、副作用があってもエラーにならない
noSideEffectPragmaを使って定義したprocの糖衣構文
v0.19.0から入った
参考
Nimのややマイナーな言語仕様(funcとnot nil) - Qiita
Nim forum