LoginSignup
2
1

More than 3 years have passed since last update.

SATySFiのパッケージを作る

Posted at

これは「SATySFi Advent Calendar 2019」の24日目の記事です。

23日目はbd_gfngfnさんでした。25日目はpuripuri2100です。

はじめに

SATySFiで機能を拡張したり新たな機能を追加したりするときに用いるのが「パッケージ」です。

実態としてはlet-inlinelet-blockで定義されたコマンド、letlet-recで定義された関数などです。

利用者側がパッケージを@require@importで読み込むだけで、そこで定義されているコマンドや関数を使えるようになるという便利機能で、SATySFiを使っている人間ほぼ全員がお世話になっていることでしょう。

さて、このパッケージはとても簡単に作ることができるのでここで解説してみようと思います。

コマンドや関数をパッケージ化することでメンテナンスしやすくなったり、便利機能を使いまわすことができたり、車輪の再発明を防いだりすることができるので、良いコマンドや関数を作ったらパッケージ化していくようにしましょう。

パッケージの配布方法についてはこのアドベントカレンダーの「素敵なライブラリをSatyrographosで配布しよう!」をお読みください。

ファイルを分ける

まず、機能が似ている関数やコマンド、目的が同じ関数やコマンドを別のファイルに分けましょう。これだけでもパッケージになります。

基本としてはそのままコピペするだけですが、注意点として依存する他のパッケージがある場合はそれを読み込む必要がありますし、元の文書のプリアンブルなどに依存する関数などが書いてある場合はそれもすべてコピペする必要があるということです。

ここで定義された関数などは、パッケージを読み込んだだけですぐに使えるようになります。
便利ですね。

しかし、これには欠点があります。
内部で関数などを定義するときだけに使われるものがトップレベルで定義されてしまい、場合によっては他のパッケージの関数などを覆い隠してしまい、衝突してしまうかもしれないのです。

ここで使う機能がモジュールです。

モジュールを使う

定義する関数などに名前空間を付ける機能がモジュールです。

モジュールは

module 〈名前〉 = struct

  関数やコマンドの定義

end

という形で使います。
コンストラク名は大文字のアルファベットから始まるアルファベットと数字の組み合わせのものです(正規表現なら[A-Z][a-zA-Z0-9]*となります)。

ここで定義された関数は〈モジュール名〉.〈関数名〉のようにして使います。
たとえばこんな感じです。


module Module0 = struct

  let hoge = 1

end

let fuga = Module0.hoge

一々モジュール名を書くのが面倒な時はopen 〈モジュール名〉とすることで省略できるようになります。

効果を局所的にしたいときはopen 〈モジュール名〉 inとするか〈モジュール名〉.(式)とするかします。

シグネチャを使う

モジュールを使うと名前空間によって関数などが衝突するのを防げますが、内部で使うだけの関数も公開されてしまいます。

そこで、シグネチャという機能を使うことで後悔する関数やコマンドを限定することができます。

使い方は

module 〈名前〉:sig 

  公開する関数などの名前と型

end = struct

  関数やコマンドの定義

end

です。関数はval f : 型の形で、型はtype ttype t = 定義の形で公開できます。

コマンドはval cmd : 型のリスト inline-cmdかblock-cmdの指定direct cmd : 型 inline-cmdかblock-cmdの指定でできます。directを使うと、トップレベルで定義したのと同じように、モジュール名を付けなくてもコマンドを使うことができるようになります。

例えばこんな感じです。

@require: stdja

module Module1 :sig

  val hoge : int
  direct \test : [string] inline-cmd
  direct +test : [string] block-cmd

end = struct

  let hoge = 1

  let fuga = 2 %公開されない

  let-inline \test str = embed-string str

  let-block +test str = <+p{\test(str);}>

end

おわりに

短い記事なりましたが、モジュール機能やシグネチャを使って素敵なパッケージをたくさん作ってみてください。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1