热门问题
时间线
聊天
视角

Cuneiform語言

来自维基百科,自由的百科全书

Cuneiform语言
Remove ads

Cuneiform是用於大規模科學資料分析的開源工作流程語言英語Scientific workflow system[2][3]。 它是促進平行計算靜態型別純函數式程式語言。它的特徵是有個全功能的外界函式介面英語foreign function interface,允許使用者整合來自很多外部程式語言的軟體。Cuneiform在組織層面上提供了一些設施,如條件分支通用遞迴,使其具有圖靈完備性

快速預覽 編程範型, 設計者 ...
Remove ads

概述

Cuneiform嘗試拉近在科學工作流程系統如Apache Taverna英語Apache TavernaKNIME英語KNIMEGalaxy,與大規模資料分析程式模型如MapReducePig Latin之間的間隙,同時提供函數式程式設計語言的通用性。

Cuneiform是用分散式Erlang實現的。如果執行在分散式模態下,它匯出一個遵循POSIX分散式檔案系統,如GlusterCeph英語Ceph (software)#CephFS(用FUSE整合某個其他檔案系統例如HDFS)。作為替代選擇,Cuneiform指令碼可以執行在HTCondor英語HTCondorApache Hadoop頂上[4][5][6][7]

Cuneiform受到了Peter Kelly的工作的影響,他提議函數式程式設計作為科學工作流程執行的模型[8]。 故而,Cuneiform不同於其他的基於資料流程編程的工作流程語言,如並列手稿語言Swift英語Swift (parallel scripting language)[9]

Remove ads

擴充軟體整合

外部工具和庫(比如RPython庫)是通過外界函式介面英語foreign function interface來整合的。通過它可以組合,比如允許通過snippet節點使用外部軟體的KNIME英語KNIME,或為整合Java軟體提供BeanShell英語BeanShell服務的Apache Taverna英語Apache Taverna。通過定義採用外界語言的任務,就可能使用一個外部工具或庫的API。這種方式下,工具可以直接整合而不需要寫包裝器或重新實現工具[10]

目前支援的外界程式語言有:

計劃增加外界語言AWKgnuplot

型別系統

Cuneiform提供簡單的、靜態檢查的型別系統[11]。雖然Cuneiform提供列表作為複合資料類型,它省略了傳統的列表訪問子(headtail),以避免在訪問空串列時,可能引起的執行時間錯誤的可能性。轉而列表只能通過在其上mapfold,以全有或全無方式訪問。此外,Cuneiform(在組織層面)省略了算術,這排除了除以零的可能性。省略任何的部份定義運算,允許保證執行時間錯誤只能在外界代碼中引發。

基礎資料類型

Cuneiform提供的基礎資料類型有布林值字串檔案。這裡的檔案被用來以任意格式在外界函式之間交換資料。

記錄和模式匹配

Cuneiform提供記錄(結構)作為複合資料類型。下面的例子展示定義一個變數r,作為有兩個欄位a1a2的記錄,第一個是字串,而第二個是布林值:

let r : <a1 : Str, a2 : Bool> =
  <a1 = "my string", a2 = true>;

記錄可以要麼通過投影(projection)要麼通過模式匹配來訪問。下面的例子從記錄r,提取兩個欄位a1a2

let a1 : Str = ( r|a1 );

let <a2 = a2 : Bool> = r;

列表和列表處理

進一步的,Cuneiform提供列表作為複合資料類型。下面的例子展示定義一個變數xs,作為一個有三個元素的一個檔案:

let xs : [File] =
  ['a.txt', 'b.txt', 'c.txt' : File];

列表可以通過forfold算子來處理。這裡的for算子可以接受多個列表,來逐個元素的處置列表(類似於Racket中的for/listCommon Lisp中的mapcarErlang中的zipwith)。

下面的例子展示如何在一個單一的列表上map,結果是一個檔案列表:

for x <- xs do
  process-one( arg1 = x )
  : File
end;

下面的例子展示如何zip兩個列表,結果也是一個檔案列表:

for x <- xs, y <- ys do
  process-two( arg1 = x, arg2 = y )
  : File
end;

最後,列表可以使用fold算子來做聚集。下面的例子合計一個列表的元素:

  fold acc = 0, x <- xs do
    add( a = acc, b = x )
  end;
Remove ads

並列執行

Cuneiform是純函數式語言,就是說它不支援可變參照。作為結論,它可以使用獨立子項,將一個程式分解成可並列的各部份。Cuneiform排程器分布這些部份到做工節點。此外,Cuneiform採用傳名呼叫求值策略,值只在它對計算結果有貢獻時計算。最後,外界函式應用是記憶化的,用來加速包含以前推導結果的計算。

例如,下列Cuneiform程式允許fg的應用平行的執行,而h是有依賴的,它只在fg二者完成的時候可以開始:

let output-of-f : File = f();
let output-of-g : File = g();

