# pl/ocaml-extension-points

PPX are executed at compilation phase. They transform the AST of OCaml code.

There are attributes that are attached to the AST, and they are read-only meta-info that does not affect directly compilation and semantic of the PL.

There are extension nodes that are maco instructions that must be expanded to valid OCaml code, from the PPX compiler. TODO check if they can be expanded into code using other extension nodes, like macro in CL.

TODO in Dok I want to add a lot of meta-info to a node, because it supportsfeature/multiple-run-times. So the IDE must mask some of this info. The code is not meant to be readable without an IDE. See paradigm/IDE-oriented-programming.

type serializable_blob = Blob.t =
{ value : string
; length : int
; id : int
}
[@@deriving yojson]

let a = 12 [@attr pl]

let b = "some string" [@@attr pl]

[@@@attr pl]

# note: the numbers of @ indicate the scope level at wihch apply the meta-info

# An extension mixing C code with Ocaml code
external%c puts_flush : str:string -> bool = {|
int r = puts($str); if ( r < 0 ){ return false; } r = fflush(stdout); return (r == 0); /* return is mandatory, unless your function is void */ |} [@@ release_runtime_lock] let _ : bool = puts_flush ~str:"Hello World" # An extension supporting TDD let%expect_test _ = let f output = print_string output; [%expect {| hello world |}] in f "hello world"; f "hello world"; ;; print blah; [%expect {| abc defg hij|}] print blah; [%expect {| abc defg hij |}] print blah; [%expect {| abc defg hij |}] # An extension for SQL let update_account = [%sqlf {| UPDATE accounts SET email =$email, account_type = $account_type WHERE account_id =$account_id
RETURNING account_id, created_at, account_type, email
|}]


See http://ocamlverse.net/content/metaprogramming.html as entry point.