Cuneiform语言

Cuneiform是用于大规模科学数据分析的开源。
它是促进并行计算的静态类型的纯函数式编程语言。它的特征是有个全功能的，允许用户集成来自很多外部编程语言的软件。Cuneiform在组织层面上提供了一些设施，如条件分支和通用递归，使其具有图灵完备性。
概述.
Cuneiform尝试拉近在科学工作流程系统如、或Galaxy，与大规模数据分析程序模型如MapReduce或Pig Latin之间的间隙，同时提供函数式编程语言的通用性。
Cuneiform是用分布式Erlang实现的。如果运行在分布式模态下，它导出一个遵循POSIX的分布式文件系统，如Gluster或（用FUSE集成某个其他文件系统例如HDFS）。作为替代选择，Cuneiform脚本可以执行在或Apache Hadoop顶上。
Cuneiform受到了Peter Kelly的工作的影响，他提议函数式编程作为科学工作流程执行的模型。
故而，Cuneiform不同于其他的基于数据流程编程的工作流程语言，如并行脚本语言。
扩展软件集成.
外部工具和库（比如R或Python库）是通过来集成的。通过它可以组合，比如允许通过snippet节点使用外部软件的，或为集成Java软件提供服务的。通过定义采用外界语言的任务，就可能使用一个外部工具或库的API。这种方式下，工具可以直接集成而不需要写包装器或重新实现工具。
目前支持的外界编程语言有：
计划增加外界语言AWK和gnuplot。
类型系统.
Cuneiform提供简单的、静态检查的类型系统。虽然Cuneiform提供列表作为复合数据类型，它省略了传统的列表访问子（codice_1和codice_2），以避免在访问空列表时，可能引起的运行时间错误的可能性。转而列表只能通过在其上codice_3或codice_4，以全有或全无方式访问。此外，Cuneiform（在组织层面）省略了算术，这排除了除以零的可能性。省略任何的部份定义运算，允许保证运行时间错误只能在外界代码中引发。
基础数据类型.
Cuneiform提供的基础数据类型有布尔值、字符串和文件。这里的文件被用来以任意格式在外界函数之间交换数据。
记录和模式匹配.
Cuneiform提供记录（结构）作为复合数据类型。下面的例子展示定义一个变量codice_5，作为有两个字段codice_6和codice_7的记录，第一个是字符串，而第二个是布尔值：
let r : &lt;a1 : Str, a2 : Bool&gt; =
 &lt;a1 = "my string", a2 = true&gt;;
记录可以要么通过投影（projection）要么通过模式匹配来访问。下面的例子从记录codice_5，提取两个字段codice_6和codice_7：
let a1 : Str = ( r|a1 );
let &lt;a2 = a2 : Bool&gt; = r;
列表和列表处理.
进一步的，Cuneiform提供列表作为复合数据类型。下面的例子展示定义一个变量codice_11，作为一个有三个元素的一个文件：
let xs : [File] =
 ['a.txt', 'b.txt', 'c.txt' : File];
列表可以通过codice_12和codice_4算子来处理。这里的codice_12算子可以接受多个列表，来逐个元素的处置列表（类似于Racket中的codice_15、Common Lisp中的codice_16或Erlang中的codice_17）。
下面的例子展示如何在一个单一的列表上codice_3，结果是一个文件列表：
for x &lt;- xs do
 process-one( arg1 = x )
 : File
end;
下面的例子展示如何codice_19两个列表，结果也是一个文件列表：
for x &lt;- xs, y &lt;- ys do
 process-two( arg1 = x, arg2 = y )
 : File
end;
最后，列表可以使用codice_4算子来做聚集。下面的例子合计一个列表的元素：
 fold acc = 0, x &lt;- xs do
 add( a = acc, b = x )
 end;
并行执行.
Cuneiform是纯函数式语言，就是说它不支持可变引用。作为结论，它可以使用独立子项，将一个程序分解成可并行的各部份。Cuneiform调度器分布这些部份到做工节点。此外，Cuneiform采用传名调用求值策略，值只在它对计算结果有贡献时计算。最后，外界函数应用是记忆化的，用来加速包含以前推导结果的计算。
例如，下列Cuneiform程序允许codice_21和codice_22的应用平行的运行，而codice_23是有依赖的，它只在codice_21和codice_22二者完成的时候可以开始：
下列Cuneiform程序通过将函数codice_21映射到一个三元素列表，创建了三个并行应用：
类似的，在记录codice_5的构造中，codice_21和codice_22的应用是独立的，因此可以并行运行：
例子.
下面是一个hello-world脚本：
def greet( person : Str ) -&gt; &lt;out : Str&gt;
in Bash *{
 out="Hello $person"
( greet( person = "world" )|out );
这个脚本定义了采用Bash的一个任务codice_30，它对其字符串实际参数codice_31预加上codice_32。这个函数产生具有一个单一字符串字段的记录codice_33。应用codice_30，绑定实际参数codice_31到字符串codice_36，产生记录codice_37。将这个记录投影为它的字段codice_33，求值出字符串codice_39。
可以通过定义采用Bash的一个任务来集成命令行工具：
def samtoolsSort( bam : File ) -&gt; &lt;sorted : File&gt;
in Bash *{
 sorted=sorted.bam
 samtools sort -m 2G $bam -o $sorted
在这个例子中定义了任务codice_40。它调用了工具，处置一个BAM格式的输入文件，并产生一个排序了也是BAM格式的输出文件。
发行历史.
在2016年4月，Cuneiform的实现语言从Java切换成了Erlang，并且在2018年2月，它的主要发布执行平台从Apache Hadoop变更为分布式Erlang。此外，从2015年到2018年，曾被作为可替代执行平台来维护。
Cuneiform的外表语法修订过两次，这反映在主版本号上。
版本1.
在2014年5月发布的最初草案中，Cuneiform密切关联于Make，它构造解释器在执行期间要遍历的静态数据依赖图。与后来版本的主要区别，是缺乏条件、递归或静态类型检查。区分文件和字符串，是通过同波浪号codice_41形成一个单一引用的字符串。脚本的查询表达式，通过codice_42关键字来介入。Bash是缺省外界语言。函数应用必须使用codice_43形式来完成，它接受codice_44作为第一个关键字实际参数。一年之后，这种外表语法被一种精简却类似的版本所替代。
下面的例子脚本从一个FTP服务器下载一个参考genome：
版本2.
Cuneiform外表语法的第二个草案，首次发表于2015年3月，在Cuneiform的实现语言从Java到Erlang的迁移期间，持续使用了三年。求值不同于早期方式，解释器归约一个表达式，而非遍历一个静态图。在外表语法保持使用这段时期，解释器被形式化和简化，这导致了第一个Cuneiform的语义规定。语法特征是有了条件。但是，布尔值被编码为列表，再度利用空列表为布尔值codice_45，非空列表为布尔值codice_46。递归后来作为形式化的副产品而增加。但是，静态类型检查，只在后来的版本3中介入。
下列脚本解压一个压缩文件，并把它分解为大小均匀的划分：
版本3.
Cuneiform外表语法的当前版本，比较于早期的草案，是尝试拉近与主流函数式编程语言的间隙。它的特征是简单的静态检查的类型系统，并在列表之外介入记录作为第二个复合数据结构类型。布尔值独立为基础数据类型。
下列脚本解包一个文件，结果为一个文件列表：