計算モデル安全性ポピュラリティスマートコントラクトプログラミングの場合、既存ライブラリの豊富さはあまり重要ではありません。既存のライブラリをそのままスマートコントラクトで使うということはあまりないからです。HTMLのパージングのライブラリをスマートコントラクトで使うということはありません。Tezosの場合それはより顕著です。moneyを目指すTezosではスマートコントラクト内で複雑な計算をすることは推奨されていません。複雑な計算はチェーン外で(平方根をニュートン法で求め)、その結果の検証をチェーン上で行う(自乗して元の値と比べる)のが理想のスマートコントラクトでのプログラミングとなります。型付き関数型言語の代数データ型とパターンマッチは文句なしに非常に強力な記述力を提供します。オブジェクト指向系言語ではクラスとメソッドがその代替となりますが、巨大なライブラリを形成することがないスマートコントラクトの世界(少なくともTezosではそう)では継承の魅力は大きいとは言えません。代数データ型と比べるとどうしても冗長さが目立つことになります。計算モデル計算モデルについては、スマートコントラクト実行環境と適合した物を持つ汎用プログラミング言語が適しています。Tezosのスマートコントラクトには静的型付き純粋関数型スタックVMであるMichelsonが使われています。これにコンパイルされる高級言語も同じ性質を持っている方が、高級言語とVMでのプログラム意味論の類推の簡単さや、コンパイラ記述の書きやすさに大きな利点があります。入出力のないスマートコントラクトでは、命令型言語とはいえSSA変換で十分純粋関数型に変換可能なので、命令型であることはさほど大きいデメリットではありません。strictな計算モデルを持つ言語は、その意味論をそのままスタックVMに移すのは手間がかかります。StrictなHaskellは、もうそれはHaskellではないDSLになっちゃいますね。OCamlは副作用に関する言語要素を抜けば簡単にstrictな純粋関数型言語になります。その多くのライブラリが副作用を使用していますが、上述の通りスマートコントラクトではライブラリはあまり重要ではありません。安全性パブリック・ブロックチェーンは換金性のあるトークンを扱わざるをえません(このことについては、私の発表でよく触れていますが、いつか小文を書いた方が良いとは思っています)。結果、その上で動くスマートコントラクトも換金性のあるトークンを操作することになります。スマートコントラクトのバグは、DAO事件などを見れば明らかなように、巨額の経済被害に直結します。シリアスなスマートコントラクトを書くのであれば、安全性に優れた、バグの発生しづらいプログラミング言語を選ぶ必要があります。汎用プログラミング言語中では、静的型付けを持った関数型言語が比較的そういった性質を持っています。型がなければ人類は実行時型エラーの起こらないプログラムを書くことはできないし、副作用ばかりであればプログラム挙動の解析、理解は形式的にも非形式的にも難しくなります。静的型付けを持った関数型言語を使ったからといって、バグが完全に無くなる、などというオメデタイ話はありません。そこで、安全よりの汎用プログラミング言語を選択した上で、完璧な安全性を保証したければプログラム検証技術を適用することが考えられます。静的型付けのある関数型言語とプログラム検証との相性は良く、特にOCamlはCoq定理証明支援器をはじめとする検証技術の環境には最も恵まれている言語の一つです。SCaml本体はこのようなプログラム検証技術を組み込みませんが、SCamlのプログラムを検証するための道具立てはすでに揃っていると言えます。ポピュラリティ汎用プログラミング言語は、一から作るDSLと比べれば、言語リファレンスやチュートリアルなどがすでに存在しているという面で参入障壁が非常に低いという利点があります。できれば既に習得しているユーザーがいれば、その障壁さえ無いのですから、それに越したことはありません。OCamlは広い世間では全くポピュラーな言語とは言えませんが、金融におけるトレーディングシステムや派生商品コントラクト記述言語に使われていたり、Facebook、dockerなど、decentな産業ユーザーはそれなりにいます。日本の大学教育はOCamlをやらされた人を毎年安定して供給してくれています。感覚でモノを言いますが50人/年はいるのではないでしょうか。これらの人々はコンピュータサイエンス系の学部に所属していることが多く、プログラミングに対する能力は非常に高いと期待できます。これらの人々の大半は単位さえ取ってしまえばOCamlなどその後の人生で触れることもないでしょうが、幾人かは目の前に金を積めばOCamlを使ってくれる人もいるのではないか。そんな人数ではポピュラリティもクソもないという方もおられるかもしれませんが、我々は全人類が有価値トークンを扱うスマートコントラクトを書くべきとは思っていない。コンピュータサイエンスを学び、プログラムの意味論に親しんだことのある人々の中ではOCamlは十分にポピュラリティのある言語です。OCaml以上の観点からOCamlを選ぶのは正解(もしくは正解に限りなく近いと結論しないと話がはじまらない)なのです。C系(C++/C#)のポインタ、リファレンスは必要ありません。型の無いスクリプト言語で手軽にスマートコントラクトを書いてバグらせたくはない。Scalaはクラス部分が余分。手続き型言語はプログラムの意味解析が人間、機械共に難しい。Erlangのような並列計算への利便性は必要ない。Haskellは遅延評価が相性が悪い。Coqと比べると人気ではどうしても劣る。Rustが提供するポインタ安全性やリソース安全性は純粋関数型スタックVMでの実行モデルにおいては価値がない。OCamlはマルチコア対応が遅れているが、スマートコントラクトはマルチスレッド概念は不要。OCamlを使っている人々でその文法が好きという人も珍しいが、CamlP4やPPXなどで強化可能だし、いざとなれば文法を全く差し替えることも(ReasonMLやCamleopardを参照)できる。Haskellが好きならHaskellそっくりの文法を持ったOCamlを作ることは全く可能です。そんなことをする酔狂な人が過去にいなかっただけですね(私に十分金を積んでくれれば一ヶ月で作ってあげます)。OCamlではコンパイラフレームワークがライブラリとして提供されており、これを最大限利用することで、パーサと型検査器は変更無しでタダで(ライセンスに同意できれば)利用できます。強力なアノテーションの機能がついているので、元言語の文法仕様を変えずに追加言語仕様をアノテーションを使うことで実現することが可能。ここに下位言語へのバックエンドを追加しさえすればそれだけでスマートコントラクト用言語ができてしまう、そこまでお膳立てが出来ているのです。以上の根拠でOCamlのコンパイラフレームワークを利用できるだけ利用したTezosブロックチェーンのスマートコントラクト記述言語がSCamlです。バージョンは3000行、5日で作れました。そこにパターンマッチとユーザー定義型を追加するのに10日。SCamlは半月で完成させたことになります。OCamlによるパースと型検査SCamlのプログラムはまずOCamlのパーサと型検査器に処理されます。OCamlプログラムとして問題があればOCamlコンパイラと同じエラーメッセージで報告されます。OCamlのエラーが読みにくい、という方は自作言語を作ってそのエラーメッセージのお粗末さに絶望したことのない人間だ。OCaml型付きASTからSCamlの中間言語への変換OCamlのコンパイラフレームワークによって検査されたプログラムはOCamlの型付きASTからSCamlの中間言語"IML"のASTに変換されます。IMLは単相型付き純粋関数型。それに適合しない機能を使っているOCamlプログラムはここで拒否されます。モジュール/ファンクタクラス/オブジェクトの使用は全て弾かれます。多相型を弾くのは下位言語Michelsonが単相型の言語だからです。多相関数が書けなくなりますが、プログラムが小規模でライブラリも重要性がないというスマートコントラクトの特殊な環境ではそうデメリットではありません。(将来多相関数をサポートし、各使用に応じて関数定義を複数回具体化する計画はあります。)再帰を弾くのもやはりMichelsonが一般の再帰が記述できないようになっているためです。(Michelsonにはリストなどの再帰型データに関する操作プリミティブやループのためのプリミティブがあるので、それでもチューリング完全な言語です。これらのプリミティブを呼び出す関数はSCamlには用意されています。)パターンマッチとユーザー定義型はIMLには存在しないため、この変換にはパターンマッチコンパイルとユーザー定義型のプリミティブ型への変換も含まれています(ここに10日かかった)。IMLは単相型付き純粋関数型言語です。MichelsonスタックVMオプコードへのコンパイルは、オーソドックスなλ計算からスタックマシンへのコンパイルで、特筆すべきことはありません。初期のMichelsonでは型付きのくせにクロージャーが無かったため、クロージャー変換が大変でしたが(クロージャー変換を知っていて、この難しさがわからない人は型付きのスタックマシンで考えてみると良いです)、MichelsonのBabylonアップグレードによりクロージャーが下位言語レベルでサポートされたので、苦労なくできるようになりました。typingとそれを使ったクロージャー変換の労力は無駄になりました。)驚き最小の原則と、唯一の驚きSCamlはOCamlからMichelsonへの最も自然なコンパイル方法を選択しています。OCamlの様々な機能がSCamlでは制限されてはいますが、これらの機能はサポートされていないことを明示的に表示して拒否されるので、(OCamlプログラムとしてのエラーの意味がわからない、という初心者を除けば)謎のエラーを貰うことはありません。「驚き最小の原則」をかなり実現できているはずです。唯一の驚きがあります。big_mapの型を持つ変数は関数中の自由変数として出現することができません。このようなコードを書いてしまった場合はコードの再設計を迫られます。これは、Michelsonのクロージャの環境部分にこれらの「unpackableな型」を持つ値を載せることができない制限のためです。これは高級言語側ではシステマチックに回避することは恐らくできません。内部で自由に出現しています。そのため拒否されます。Curry化された高階関数を取らずUncurry化された関数を取るList.fold_left'を用意しています。khsこれがOCamlプログラマにとってのSCaml仕様上でのほぼ唯一の驚きだと思います。(SCamlのバグによる驚きについては、そりゃあるでしょう。なくなるように努力していますが。)Tezosの他のOCaml系言語との比較TezosにはLiquidityとCamLigoというやはりOCamlに似た高級言語があります。Liquidityの制作者はTezosと揉めた経緯があり、今は独自のブロックチェーンをやっています。Liquidityは今でもTezosに使えることになっていますが、様々なリスクが無視できないため個人的には使わないことをお勧めしています。この技術外のリスクを除くと、LiquidityとCamLigoはOCamlのコンパイラフレームワークをあまり使わずに作られた言語で、スマートコントラクト用の独自機能や検証機構が追加されており、OCamlと非互換な部分があることが共通しています。SCamlには他のに言語のようなスマートコントラクトのための便利な機能はありませんが、その分、OCamlのコンパイラと同じ使用感とそのエコシステムツールがほぼそのまま使えるという利点があります。SCamlにもOCamlを超えたスマートコントラクト用言語仕様や、検証機構を備えようという計画(というか夢想)はありますが、それはSCaml本体に施されることはなく、SCamlを取り巻くツールとして実装されるべきだと考えています。SCaml自体は愚直にOCamlコンパチブルな言語であった方が、言語開発者としての責任領域を下手に広げずに済みます。OCamlという既知の言語との仕様の共通性を担保することは、SCamlを対象とした新機能を作ろうと思っていただける第三者の参入障壁を下げるという点でも重要なことだと思っています。Stupidraightforward.今回はこれでおしまい第0回はSCamlのコンセプトについて説明しました。これから少しずつSCamlによるTezosスマートコントラクトプログラミングについての解説を書いていきたいと思います...が、記事書きで本業を圧迫できないので、あまり丁寧な説明にはなりそうにありません。粗く不親切であっても全部をまず抑える方が良いかと思っています。Tezosブロックチェーンの動作機構については他に譲ります。JapanからもSCamlを使ったチュートリアルが出る予定です。「やさしさ」はそちらに任せます。