# Optimising an interpreter

**URL:** <https://discuss.ocaml.org/t/optimising-an-interpreter/10874>\
**Category:** Learning\
**Tags:** metaocaml, metaprogramming\
**Created:** [November 28, 2022, 8:56pm UTC](https://discuss.ocaml.org/t/optimising-an-interpreter/10874 "2022-11-28T20:56:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jon\_Harrop](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jon_harrop/32/2015_2.png) [@Jon\_Harrop](https://discuss.ocaml.org/u/Jon_Harrop)\
**Post date:** [November 28, 2022, 8:56pm UTC](https://discuss.ocaml.org/t/optimising-an-interpreter/10874/1 "2022-11-28T20:56:34Z")

</div>

If I have an interpreter written in OCaml and I want it to run code faster without the burden of having to write a compiler what are my options?

I could use MetaOCaml and do staged metaprogramming. Should be easy and achieve a very respectable speedup but MetaOCaml is obscure so I assume dev tools would no longer work?

If I run my interpreter as bytecode can I generate bytecode on-the-fly and have it executed? If so, how? Can malfunction do this sort of thing?

Are there any libraries that might help like expression trees to LLVM compilers?

---

<div class="post-metadata">

**Author:** ![didier-wenzek](https://avatars.discourse-cdn.com/v4/letter/d/9de0a6/32.png) [@didier-wenzek](https://discuss.ocaml.org/u/didier-wenzek)\
**Post date:** [November 28, 2022, 9:13pm UTC](https://discuss.ocaml.org/t/optimising-an-interpreter/10874/2 "2022-11-28T21:13:40Z")

</div>

This series of posts might help you: [How I wrote my own “proper” programming language](https://mukulrathi.com/create-your-own-programming-language/intro-to-compiler/). This uses a combination of OCaml/C++/LLVM. So not exactly what you are looking for, but definitely a valuable source of inspiration.

---

<div class="post-metadata">

**Author:** ![ygrek](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ygrek/32/268_2.png) [@ygrek](https://discuss.ocaml.org/u/ygrek)\
**Post date:** [November 28, 2022, 9:25pm UTC](https://discuss.ocaml.org/t/optimising-an-interpreter/10874/3 "2022-11-28T21:25:09Z")

</div>

> **[GitHub - stedolan/malfunction: Malfunctional Programming](https://github.com/stedolan/malfunction)**
>
> Malfunctional Programming. Contribute to stedolan/malfunction development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![bluddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bluddy/32/104_2.png) [@bluddy](https://discuss.ocaml.org/u/bluddy)\
**Post date:** [November 29, 2022, 7:43am UTC](https://discuss.ocaml.org/t/optimising-an-interpreter/10874/4 "2022-11-29T07:43:14Z")

</div>

As an interpreter, you rely fully on OCaml’s GC and runtime. You’re going to have a very hard time compiling to LLVM without a GC, runtime etc. Your best bet is Malfunction IMO.

---

<div class="post-metadata">

**Author:** ![vlaviron](https://avatars.discourse-cdn.com/v4/letter/v/ec9cab/32.png) [@vlaviron](https://discuss.ocaml.org/u/vlaviron)\
**Post date:** [November 29, 2022, 10:40am UTC](https://discuss.ocaml.org/t/optimising-an-interpreter/10874/5 "2022-11-29T10:40:57Z")

</div>

> [@Jon\_Harrop](#):
>
> If I run my interpreter as bytecode can I generate bytecode on-the-fly and have it executed? If so, how? Can malfunction do this sort of thing?

Yes, using `Dynlink`. You compile your input to a `.cmo` file, then dynlink it from your interpreter.  
It seems like Malfunction doesn’t provide any way to output `.cmo` files, but you can use it with the native version of your interpreter to produce `.cmxs` files, that you can then dynlink.

---

<div class="post-metadata">

**Author:** ![yallop](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yallop/32/517_2.png) [@yallop](https://discuss.ocaml.org/u/yallop)\
**Post date:** [November 29, 2022, 2:43pm UTC](https://discuss.ocaml.org/t/optimising-an-interpreter/10874/6 "2022-11-29T14:43:40Z")

</div>

> [@Jon\_Harrop](#):
>
> I could use MetaOCaml and do staged metaprogramming. Should be easy and achieve a very respectable speedup but MetaOCaml is obscure so I assume dev tools would no longer work?

The tools mostly work.

For example, ocamlfind (with [this package](https://github.com/ocaml/opam-repository/blob/master/packages/base-metaocaml-ocamlfind/base-metaocaml-ocamlfind.base/opam), which is installed automatically) and dune (see, e.g., this [example](https://github.com/yallop/ocaml-reex/blob/94eea88bb06be5e295627f437d7a585bd9d9b0a6/lib/dune#L8-L13)) both support MetaOCaml.

I don’t know how well Merlin works with MetaOCaml, but it might work reasonably well if you use attributes rather than quotation syntax (i.e. `(2 + 3) [@metaocaml.bracket]` rather than `.<2 + 3>.`).

Libraries mostly work unmodified (since MetaOCaml is binary-compatible with OCaml), but a few libraries conflict with MetaOCaml’s additional syntax (e.g. by using `>.` for float comparison) and need minor modifications.
