Lucid语言

Lucid是数据流程编程语言，设计用来实验非冯·诺伊曼编程模型。它是William W. Wadge和Edward A. Ashcroft在1976年设计的，并描述于1985年的书籍《Lucid, the Dataflow Programming Language》。
pLucid是Lucid的首个解释器。
模型.
Lucid使用针对数据计算的需求驱动模型。每个语句都可以理解为一个方程，它定义了一个网络，即处理器和它们之间的数据经此流动的通信线路。每个变量都是值的一个无限流（stream），而每个函数都是一个过滤器或变换器。Lucid最大的创新之处，是能够进行流合成（composition）的迭代，这是通过“当前”值和算子codice_1（读作followed by）来模拟表述的。
Lucid基于了一种“历史”（history）的代数，“历史”是数据项的无限序列。在操作上，“历史”可以被认为是一个变量的变更着的值的记录，对“历史”的运算操作比如codice_2和codice_3可以随其名字所提示的那样理解。Lucid最初被构想为一个规矩的、数学上纯粹的单赋值语言，如此其验证将会被简化。但是，数据流程释义在Lucid的演变方向上有着重要的影响。
细节.
Lucid从ISWIM继承了codice_4子句作为自己的块结构，从POP-2继承了数据类型。在Lucid中，每个表达式中的变量，都要先在表达式自身的codice_4子句中寻找对应的变量定义，包含仍未约束的变量的表达式，在继续进行（proceed）之前，要等待直到这个变量已经被约束，即等待从输入中获取变量的值。一个表达式如codice_6，在返回这个表达式的输出之前，将等待直到codice_7和codice_8二者都成为约束的。这样有一个重要结果，避免了更新有关值的显式的逻辑，导致了相较于主流语言的先声明再引用方式有大量的代码简约。
在Lucid中每个变量都是值的流（stream）。算子codice_1（followed by的助忆码），定义了在前一个表达式之后会出现什么。表达式codice_10使用codice_1定义了一个流codice_12，在这个实例中，这个流产生序列[1,2,3...]。在流中的值，可以通过如下这些算子来寻址取用，假定codice_7是用到的变量：
计算是通过定义作用在数据的时变流上的过滤器或变换函数来完成的。涉及多个流的函数和运算操作采用逐点（pointwise）释义比如：codice_60，在后面例子中进行二个流的归并和串接时，因而在条件表达式codice_61中需要通过codice_62对要操作的流进行预处理。
数据结束（end of data）对象用预定义特殊标识符codice_63表示，codice_64将返回codice_22，此外所有的对codice_63的运算操作都产生codice_63。错误对象用预定义特殊标识符codice_68表示。codice_69是预定义变量，它是以codice_70开始的自然数序列。此外预定义变量还有codice_71、codice_72等。
例子.
序列的总和.
total
where
 total = 0 fby total + x
end
累积移动平均.
running_avg
where 
 su​m = first(inp​ut) fby su​m + next(inp​ut);
 n = 1 fby n + 1;
 running_avg = su​m / n;
end
阶乘.
fac
where
 n = 0 fby (n + 1);
 fac = 1 fby (fac * (n + 1));
end
斐波那契数列.
fib
where
 fib = 0 fby (1 fby fib + next fib);
end
指数函数.
指数函数的幂级数formula_1的前10项：
expsum asa next i eq 10
where
 X is current x;
 i = next ind​ex;
 term = 1 fby (term / i) * X;
 expsum = 0 fby expsum + term;
end
均方根.
在下面均方根程序中的平方根计算使用了。
sqroot(a​vg(square(a)))
where
 square(x) = x*x;
 a​vg(y) = mean
 where
 n = 1 fby n+1;
 mean = first y fby mean + d;
 d = (next y - mean)/(n+1);
 end;
 sqroot(z) = approx asa err &lt; 0.0001
 where
 Z is current z;
 approx = Z/2 fby (approx + Z/approx)/2;
 err = abs(square(approx)-Z);
 end;
end
素数.
prime
where
 prime = 2 fby (n whenever isprime(n));
 n = 3 fby n+2;
 isprime(n) = not(divs) asa divs or prime*prime &gt; N
 where
 N is current n;
 divs = N mod prime eq 0;
 end;
end
汉明数.
计算升序的正规数的算法经由戴克斯特拉得以流行，有关问题叫做“汉明问题”。Dijkstra计算这些数的想法如下：
hamming
where
 h = 1 fby merge(merge(2 * h, 3 * h), 5 * h);
 merge(x,y) = if xx &lt;= yy then xx else yy fi
 where
 xx = x upon xx &lt;= yy;
 yy = y upon yy &lt;= xx;
 end;
end
注意这个程序中归并函数中的codice_62条件能够起到二个流中可能存在的相同值在结果中只出现一个的效果。
快速排序.
下面程序实现了霍尔的快速排序算法，将序列划分为小于基准值（pivot）的元素和不小于它的元素的两个子序列，然后递归的排序这两个子序列，再将结果的两个排好序的子序列串接起来。
qsort(a) = if iseod(first a) then a else follow(qsort(b0), qsort(b1)) fi
where
 p = a &lt; first a;
 b0 = a whenever p;
 b1 = a whenever not p;
 follow(x,y) = if xdone then y upon xdone else x fi
 where
 xdone = iseod x
 end
end
数据流程图.
 +--------&gt; whenever -----&gt; qsort ---------+
 | | |
 | not |
 |---&gt; first | |
 | V | |
 |---&gt; less ---+ |
 | V V
 ---+--------&gt; whenever -----&gt; qsort -----&gt; follow -----&gt; if-then-else -----&gt;
 | | |
 +--------&gt; next ----&gt; first ------&gt; iseod --------------+ |
 +------------------------------------------------------------+