AdaでYield
そういえば大分昔に書こうと思っていて、完全に忘れてたのをふと思い出したので書いてみましょう。
PiroさんのJavaScript 1.7のyield文ってなんじゃらほに書かれているフィボナッチ数列を求める例がわかりやすいので、これをAdaで書いてみます。
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Yield is
task type Test is
entry Next (Value: out Integer);
end Test;
task body Test is
A : Integer := 0;
B : Integer := 1;
Temp : Integer;
begin
loop
select
accept Next (Value : out Integer) do
Value := A;
Temp := B;
B := A + B;
A := Temp;
end Next;
or
terminate;
end select;
end loop;
end Test;
Generator : Test;
Value : Integer;
begin
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
Generator.Next(Value); Put (Value); New_Line;
end Yield;
AdaのTaskは本当に強力すぎて、正直TaskだけでもAdaを使う価値有りすぎです。or terminate
とか素敵すぎます。
あとはYieldとはあんまり関係ないですが、then abort
とかもやばいです。10msでフィボナッチ数列を出来るだけ計算してみる、なんて処理がこんなに簡単に書けちゃいます。
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Yield is
task type Test is
entry Next (Value: out Integer);
end Test;
task body Test is
A : Integer := 0;
B : Integer := 1;
Temp : Integer;
begin
loop
select
accept Next (Value : out Integer) do
Value := A;
Temp := B;
B := A + B;
A := Temp;
end Next;
or
terminate;
end select;
end loop;
end Test;
Generator : Test;
Value : Integer;
begin
select
delay 0.01;
then abort
loop
Generator.Next(Value); Put (Value); New_Line;
end loop;
end select;
end Yield;
わぁ、かっこいい。