
Humeは、2000年以降、スコットランドのセント・アンドリュース大学とヘリオット・ワット大学で開発された関数型プログラミング言語です。言語名は「高階統一メタ環境」を意味する頭字語であると同時に、18世紀の哲学者デイヴィッド・ヒュームへの敬意を表したものです。リアルタイムコンピューティングの組み込みシステムを対象とし、高度に抽象的でありながら、実行時の時間と空間コストを正確に抽出できる設計を目指しています。これにより、プログラム実行に必要な時間と空間の制約を確実に満たすことができます。
ヒュームは、関数型プログラミングの考え方と有限状態オートマトンの概念を組み合わせている。オートマトンは、通信するプログラムを「ボックス」の集合に構造化するために用いられ、各ボックスは高レベルのパターンマッチングを用いて、入力を純粋に関数的な方法で出力にマッピングする。オートマトンは何層にも構造化されており、各層は異なる機械特性を示す。
Hume言語の設計は、組み込みシステム領域で必要とされる基本的な特性と機能(特に透過的な時間および空間コスト計算)を維持しつつ、可能な限り高いレベルのプログラム抽象化を実現することを目指しています。対象とするアプリケーションは、シンプルなマイクロコントローラからスマートフォンなどの複雑なリアルタイムシステムまで多岐にわたります。この野心的な目標を達成するには、割り込み処理などの低レベルの概念と、データ構造の抽象化などの高レベルの概念の両方を取り入れる必要があります。これらのシステムは多様な方法でプログラミングされますが、言語設計はこうした多様な要件に対応できるものでなければなりません。
Humeは3層構造の言語です。外側の(静的な)宣言/メタプログラミング層、動的プロセスと関連デバイスの静的なレイアウトを記述する中間調整層、そして各プロセスをパターンから式への(動的な)マッピングとして記述する内側の層です。内側の層はステートレスで、純粋に関数型です。
既存の言語フレームワークにコストモデリングと正当性証明技術を直接適用したり、より一般的な言語を変更したり(例えばRTSJのように)するのではなく、Hume の設計者たちは形式モデルと証明を確実に構築できるように Hume を設計するというアプローチをとっています。Hume は一連の重なり合う言語レベルとして構成されており、各レベルは式の意味論に表現力を追加しますが、望ましい特性の一部を失うか、形式的な正当性/コストモデルを提供する技術的な難易度を増大させます。[ 1 ]
インタプリタ版とコンパイラ版は若干異なります。
調整システムは、データフロープログラミングのスタイルでボックスを配線します。
この表現言語はHaskellに似ています。
メッセージパッシングの並行処理システムは、JoCamlのジョインパターンやポリフォニックCシャープコードを記憶していますが、すべてのチャネルは非同期です。
組み込みのスケジューラが、すべてのボックスを順番にパターンマッチングを継続的にチェックし、入力先がビジー状態のため出力をコピーできないボックスを保留状態にします。
データコイン=ニッケル|ダイム|偽物;データドリンク=コーヒー|紅茶;データボタン= BCoffee | BTea | BCancel ;type Int = int 32 ;例外EFakeCoin :: ( Int , string ) ;show v = v as string ; box coffee in ( coin :: Coins , button :: Buttons , value :: Int ) -- 入力チャネルout ( drink_outp :: string , value ' :: Int , refund_outp :: string , display :: string ) -- 名前付き出力500 KB ( 400 B )以内-- 最大ヒープ (最大スタック) コスト制限はEFakeCoin 、TimeOut 、HeapOverflow 、StackOverflowを処理します一致-- * 未入力の出力と未消費の入力のワイルドカード( my_coin 、* 、v ) {- ''join-pattern'' と同等: coin(my_coin) & value(v) -} -> let v ' = incrementCredit my_coin v in ( * 、v ' 、* 、show v ' ) -- 時間制限 (''within x time-unit'') で TimeOut () が発生します| ( * 、BCoffee 、v ) {- ''join-pattern'' と同等: button(BCoffee) & value(v) -} -> ( vend Coffee 10 v ) within 30 s | ( * 、BTea 、v ) -> ( vend Tea 5 v ) within 30 s | ( * , BCancel , v ) -> let refund u = "Refund " ++ show u ++ " \n " in ( * , 0 , refund v , * )handle EFakeCoin ( v , msg ) -> ( * , v , * , msg ) | TimeOut () -> ( * , * , * , "コンテンツが不足している可能性があります。サービスを呼び出してください!" ) | HeapOverflow () -> ( * , * , * , "エラー: ヒープ制限を超えました" ) | StackOverflow () -> ( * , * , * , "エラー: スタック制限を超えました" ) ;incrementCredit coin v = case coin of Nickel -> v + 5 Dime -> v + 10 Fake -> raise EFakeCoin ( v , "coin rejected" ) ; vend drink cost v = if v >= cost then ( serve drink , v - cost , * , "your drink" ) else ( * , v , * , "money is short of " ++ show ( cost - v )) ; serve drink = case drink of Coffee -> "Coffee \n " Tea -> "Tea \n " ; box control in ( c :: char ) out ( coin :: Coins , button :: Buttons ) match 'n' -> ( Nickel , * ) | 'd' -> ( Dime , * ) | 'f' -> ( Fake , * ) | 'c' -> ( * , BCoffee ) | 't' -> ( * , BTea ) | 'x' -> ( * , BCancel ) | _ -> ( * , * ) ; console_outpを"std_out"にストリームします。; console_inp を"std_in"からストリームします。-- データフロー ワイヤcoffee -- 入力 (チャネルの起点) ( control . coin 、control . button 、coffee . value '初期値は0 ) -- -- 出力先( console_outp 、coffee . value 、console_outp 、console_outp ) ;ワイヤcontrol ( console_inp ) ( coffee . coin 、coffee . button ) ;