Installing OCaml under openSUSE 11.4, or: “the compilation of conf-ncurses failed”

Recently I decided to learn the basics of OCaml and I spent yesterday installing the compiler and some basic tools. On my machine at work I have a Debian 7 installation, while on my home laptop I have openSUSE 11.4. Both systems are quite dated and ship with OCaml 3.x compiler, which is five years old. Obviously, I wanted to have the latest version of the language. I could have compiled OCaml from sources – and in fact I have done that in the past to compile the latest version of Coq – but luckily there is a tool called OPAM (OCaml Package manager). OPAM can be used to easily download and install desired version of OCaml compiler. As the name implies, OPAM can be also used for managing packages installed for a particular compiler version.

The installation process went very smooth on my Debian machine, but on openSUSE I have run into problems. After getting the latest compiler I wanted to install ocamlfind, a tool required by a project I wanted to play with. To my disappointment installation ended with an error:

[ERROR] The compilation of conf-ncurses failed at "pkg-config ncurses".
This package relies on external (system) dependencies that may be missing.
`opam depext conf-ncurses.1' may help you find the correct installation for your 

I verified that I indeed have installed development files for the ncurses library as well as the pkg-config tool. Running the suggested opam command also didn’t find any missing dependencies, and the log files from the installation turned out to be completely empty, so I was left clueless. Googling revealed that I am not the first to encounter this problem, but offered no solution. I did some more reading on pkg-config and learned that: a) it is a tool that provides meta-information about installed libraries, and b) in order to recognize that a library is installed it requires extra configuration files (aka *.pc files) provided by the library. Running pkg-config --list-all revealed that ncurses is not recognized as installed on my system, which suggested that the relevant *.pc files are missing. Some more googling revealed that ncurses library can be configured and then compiled with --enable-pc-files switch, which should build the files needed by pkg-config. I got the sources for the ncurses version installed on my system (5.7) only to learn that this build option is unsupported. This explains why the files are missing on my system. I got the sources for the latest version of ncurses (6.0), configured them with --enable-pc-files and compiled, only to learn that the *.pc files were not built. After several minutes of debugging I realized that for some unexplained reasons the configure-generated script which should build the *.pc files (located at misc/gen-pkgconfig) did not receive +x (executable) permission. After adding this permission manually I ran the script and got five *.pc files for the ncurses 6.0 library. Then I had to edit the files to match the version of ncurses of my system – relevant information can be obtained by running ncurses5-config --version. The only remaining thing was to place the five *.pc files in a place where pkg-config can find them. On openSUSE this was /usr/local/pkgconfig, but this can differ between various Linux flavours.

After all these magical incantations the installation of ocamlfind went through fine and I can enjoy a working OCaml installation on both of my machines. Now I’m waiting for the “Real-world OCaml” book ordered from Amazon (orders shipped from UK Amazon to Poland tend to take around two weeks to arrive).

Typed holes support in Template Haskell

Back in April I found myself in a need for typed holes in Template Haskell. To my disappointment it turned out that typed holes are not implemented in TH. Sadly, this happens too often: a feature is added to GHC but no Template Haskell support is implemented for it. This was the time when I was working on injective type families and I already had some experience in extending TH implementation. I figured that adding support for typed holes should be a trivial task, no more than 30 minutes of coding. I created a feature request on Trac and started coding. I quickly realized that it won’t be that simple. Not that the amount of required work was that extensive. I simply tripped over the way GHC handles names internally. As a result the work got stalled for several months and I only finished it two weeks ago thanks to help from Richard Eisenberg.

My patch allows you to do several interesting things. Firstly, it allows to quote typed holes, ie. expressions with name starting with an underscore:

[d| i :: a -> a
    i x = _ |]

This declaration quote will represent _ using an UnboundVarE constructor. Secondly, you can now splice unbound variables:

i :: a -> a
i x = $( return $ VarE (mkName "_") )
j :: a -> a
j x = $( return $ UnboundVarE (mkName "_") )

Notice that in a splice you can use either VarE or UnboundVarE to represent an unbound variable – they are treated the same.

A very important side-effect of my implementation is that you can actually quote unbound variables. This means that you can now use nested pattern splices, as demonstrated by one of the tests in GHC testsuite:

baz = [| \ $( return $ VarP $ mkName "x" ) -> x |]

Previously this code was rejected. The reason is that:

  1. nested pattern splice is not compiled immediately, because it is possible that it refers to local variables defined outside of the bracket;
  2. the bracket is renamed immediately at the declaration site and all the variables were required to be in scope at that time.

The combination of the above means that the pattern splice does not bring anything into scope (because it is not compiled until the outer bracket is spliced in), which lead to x being out of scope. But now it is perfectly fine to have unbound variables in a bracket. So the above definition of baz is now accepted. When it is first renamed x is treated as an unbound variable, which is now fine, and when the bracket is spliced in, the inner splice is compiled and it correctly brings binding for x into scope. Getting nested pattern splices to work was not my intention when I started implementing this patch but it turned out we essentially got this feature for free.

One stumbling block during my work was typed Template Haskell. With normal, untyped TH I can place a splice at top-level in a file:

$$(return [
   SigD (mkName "m")
        (ForallT [PlainTV (mkName "a")]
                 (AppT (AppT ArrowT (VarT (mkName "a"))) (VarT (mkName "a"))))
 , FunD (mkName "m")
        [Clause [VarP (mkName "x")] (NormalB (VarE (mkName "x"))) [] ]

and this will build a definition that will be spliced into the source code. But converting this into a typed splice, by saying $$(return ...., resulted in compiler panic. I reported this as #10945. The reason turned out to be quite tricky. When Template Haskell is enabled, top-level expressions are allowed. Each such expression is treated as an implicit splice. The problem with typed TH splice is that it doesn’t really make sense at the top-level and it should be treated as an implicit splice. Yet it was treated as an explicit splice, which resulted in a panic later in the compiler pipeline.

Another issue that came up with typed TH was that typed holes cannot be quoted, again leading to panic. I reported this as #10946. This issue has not yet been solved.

The above work is now merged with HEAD and will be available in GHC 8.0.

Week at ICFP: Injective Type Families merged into GHC HEAD

I spent last week at Vancouver, Canada attending Haskell Implementors Workshop, ICFP and the Haskell Symposium. Yesterday I gave a talk on injective type families, described also in my previous post. Slides are on my web page but the talk itself is not yet online. Day prior to the talk I finally managed to merge the injective type families branch, which means that this feature is definitely making it into the next stable release of GHC. (In case you haven’t heard this will be GHC 8.0, not 7.12.)

My next plans include extending injective type families to fully match expressiveness of functional dependencies, as outlined in Section 7.2 of the injectivity paper. I also hope to finally implement support for typed holes in Template Haskell. The patch was supposed to be trivial and I started working on it several months ago. But then I ran into several problems with it and abandoned it to focus on ITFs.

Staypressed theme by Themocracy