Lambdaカクテル

京都在住Webエンジニアの日記です

記法・ 表記・マークアップ言語と呼ばれるものはどこまで許容されるのか

なんかYAML好きになれないんですがあなたはどうですか。オチはないです。

今仕事でやっているPerlのプロダクトでは(Config::Env)を使ってプロダクトの設定をしていて,DSLになっているので色々と便利ができる。 一番良く使っている機能は継承で,DSNとかを継承させて,手元に近い環境ではローカルのDBにつながるけれど,本番に寄せたい環境では本番のDBにつながる,といった設定ができるようになる。 だいたいのWebアプリケーションにはこういう機能があると思う。

ところで今日ちょっとしたツールを書こうとした。DBを舐めて特定のフォーマットのデータを吐くという典型的なツール。DBを叩くのでDBの接続情報が必要になる。DSNとかユーザ名とか。

だが接続情報はConfig.pmにあるから,perlでなければ使えない。するとちょっとしたツールの実装言語もperlに制約されてしまうことになって嬉しくない。 やりたいタスクによって言語を変えたいというのは言うまでもなく自然なはずで,構文解析的なのをやりたいならLispを使いたいはず*1

JSONといったマークアップ言語を使うこともできるが,JSONには継承構文がないのでそのまま使うわけにはいかず,JSONを読み込んでこれのセマンティックをパースし,ソフトウェア側でmergeする処理不可避。あまり意味がない。

*

ところで,マークアップ言語に処理的な,つまりプロシージャルな側面があると扱いにくくなるようだ。見ただけではなく実行しないと内容が判明しないといった構文。

ちなみにYAMLという闇の奥の深いマークアップ言語があって,アンカーってやつで継承できたりするのだが,これはこれで本質的ではないというか,構文を無理に追加した感じがして,むしろ可読性を下げているような気がする。あまり「マークアップ」できていない。個人の感想です。あまり好きじゃない。

YAMLを拡張してコードを埋め込むという発想もあるのだが,だったら最初から言語のDSLで書いたほうが良い。

そういうことを考えていたところ,マークアップ言語と呼ばれるものはどこまで許されるのか,一般にプログラムと呼ばれるものとの境目があるならどこなのか,ということが気になってきた。 そもそも継承欲しいなんて言っているけど,継承そのものはマークアップの必要条件ではない。継承がないマークアップも当然あるし,それで問題ない場面がある。

とはいえ,マークアップはデータの構造的なリテラルであるともいえそうで,データを簡潔に表記するために継承関係が有用ならそれを取り入れたいというのも当然な発想だ。 だが継承はプロシージャルな側面を持っていて,「継承先になければ継承元のものを使う」「継承先にあれば継承先のものを優先する」という条件判断を含んでいる。そういうのをうまく扱えばプロシージャルな側面をうまくごまかすことができる。 このへんの話は多重継承の話に似ているような気もする。

「設定」に特化した言語を1つこしらえてしまうのも,面白いかもしれない。VCLみたいになりそう・・・。Very Cool Configuration Languageみたいな名前にしてほしい。

*

んで,これができたら最早マークアップ言語じゃないじゃん,みたいなのはあると思う。ループ構文とか,ディスクをイジェクトする構文が登場したらふざけんなってなると思う。 その一方でLispには循環リストを表記するためのリテラルがあったりする。#1=(a b c d e . #1#)みたいなやつ。COOLじゃん。

継承をそのまま表記の包含みたいな形にできないだろうか。

common {
  a: 123
  local { a: 321 }
  prod { a: 666 }
}

みたいに書ければ良いのではという気もする。多重継承はできなくなりそうだけれど,設定ファイルで多重継承とかしないでほしい気もする。

*

話が逸れたけど,なんか良い設定ファイルの扱いないのだろうか。

マークアップは構造のリテラルなので,構造以上のことをやってはいけない,というのが個人的に落ち着く。

*1:行列計算したければPythonを使いたいだろう