参照
参照は値の再利用を可能にします。繰り返し構造を生み出すこともできます。
複数行のプログラム
インタプリタで複数行の入力を行う際は、 :{
と :}
をあらかじめ入力します。Haskell のインタプリタと同様です。
> :{
> 1 -> output
> 2 -> output
> :}
2
1
2
1.
ファイルからのプログラム読み込み
複数行の入力を毎回インタプリタから行うのは大変です。flow のインタプリタでは、プログラムを書いたファイルを読み込むことができます。flow のファイルの拡張子は .~
が推奨されています。
1 -> output
2 -> output
:l
コマンドを用いてファイルの読み込みができます。この機能はブラウザからは使えないので、ローカルのランタイムで実行してください。
> :l test.~
1
2
1
2.
参照の基本
参照は「トンネル」のような役割を果たすノードです。 @a
などとして表現します。
> :{
> 1 -> @a
> @a -> output
> :}
1.
参照は複数の下流にデータを流すことができます。その場合、参照は copy
のような役割を果たし、上流からのデータをすべての下流に流します。
> :{
> 1 -> @a
> @a + @a -> output
> :}
2.
参照は複数の上流からは受け取れない
参照は複数の下流を持つことができる一方で、複数の上流は持つことができません。どこからでも参照にデータを流すことを許すと、コードが読みにくくなり、バグの温床になってしまうからです。
参考: 参照は Verilog でいう wire
に似ていますが、Verilog のコードを回路に合成する際にも wire
が複数回 assign
されていると multi-driven
だといわれることがあります。これは電気的な制約によるものですが、制限されていることは同じです。
> :{
> 1 -> @a
> 2 -> @a
> :}
The ref a is multi-driven.
もし複数の入力を用いたければ、 merge
ノードを用いることをお勧めします。このノードは、複数の上流と 1 つの下流を持ち、上流から来たデータを下流に流します。
> :{
> (1 ->) (2 ->) merge -> @a
> @a -> output
> :}
1
2
1
2.
参照でループを作る
次のようなプログラムを実行すると、数字が加算されながら流れ続けます。
> @a'0 -> trace -> + 1 -> @a
0
1
2
3
4
5
6.
いくつか新しい構文が出てきたので、説明します。
@a
の後についている '0
は、最初に下流に流すデータを指定しています。これがないと、このプログラムには何も流れなくなってしまいます。
trace
は、 output
と似ていますが、出力をしつつ上流から来たデータを下流に流します。 trace
を使わずに、次のように書くこともできます。
> @a'0 -> copy (-> output) (-> + 1 -> @a)
実践: 階乗を計算する
繰り返しを用いることで、再帰的な関数を書くことができます!試しに階乗を計算してみましょう。
実装には、「2 つの上流を持つ if
」を利用します。これは、片方の上流(名前: condition
)が条件となり、もう片方の上流(名前: value
)が下流(then か else)に流すデータを定めます。then だけを見ると、条件と合わせてトランジスタのように働きます。
> (2 ->:value) (1 == 1 ->:condition) if (then:-> output) (else:-> * 2 -> output)
2.
次のプログラムは階乗( @x
で指定された数の階乗)を計算します。糖衣構文を多用していますが、糖衣構文については後の章で説明します。
> :{
> 5 -> @x
> @next'1 * @current'1 -> @result
> @result -> if (@current'1 == @x) (then:-> output) (else:-> @next)
> @current'1 + 1 -> @current
> :}
120.
糖衣構文を用いなければ次のものと等価です。
> :{
> 5 -> @x
> (@next'1 ->) (@current'1 ->) * -> @result
> ((@current'1 ->) (@x ->) == ->:condition) (@result ->:value) if (then:-> output) (else:-> @next)
> (@current'1 ->) (1 ->) + -> @current
> :}
120.