this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: adapt blog content for new odoc format

Remove # prompt prefixes and toplevel output from code blocks in blog
posts that were migrated from the old odoc_notebook format. The new
odoc-interactive-extension expects plain OCaml code without toplevel
prompts.

Files changed:
- module-type-of.mld: Remove # prompts, ;; terminators, and output
lines from 7 interactive OCaml code blocks
- this-site.mld: Remove # prompts and convert {x@ocaml[ deferred
blocks to regular {@ocaml[ blocks (output now renders automatically)
- odoc-bugs.mld: Remove # prompt and ;; from the run-on=load block
- ocaml-mcp-server.mld: Remove # prompt from bash code block
- ocaml-lsp-mcp.mld: Remove # prompts from 3 bash code blocks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+42 -73
+23 -41
site/blog/2025/03/module-type-of.mld
··· 12 12 module. For example, if I had a module [X]: 13 13 14 14 {@ocaml[ 15 - # module X = struct 16 - type t = Foo | Bar 17 - end;; 18 - module X : sig type t = Foo | Bar end 15 + module X = struct 16 + type t = Foo | Bar 17 + end 19 18 ]} 20 19 21 20 then I can get back the signature of [X] using [module type of]: 22 21 23 22 {@ocaml[ 24 - # module type Xsig = module type of X;; 25 - module type Xsig = sig type t = Foo | Bar end 23 + module type Xsig = module type of X 26 24 ]} 27 25 28 26 which can be very useful if you’re trying to ··· 36 34 expression, as it’s very useful to know. If you’re extending a module, your signature might look like: 37 35 38 36 {@ocaml[ 39 - # module type UnitExtended = sig 40 - include module type of Unit 41 - val extra_unit_function : unit -> unit 42 - end;; 43 - module type UnitExtended = 44 - sig 45 - type t = unit = () 46 - val equal : t -> t -> bool 47 - val compare : t -> t -> int 48 - val to_string : t -> string 49 - val extra_unit_function : unit -> unit 50 - end 37 + module type UnitExtended = sig 38 + include module type of Unit 39 + val extra_unit_function : unit -> unit 40 + end 51 41 ]} 52 42 53 43 The documentation we produce will expand the contents of the [include] statement, but keep track of the ··· 60 50 with. Let’s start with a module type [S]: 61 51 62 52 {@ocaml[ 63 - # module type S = sig 64 - module X : sig 65 - type t = int 66 - end 53 + module type S = sig 54 + module X : sig 55 + type t = int 56 + end 67 57 68 - module type Y = 69 - module type of X 70 - end;; 71 - module type S = 72 - sig 73 - module X : sig type t = int end 74 - module type Y = sig type t = int end 75 - end 58 + module type Y = 59 + module type of X 60 + end 76 61 ]} 77 62 78 63 We’ll now define a new module [X2] that we intend to use as a replacement for [X]: 79 64 80 65 {@ocaml[ 81 - # module X2 = struct 82 - type t = int 83 - type u = float 84 - end;; 85 - module X2 : sig type t = int type u = float end 66 + module X2 = struct 67 + type t = int 68 + type u = float 69 + end 86 70 ]} 87 71 88 72 Now we’ll define a new module type [T] which is [S] but with [X] replaced: 89 73 90 74 {@ocaml[ 91 - # module type T = S with module X := X2;; 92 - module type T = sig module type Y = sig type t = int end end 75 + module type T = S with module X := X2 93 76 ]} 94 77 95 78 Here you can see that OCaml has expanded the [module type of] expressions and told us the computed signature. ··· 99 82 the following: 100 83 101 84 {@ocaml[ 102 - # module type T = sig 103 - module type Y = module type of X2 104 - end;; 105 - module type T = sig module type Y = sig type t = int type u = float end end 85 + module type T = sig 86 + module type Y = module type of X2 87 + end 106 88 ]} 107 89 108 90 and the expansion of this would then clearly have both types [t] and [u] in it.
+10 -23
site/blog/2025/04/this-site.mld
··· 24 24 Let's start with a little demo: 25 25 26 26 {@ocaml[ 27 - # let x = 1 + 2;; 28 - val x : int = 3 27 + let x = 1 + 2 29 28 ]} 30 29 31 30 It's intended to look like an OCaml toplevel session, so each new expression starts with a [#] and is ··· 38 37 text. The following cell creates an SVG image and 'pushes' it to [Mime_printer], which receives the 39 38 mime value and renders it in the browser below the code block. 40 39 41 - {x@ocaml[ 42 - # let svg = [ 43 - {|<svg height="210" width="500" xmlns="http://www.w3.org/2000/svg">|}; 44 - {|<polygon points="100,10 40,198 190,78 10,78 160,198" |}; 45 - {|style="fill:lime;stroke:purple;stroke-width:5;"/></svg>|}];; 46 - val svg : string list = 47 - ["<svg height=\"210\" width=\"500\" xmlns=\"http://www.w3.org/2000/svg\">"; 48 - "<polygon points=\"100,10 40,198 190,78 10,78 160,198\" "; 49 - "style=\"fill:lime;stroke:purple;stroke-width:5;\"/></svg>"] 50 - # Mime_printer.push "image/svg" (String.concat "\n" svg);; 51 - - : unit = () 52 - ]x[ 53 - {%html: <svg height="210" width="500" xmlns="http://www.w3.org/2000/svg"> 54 - <polygon points="100,10 40,198 190,78 10,78 160,198" 55 - style="fill:lime;stroke:purple;stroke-width:5;"/></svg> %} 40 + {@ocaml[ 41 + let svg = [ 42 + {|<svg height="210" width="500" xmlns="http://www.w3.org/2000/svg">|}; 43 + {|<polygon points="100,10 40,198 190,78 10,78 160,198" |}; 44 + {|style="fill:lime;stroke:purple;stroke-width:5;"/></svg>|}];; 45 + 46 + Mime_printer.push "image/svg" (String.concat "\n" svg) 56 47 ]} 57 48 58 49 {1 Things to come} ··· 84 75 in the cell above. Merlin highlights the use of the varible [svg] is, because it's not aware 85 76 of the varible, but the code gets executed correctly and the image is rendered below the cell. 86 77 87 - {x@ocaml[ 88 - Mime_printer.push "image/svg" (String.concat "\n" svg);; 89 - ]x[ 90 - {%html: <svg height="210" width="500" xmlns="http://www.w3.org/2000/svg"> 91 - <polygon points="100,10 40,198 190,78 10,78 160,198" 92 - style="fill:lime;stroke:purple;stroke-width:5;"/></svg> %} 78 + {@ocaml[ 79 + Mime_printer.push "image/svg" (String.concat "\n" svg) 93 80 ]} 94 81 95 82 Edit 2025-05-20: I have now got merlin working across cells, though I'm not convinced the current
+3 -3
site/blog/2025/08/ocaml-lsp-mcp.mld
··· 7 7 We're going to use {{:https://github.com/isaacphi}issacphi}'s adapter for LSP servers, which is written in go. So install go, and then: 8 8 9 9 {@bash[ 10 - # go install github.com/isaacphi/mcp-language-server@latest 10 + go install github.com/isaacphi/mcp-language-server@latest 11 11 ]} 12 12 13 13 Once that's done, make sure you've got `ocaml-lsp-server` installed in your switch: 14 14 15 15 {@bash[ 16 - # opam install ocaml-lsp-server 16 + opam install ocaml-lsp-server 17 17 ]} 18 18 19 19 Then add the MCP config for claude where you want to run it: 20 20 21 21 {@bash[ 22 - # claude mcp add ocamllsp -s local -t stdio -- /Users/jon/go/bin/mcp-language-server -workspace . -lsp ocamllsp 22 + claude mcp add ocamllsp -s local -t stdio -- /Users/jon/go/bin/mcp-language-server -workspace . -lsp ocamllsp 23 23 ]} 24 24 25 25 It'd be nice to get this working `globally` - that is, with `-s user` - but I haven't been able to get that to work yet.
+1 -1
site/blog/2025/08/ocaml-mcp-server.mld
··· 535 535 the University of Cambridge. To enable it with Claude, try this: 536 536 537 537 {@bash[ 538 - # claude mcp add -t sse ocaml http://dill.caelum.ci.dev:8000/sse 538 + claude mcp add -t sse ocaml http://dill.caelum.ci.dev:8000/sse 539 539 ]} 540 540 541 541 Obviously this is pre-alpha quality software, and we might take it
+5 -5
site/blog/2025/09/odoc-bugs.mld
··· 56 56 [S1] is: 57 57 58 58 {@ocaml run-on=load [ 59 - # module type S1 = sig 60 - type t0 61 - type 'a t := unit 59 + module type S1 = sig 60 + type t0 61 + type 'a t := unit 62 62 63 - val x : t0 t 64 - end;; 63 + val x : t0 t 64 + end 65 65 ]} 66 66 67 67 where the substitution has clearly taken place. In contrast, odoc takes the position