I want to start working on a little compiler and to build it I am hesitating between several different languages.
My requirements are simple, I want to be able to emit LLVM-IR code cause I have a LLVM backend I would like to reuse to target a specific platform.
So right now I have the following choices :
Use OCaml and the LLVM bindings - Efficient, LLVM ships with the OCaml bindings, but the coding experience with OCaml (IDE, support) is not the best.
Use C/C++ and the LLVM bindings - The most obvious way I would say, but I would like to use a functional language as this topic is new to me and I want to learn something new.
Use F# - I felt in love with this language, but there are no official LLVM bindings. So I guess I could do the same through the use of System.Reflection.Emit. Even though it seems like there is an initiative here for F# binding for LLVM - https://github.com/keithshep/llvm-fs
I would love to get your thoughts on this.
Metaprogramming is a real weak point of C++. Most of your effort will be expended trying to manipulate trees. The core advantage of OCaml and F# in this context is pattern matching over union types (and not functional programming) precisely because this makes it so much easier to manipulate trees. Historically, OCaml and F# come from the ML family of languages and were bred specifically for this application domain.
I used LLVM via its OCaml bindings to write HLVM, which includes both standalone and JIT compilation to native code, multicore-capable garbage collection, foreign function interface, tail call optimization and many other features. The experience was very pleasant. My only advice would be to keep track of which LLVM features are tried-and-tested and which are experimental because you don't want to depend on anything experimental (e.g. the GC support when I wrote HLVM).
You can easily use System.Reflection.Emit
to generate CIL from F# but you obviously won't be able to leverage your LLVM backend by doing so, although you do get a garbage collector for free, of course. .NET bindings to LLVM are an option. I am not familiar with the ones you cite but writing bindings to LLVM's C API is relatively straightforward. However, I am not sure how well supported LLVM is on the Windows platform.
Regarding OCaml vs F#, both have advantages and disadvantages but I'd say the overall difference is relatively small in this context. Writing functions to print values of big union types due to the lack of generic printing is tedious in OCaml, although this can be automated using some third-party macros. F# provides generic printing but is missing some useful features such as polymorphic variants and structurally-typed objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With