Talk at Func Prog Sweden

Hi,

Here’s a link for the talk I gave at the Func Prog Sweden meetup. In that talk I show the process we follow some years ago in order to move all our code base to OCaml and why it was an excellent decision.

EDIT:

Wolfram System Modeler is a simulation environment that can be used to model multi-domain systems. For example systems composed of electrical, thermal, hydraulic, mechanical, etc, components.

One of the main parts of System Modeler is the model compiler (Kernel) which takes models written in the Modelica language and compiles them into efficient simulation executables. This compiler was ported to OCaml by using custom tool that performed the code to code translation of our old code base.

Slides https://a2076202-c90b-450e-901b-cb56c346913c.usrfiles.com/ugd/a20762_adfa899586c7413a8c17f7b708dbc177.pdf

Best regards.

10 Likes

Note that it may not be obvious to some of us what the “System Modeler” is. Would you mind adding a bit of context ?

Yes. I have expanded the original post.

1 Like

Thanks for the talk! Would you by chance have the slides uploaded somewhere?
(I read the slides from the Youtube video, but this is less convenient.)

One take-away of the talk is that OpenModelica is not such a good implementation language: it’s verbose, not so expressive, lacks a lot of tooling, etc. The lack of expressiveness can be easily explained from the fact that it is an offspring of a declarative language designed for modelization and simulation, not general-purpose programming. The lack of tooling comes naturall for a custom language with a small userbase. But two natural questions come up:

  1. Assuming other OpenModelica users may be interested in porting their code, are the code-translation tools you developed openly available? (Are there other OpenModelica codebases that could be interested?)
  2. Wolfram System Modeler takes the simpler Modelica language has input. Would it make sense to consider a different modelling language that is closer to standard functional programming?

(Two related ideas come to my non-expert mind:

  1. Zelus, as an existing, modern language design for hybrid system modelling. It is inspired by synchronous-dataflow languages rather than functional languages, so probably nicer than a functional language for low-level process modelling and worse to express symbolic manipulations.
  2. Restricted functional languages for verification and simulation have been proposed for various problem domain, for example recently Imandra for the financial domain.

)

1 Like

It seems like I cannot attach the slides here because PDF files are not allowed. If you send me an email address in a private message I can send you the slides.

Yes. When using MetaModelica for general purpose programming one can feel the verbosity. However, when using Modelica for making models it does not feel very verbose. Specially because most of the modeling is done graphically by connecting components. Only when one develops textual custom components one has to write code.

We did not publicly released the tools. The projects that used the MetaModelica (v1) language have moved to MetaModelica (v2). My tools only worked for the v1 of the language. At this point, most probably there’s no project still using v1.

There are a few modeling languages that follow a more functional approach. However, for the creation of models, we support Modelica because is a more widespread language supported by many tools. Thanks to the integration with the Wolfram Language, it is possible to create models programmatically using functional features and then generate Modelica code. One of those examples is when designing control systems with the Wolfram Language and generating Modelica models.

I have had the pleasure of meeting some of the persons behind Zelus. It is an interesting project.

can you drop them on any webspace and post the URL here?

@gasche @mro

I have added a link with the slides in the original post.

1 Like

Thank you for this talk. I was intrigued by your mention of ocamldebug and how you used it to hunt down bugs using reverse execution.

As you know, OCaml does type erasure so polymorphic data structures are difficult to debug in ocamldebug. You would just see <poly> in a lot of places. How did you get around that limitation because there is a lot of polymorphism in practice in OCaml codebases. What about your codebase?

Also it is not possible in practice to run ocamldebug in many situations because of a dependency which might indirectly depend on the threads library. (BTW the situation has improve a bit with Support debugging multithreaded programs until they create threads by xavierleroy · Pull Request #10594 · ocaml/ocaml · GitHub ). How did your large project manage to remain ocamldebug-able ?

In our code base, we have different types of errors. The simplest is, for example, when the user creates an incorrect model, an error is raised and reported in a friendly way for the user. For all other unforseen situations we raise an exception. When the user runs the product, all these exceptions are catch and they display an “internal error” message. Since we have a single point where this exceptions are catch, it is very easy to disable the catch. So we have a flag that will make our program not catch the exceptions when debugging. When there are uncaught exceptions, ocamldebug stops in the place where the exception was thrown. Then we just have to back step a bit to figure out which conditions lead it to raise the exception.

Yes the <poly> makes more difficult to see the values in the debugger. To debug these cases I usually create data printers, either with ppx_deriving when possible or if I need something more simplified I use a small library I made called Pla which helps me create printers in a simple way. For most data structures we have some kind of printer. I usually place a print at the place I want to see and recompile + rerun the debugger. In ocamldebug you can see the “time”, I copy that value and in my rerun I just put a goto time or a break to go back to the place where I was before.

We do not use threads and we don’t use too many external libraries. Initially, our code base depended only on the standard library.The main reason was that, back when we started with OCaml, it was difficult to get many of the libraries to compile in Windows using the VS port. Since we converted all our code, that included all the libraries an utilities we required. As the time passed, we started integrating other libraries, for example containers, menhir, ppx_deriving, pla and dune. Those are probably all the libraries that we depend on for building the product. In the development computers we install ocamlformat and ocaml-lsp-server.

Other trick we use to simplify debugging is that we have organized the code in a way that it allows multiple entry points. For example, our compiler has different stages: stage1 -> stage2 -> stage3 -> stage4. If we have detected an error in stage4 we can easily export the input data to that stage (using Marshall). Then we can run only the stage4 though it’s custom entry point. That way we skip the stepping of the debugger on all the other stages which can be slow.

2 Likes