def 関数でのクロージャ [資産管理電卓(LineCalc)]
def や fnc 関数で定義した関数では外部の変数にアクセスすることができません。
外部の環境を関数定義内に取り込むことをクロージャと言います。
LCSではクロージャは無名関数では使用可能です。
場合により関数内で外部変数をアクセスできたほうが記述が簡潔になることがあります。
LCSのような電卓では数行の簡易なプログラムにより計算を行うことが多いので簡易な記載はなおさら有効です。
そのような場合には、
上記のように def に渡す関数の文字列を無名関数により作成するとクロージャを実現でき、関数 tes 内で外部変数 tmp にアクセスできます。
もしくは、
=(代入)を使って無名関数を変数に代入して関数を定義しても可能です。
上記のように入れ子になっていても外側の変数(tmp,foo)にはすべてアクセスすることができます。
上記のように再帰関数をコンテキストリソースを介さず作成可能です。
LCSでは変数定義が代入によりされ、明示されるわけではありません。
関数内で外部変数にアクスセスできるとテンポラリ変数などがかぶることが多くなり変数の使用が制限され変数使用時の負担が増加しバグの原因になる可能性があります。
その為 fnc や def ではクロージャの環境が無い状態をデフォルトにしています。
{ tmp = 123, fnc(tes,tmp), // tmp は未定義エラー tes }
外部の環境を関数定義内に取り込むことをクロージャと言います。
LCSではクロージャは無名関数では使用可能です。
{ tmp = 123, =>{tmp}() }
場合により関数内で外部変数をアクセスできたほうが記述が簡潔になることがあります。
LCSのような電卓では数行の簡易なプログラムにより計算を行うことが多いので簡易な記載はなおさら有効です。
そのような場合には、
{ tmp = 123, def(tes,=>{tmp}), tes }
上記のように def に渡す関数の文字列を無名関数により作成するとクロージャを実現でき、関数 tes 内で外部変数 tmp にアクセスできます。
もしくは、
{ tmp = 123, tes = =>{tmp}, tes }
=(代入)を使って無名関数を変数に代入して関数を定義しても可能です。
{ tmp = 123, def(tes, =>{ foo = 456, def(tes2, =>{ tmp+foo } ), tes2 } ), tes }
上記のように入れ子になっていても外側の変数(tmp,foo)にはすべてアクセスすることができます。
{ def(tes, =>{if(@1 > 1 , @1 * tes(@1 - 1), 1)}), tes(3) }
上記のように再帰関数をコンテキストリソースを介さず作成可能です。
LCSでは変数定義が代入によりされ、明示されるわけではありません。
関数内で外部変数にアクスセスできるとテンポラリ変数などがかぶることが多くなり変数の使用が制限され変数使用時の負担が増加しバグの原因になる可能性があります。
その為 fnc や def ではクロージャの環境が無い状態をデフォルトにしています。
コメント 0