[compiler-hacking] useful feature?

Leo White lpw25 at cam.ac.uk
Fri Oct 17 14:05:18 BST 2014


> Hi all, not sure if this is a valid suggestion for a feature that could be tackled during one of the the compiler
> hacking sessions. (It's more to do with Lwt than the compiler.)
>
> The problem was described by Thomas under "Error handling in key look-ups" at
> http://roscidus.com/blog/blog/2013/11/28/asynchronous-python-vs-ocaml/
>
> The problem occurs when "try..with" is used instead of the Lwt counterparts for handling exceptions.

This certainly seems a valid suggestion for the compiler-hacking
sessions. I also think that this list is a good place to discuss such
suggestions, so thank you for starting us off with an interesting one.

> My idea consists of emitting a warning each time the following two conditions are both met:
> 1. if we have an AST that contains "try EXP with (VAR, EXP')+", and
> 2. the type of EXP, and the type of each EXP' is "tp Lwt.t" for some type tp.
>
> I'm not sure if this is entirely reasonable or useful, nor can I judge how difficult it is to implement since I don't
> know what the codebase looks like, but thought I'd offer it up for your judgement.

Firstly, you don't want to add specific knowledge of Lwt to the compiler
itself, so the feature would need to be something more general which
could be triggered by Lwt's camlp4/ppx preprocessor.

The basic thing that you are suggesting is a way to tell the compiler:
"if this expression has the type `foo` then please warn me". You could
imagine supporting this through an attribute like:

    (try
        ...
    with Not_found -> ...) [@warn_if_type: 'a Lwt.t]

which could be inserted on all try expressions by the Lwt camlp4/ppx
preprocessor.

The first difficulty with this is deciding what it means for an
expression to have type `'a Lwt.t`. Does it mean "could be `'a Lwt.t`" or
"definitely has type `'a Lwt.t`"? This matters because
polymorphism/abstraction means we cannot always tell whether or not
something has type `'a Lwt.t`.

Consider the function

    let f (g : unit -> 'a) =
      (try
          g ()
      with Not_found -> raise Invalid_argument) [@warn_if_type: 'a Lwt.t]

Should this emit the warning or not? If it does then there will be many
false positives, but if it doesn't then you will not detect cases like:

    f (fun () -> return 5)

which clearly does wrap an `'a Lwt.t` in a regular exception handler.

Similarly module abstraction prevents you knowing whether or not an
expression has type `'a Lwt.t`. For example:

    module M : sig
      type 'a t
      val x : int t
      val f : int t -> int t
    end = struct

      type 'a t = 'a Lwt.t

      let x = return 1

      let f x =
        Lwt.bind x
          (fun x ->
             if x <= 1 then raise Not_found
             else return (x - 1))

    end

    let y =
      try
        M.f M.x
      with Not_found -> M.x

Here again we have wrapped an Lwt.t in a regular exception handler, but
cannot tell that we have done.

It is quite possible that real Lwt code does not encounter these
problems, or that the warning is still useful even though it is not 100%
accurate, but these kinds of issues should probably be considered before
attempting to implement something.

Regards,

Leo


More information about the Cam-compiler-hacking mailing list