explicit definition に使う define
という単語は実はキーワードではなく、標準ライブラリで定義されています。この記事では、どういった仕組みになっているのかを確認します。
define の定義
REPL に define
を入力してみましょう。
define
:0
見慣れない記号が出てきました。0
は普通に数値の 0 ですが、その前に :
があります。
:
は conjunction で、:0
は部分適用によって作られた adverb です。つまり、monad define
は define
という adverb に被演算子 monad
を渡していることになります。
となると、今度は monad
の定義が気になりますね。
monad
3
dyad
4
verb , adverb , conjunction , noun
3 1 2 0
なんと、全て整数になっています。(ちなみに monad
と verb
は同じ値です。) そのため、monad define
の代わりに 3 : 0
と書くこともできます。
conjunction :
:
には、いくつかの異なる使い方があります。
m : 0
explicit definition を開始します。conjunction なので、式の一部として使えます。
NB. noun define は 0 : 0
<noun define
***
)
┌────┐
│*** │
└────┘
NB. monad define は 3 : 0
monad define i.5
2 * y
)
0 2 4 6 8
m : n
explicit definition の定義が短いとき、m : n
(n
は文字列) を使うと一行で書くことができます。この用途のために、def
という名前が定義されています。
def
:
NB. 括弧 ( ) は無くても同じ
'left' (dyad def 'x ; y') 'right'
┌────┬─────┐
│left│right│
└────┴─────┘
NB. ' のエスケープに注意
(monad def 'y $ ''text''') 2 2
te
xt
m : n
は explicit definition (m : 0
) の内部でも使えます。
u : v
u : v
は、上の 2 種類とは全く違う意味で、dual-valence 1 の verb を作る機能です。monad として使われたときは u
が実行され、dyad の場合は v
が実行されます。
sum=: +/ : ([: +/ ,)
NB. +/
sum 2 5 4 7
18
NB. [: +/ ,
1 10 sum 2 5 4 7
29
explicit definition と組み合わせることもできます。これによって省略可能な引数を実現できます。
increment=: 1&$: : (dyad def 'x + y') NB. この括弧は必須 (modifier は左から右)
increment 2
3
2 increment 3
5
$:
は、verb を作る train の中で使うとその train 自身を返す verb です。tacit definition で再帰呼び出しをするのにも使われます 2。
ここでは $:
は train 1&$: : (dyad def 'x + y')
を指し、1&
で $:
に左の引数 (デフォルト引数) を与えているので最終的には dyad 側が実行されます。
u : v
のどちらかの被演算子を [:
にすると、monad もしくは dyad の一方の使い方のみに限定することができます。[:
の、実行されると必ずエラーが発生するという性質を利用しています。
NB. dyad として使ってほしい
multiply=: [: : *
2 multiply 3
6
NB. [: が実行されるのでエラー
multiply 2
|domain error: multiply
| multiply 2
[ 前 : 複数行のリテラル ] [ 目次 ] [ 次 : direct definition ]