h( f = output-of-f, g = output-of-g );

下列Cuneiform程式通過將函式f對映到一個三元素列表,建立了三個並列應用:

let xs : [File] =
  ['a.txt', 'b.txt', 'c.txt' : File];

for x <- xs do
  f( x = x )
  : File
end;

類似的,在記錄r的構造中,fg的應用是獨立的,因此可以並列執行:

let r : <a : File, b : File> =
  <a = f(), b = g()>;
Remove ads

例子

下面是一個hello-world指令碼:

def greet( person : Str ) -> <out : Str>
in Bash *{
  out="Hello $person"
}*

( greet( person = "world" )|out );

這個指令碼定義了採用Bash的一個任務greet,它對其字串實際參數person預加上"Hello "。這個函式產生具有一個單一字串欄位的記錄out。應用greet,繫結實際參數person到字串"world",產生記錄<out = "Hello world">。將這個記錄投影為它的欄位out,求值出字串"Hello world"

可以通過定義採用Bash的一個任務來整合命令列工具:

def samtoolsSort( bam : File ) -> <sorted : File>
in Bash *{
  sorted=sorted.bam
  samtools sort -m 2G $bam -o $sorted
}*

在這個例子中定義了任務samtoolsSort。它呼叫了工具SAMtools英語SAMtools,處置一個BAM格式的輸入檔案,並產生一個排序了也是BAM格式的輸出檔案。

Remove ads

發行歷史

更多資訊 版本, 出現日期 ...

在2016年4月,Cuneiform的實現語言從Java切換成了Erlang,並且在2018年2月,它的主要發布執行平台從Apache Hadoop變更為分散式Erlang。此外,從2015年到2018年,HTCondor英語HTCondor曾被作為可替代執行平台來維護。

Cuneiform的外表語法修訂過兩次,這反映在主版本號上。

版本1

在2014年5月發布的最初草案中,Cuneiform密切關聯於Make,它構造直譯器在執行期間要遍歷的靜態資料依賴圖。與後來版本的主要區別,是缺乏條件、遞迴或靜態型別檢查。區分檔案和字串,是通過同波浪號~形成一個單一參照的字串。指令碼的查詢表達式,通過target關鍵字來介入。Bash是預設外界語言。函式應用必須使用apply形式來完成,它接受task作為第一個關鍵字實際參數。一年之後,這種外表語法被一種精簡卻類似的版本所替代。

下面的例子指令碼從一個FTP伺服器下載一個參考genome:

declare download-ref-genome;

deftask download-fa( fa : ~path ~id ) *{
    wget $path/$id.fa.gz
    gunzip $id.fa.gz
    mv $id.fa $fa
}*

ref-genome-path = ~'ftp://hgdownload.cse.ucsc.edu/goldenPath/hg19/chromosomes';
ref-genome-id = ~'chr22';

ref-genome = apply(
    task : download-fa
    path : ref-genome-path
    id : ref-genome-id
);

target ref-genome;
Remove ads

版本2

Thumb
基於Swing的編輯器和Cuneiform 2.0.3的REPL

Cuneiform外表語法的第二個草案,首次發表於2015年3月,在Cuneiform的實現語言從JavaErlang的遷移期間,持續使用了三年。求值不同於早期方式,直譯器歸約一個表達式,而非遍歷一個靜態圖。在外表語法保持使用這段時期,直譯器被形式化和簡化,這導致了第一個Cuneiform的語意規定。語法特徵是有了條件。但是,布林值被編碼為列表,再度利用空串列為布林值false,非空串列為布林值true。遞迴後來作為形式化的副產品而增加。但是,靜態型別檢查,只在後來的版本3中介入。

下列指令碼解壓一個壓縮檔案,並把它分解為大小均勻的劃分:

deftask unzip( <out( File )> : zip( File ) ) in bash *{
  unzip -d dir $zip
  out=`ls dir | awk '{print "dir/" $0}'`
}*

deftask split( <out( File )> : file( File ) ) in bash *{
  split -l 1024 $file txt
  out=txt*
}*

sotu = "sotu/stateoftheunion1790-2014.txt.zip";
fileLst = split( file: unzip( zip: sotu ) );

fileLst;
Remove ads

版本3

Cuneiform外表語法的目前版本,比較於早期的草案,是嘗試拉近與主流函數式程式設計語言的間隙。它的特徵是簡單的靜態檢查的型別系統,並在列表之外介入記錄作為第二個複合資料結構類型。布林值獨立為基礎資料類型。

下列指令碼解包一個檔案,結果為一個檔案列表:

def untar( tar : File ) -> <fileLst : [File]>
in Bash *{
  tar xf $tar
  fileLst=`tar tf $tar`
}*

let hg38Tar : File =
  'hg38/hg38.tar';

let <fileLst = faLst : [File]> =
  untar( tar = hg38Tar );

faLst;

參照

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads