#OCaml@p : A debugging print system for OCaml OCaml@p is a tool supporting debug in OCaml programming. When you compile a program by this tool, this tool generates definition of print function automatically, and inserts function calls to print expression attached marker [@p] automatically. note : This tool doesn't consider use in combination with other PPX tools using attributes. #How to use ##installation Version : 1.1.0 required OCaml version : OCaml 4.03.0 OPAM released install ``` opam install ocaml_at_p ``` uninstall ``` opam remove ocaml_at_p ``` ##How to compile with OCaml@p When you compile a.ml with OCaml@p ``` ocamlfind ocamlc(ocamlopt) -package ocaml_at_p -linkpkg a.ml ``` ##How to write code ###Marker for print In OCaml@p, when you write marker [@p] behind expression that you want to print the return value, so you can print. The marker [@p] is attribute syntax in OCaml. ``` let add x y = x + y [@p x] [@p y] [@p] [@p _this+100] let a = add 1 10 let b [@p] = a ``` Then,markers (`[@p x],[@p y],[@p]`) are attached the expression (`x + y`).Two marker `[@p x]` and `[@p y]` are used to print values of expressions `x` and `y` ,and the marker `[@p]` is the value of the expression `x + y`.The variable `_this` is specific one bound by result of evaluation to expression (`x + y`). `_this` is the special variable bound by the result value of evaluating the expression. The following is result of run the program. ``` 1 <- at [@p x] 10 <- at [@p y] 11 <- at [@p] 111 <- at [@p _this+100] b = 11 <- at "let b [@p] = a" ``` ###Marker types There are two types marker `[@p]`, `[@ps]`, `let x [@p]`. * `e [@p]` - newline after printing e * `e [@p expr]` - newline after printing expr * `e [@ps]` - not newline after printing e * `e [@ps expr]` - not newline after printing expr * `let x [@p] = e` - newline after printting "x = " and e ###Outer module check [@@@ppopen] This tool cannot be sure to define print function that print a value of datatype defined in other ml files, so it is difficulty for users to understand error messages. Then, users need to write `[@@@ppopen module_name]` in Toplevel of ml file written markers to be clear that the ml files of module are compiled by OCaml@p. ##limitation ###module from functor(TODO) A program using module generated by functor connot be compiled with OCaml@p. OCaml@p change signature, and functor's arguments signature is also changed. So it cause type error. ###polymorphic value OCaml@p cannot print polymorphic values e.g. internal a polymorphic function. For example, the marker `[@p xs]` in the function `length` cannot print. ``` let rec length = function | [] -> 0 | x::xs -> 1 + length xs [@p xs] ``` --- # OCaml@p : OCamlにおけるデバッグ出力機構 OCamlプログラムのデバッグ出力をサポートするツールです.このツールを用いてコンパイルすると,型定義から型に対応した出力関数定義を自動生成します.また,マーカ[@p]のついた式を出力する関数呼び出しを自動で挿入します. 注 : 本システムでは他のattributeを用いたPPXツールとの併用は考慮していません. #使用方法 ##インストール方法 Version : 1.1.0 必要な OCaml version : OCaml 4.03.0 opam でリリースされています install ``` opam install ocaml_at_p ``` uninstall ``` opam remove ocaml_at_p ``` ##OCaml@pを用いたコンパイル方法 a.mlをOCaml@pでコンパイルするとき ``` ocamlfind ocamlc -package ocaml_at_p -linkpkg a.ml ``` ##コードの記述方法 ###出力マーカ [@p] OCaml@pでは返す値を出力したい式にマーカ[@p]を記述することで,出力することができます.マーカはOCamlのattribute構文を用いています. ``` let add x y = x + y [@p x] [@p y] [@p] [@p _this+100] let a = add 1 10 let b [@p] = a ``` ここで,`[@p x],[@p y],[@p]`は式`x + y`に付与されています.`[@p x],[@p y]`はそれぞれ`x,y`の値を,`[@p]`は`x + y`の値を出力します.`_this`は特別な変数で,式`x + y`の評価結果が束縛されている.このプログラムを実行した時の出力結果は以下のようになります. ``` 1 <- [@p x] の出力 10 <- [@p y] の出力 11 <- [@p] の出力 111 <- [@p _this+100] の出力 b = 11 <- let b [@p] = a での出力 ``` ###マーカの種類 マーカは5種類存在する. * `e [@p]` - `e`の評価結果を出力後に改行 * `e [@p expr]` - `expr`の評価結果を出力後に改行 * `e [@ps]` - `e`の評価結果を出力後に改行しない * `e [@ps expr]` - `expr`の評価結果を出力後に改行しない * `let x [@p] = e` - `"x = "`と`e`の評価結果を改行 ###外部モジュールチェック [@@@ppopen] 本システムでは他のmlファイル内で定義されたデータ型を出力する際に,出力関数が定義されているか確かめる術がないため,Unboundエラーが出てしまい、エラー内容がわかりづらい.そこで,そのモジュールのmlファイルがOCaml@pを用いてコンパイルされていることを、ユーザが出力を行うファイルのトップレベルに`[@@@ppopen モジュール名]`と記述するようにした. ##制限 ###ファンクターを用いたモジュール OCaml@pはモジュールの型シグネチャを書き換えるので,ファンクタの引数に要求されるモジュールの型シグネチャも書き換える.これにより,型エラーを引き起こしてしまう.対応検討中. ###多相型の値 OCaml@pでは,例えば多相関数の中に現れるような,型の定まらない多相型の値を出力することができない.例えば,次のような関数内のマーカ`[@p xs]`は出力できない. ``` let rec length = function | [] -> 0 | x::xs -> 1 + length xs [@p xs] ```