Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

Compiler or Language projects previously worked on

JacquesPa edited this page Nov 23, 2017 · 3 revisions

Some bugs and features that have been worked on previously:

Support extending existing object types

  • Expertise: ★★★☆☆

  • Time: ★★★☆☆

  • Mantis: None

  • Mentor: Leo

  • Who is working on this: @objmagic

  • What needs to be done: Polymorphic variant types can be used to build other polymorphic variant types:

    type foo = [ `A of int | `B of float ]
    type bar = [ foo | `C of string ]

    It would be useful to do the same thing with object types:

    type foo = < a: int; b: float >
    type bar = < foo; c: string >

    Note that this will only work for exact (closed) object types.

  • Status: Resolved

Integer range patterns

  • Expertise: ?

  • Time: ?

  • Mantis: None

  • Mentor:

  • Who is working on this: dsheets and @thizanne and @mbouaziz

  • What needs to be done: add support for char-style range for integers (int, int32, int64 and nativeint)

    let f = function
      | 0..100 -> true
      | _ -> false
  • Status: Resolved

Fix documentation of printf's treatment of width specifiers

  • Expertise: ★☆☆☆☆
  • Time: ★★☆☆☆
  • Mantis: 4799
  • Mentor: ???
  • Who is working on this: ???
  • What needs to be done: document printf's treatment of width specifiers for the format specifiers %b, %c and %a. Investigate the interaction of width specifiers with other format specifiers. See the Mantis issue for details.
  • Status: Resolved

Name clashes

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: 1956
  • Mentor: ???
  • Who is working on this: @stedolan
  • What needs to be done: Check all external names have a "caml_" prefix and add C macros for backwards compatibility.
  • Status: Resolved

Warnings-as-errors not properly flushed in the toplevel

  • Expertise: ★★☆☆☆

  • Time: ★★☆☆☆

  • Mantis: 6396

  • Mentor:

  • Who is working on this:

  • What needs to be done: If a warning marked as an error is emitted in the top-level by a phrase which also triggers a regular error, then the warning-error will instead be raised for the next phrase. For example,

    $ ocaml -w +A -warn-error +A 
            OCaml version 4.02.0+dev5-2014-04-29
    
    # class c = object   method x = 1   end;;
    class c : object method x : int end
    
    # class e = object inherit c  method x = 3 method f = 1 + "x" end;;
    Warning 7: the method x is overridden.
    Error: This expression has type string but an expression was expected of type
             int
    
    # ();;
    Error: Some fatal warnings were triggered (1 occurrences)
  • Status: Fixed by commit 837bcd6.

Allow recursive bindings with _

  • Expertise: ★★★☆☆

  • Time: ★★★☆☆

  • Mantis:

  • Mentor: Leo

  • Who is working on this: @OlivierNicole

  • What needs to be done: Currently, you cannot use _ in recursive bindings:

    # let rec _ = () and x = 3;;
    Characters 8-9:
      let rec _ = () and x = 3;;
              ^
    Error: Only variables are allowed as left-hand side of `let rec'

    This is because patterns aren't allowed there, only variables. Really _ should be considered a variable in this context.

  • Status: Rejected

Toplevel should not swallow exception in installed custom printers

# type t = A | B;;
type t = A | B
# let print_t fmt t = match t with A -> Format.fprintf fmt "A";;
Characters 20-60:
  let print_t fmt t = match t with A -> Format.fprintf fmt "A";;
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
B
val print_t : Format.formatter -> t -> unit = <fun>
# #install_printer print_t;;
# B;;
- : t = <printer print_t raised an exception>
  • Status: resolved

Fix reordering of linker options

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: http://caml.inria.fr/mantis/view.php?id=7150
  • Mentor:
  • Who is working on this:
  • What needs to be done: When invoking the linker, ocamlopt reorders the user-specified and library-embedded options, changing the order of the library search path. See the Mantis issue for more details.
  • Status: closed

Insert debug info for %revapply and %apply primitives

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: 6258
  • Mentor:
  • Who is working on this:
  • What needs to be done: No debug information is inserted for used in backtraces for %revapply and %apply primitives.
  • Status: resolved

Support [] as a constructor name

  • Expertise: ★★☆☆☆

  • Time: ★☆☆☆☆

  • Mentor: @yallop

  • Who is working on this: @objmagic

  • What needs to be done: The compact local open syntax M.() M.[] etc. makes it almost possible to override the list syntax, since [x1; x2; ... xn] desugars into x1 :: x2 :: ... xn :: [], and :: and [] are resolved in the module M. This doesn't quite work currently because [] is not allowed as a user-defined constructor name (although :: is). This change would give us convenient syntax for heterogeneous lists, for example:

    module H =
    struct
      type 'a hlist =
       [] : unit hlist
     | :: : 'a * 'b hlist -> ('a * 'b) hlist
    end
    
    let h = H.[1; "two"; false]
  • Status: merged

Add Bigarray.[kind_]byte_size functions

  • Expertise: ★☆☆☆☆

  • Time: ★☆☆☆☆

  • Mantis: http://caml.inria.fr/mantis/view.php?id=6263

  • Mentor: @yallop

  • Who is working on this: @objmagic

  • What needs to be done: Add the following functions to the Bigarray API:

    val kind_byte_size : ('a, 'b) kind -> int
    (** [kind_byte_size k] is the byte length of an element of kind [k]. *)
    
    val byte_size : ('a, 'b, 'c) t -> int
    (** [byte_size a] is [a]'s byte length. *)
    

    The function byte_size can simply be implemented by exposing the existing C function caml_ba_byte_size

  • Status: merged

Make ocamlobjinfo work with the flambda branch

  • Expertise: ★★★☆☆

  • Time: ★★★★☆

  • Issue: https://github.com/OCamlPro/flambda-task-force/issues/92

  • Mentor: Mark/Leo

  • Who is working on this: @marklrh

  • See the issue for details.

    The worst part of this is probably fixing the Makefiles. They must be fixed properly (in particular, the lists of object files making up Flambda should not be duplicated, but shared with the toplevel Makefile.shared).

    The rest is easy: in the Cmx_format.unit_infos type there is a field called ui_export_info, of type Export_info.t. The Export_info module has a printer that can be used with Format, e.g.

      Format.eprintf "%a" Export_info.print_all cmx.ui_export_info
  • Status: merged

Punning for object copying

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: None
  • Mentor:
  • Who is working on this:
  • What needs to be done: Add punning for instance variable bindings in the object copying construct. The syntax
{< x; y >}

should be equivalent to the expanded form

{< x = x; y = y >}

Document new Printexc values

Existential types for exceptions

  • Expertise: ★★★★☆
  • Time: ★★★☆☆
  • Mantis: 6219
  • Mentor: Leo
  • Who is working on this: Leo
  • What needs to be done: The syntax is apparently already supported, but type checking is not yet supported.
  • Status: This is likely to be included in the open types patch.

Improve functor syntax (1)

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: None
  • Mentor: Leo
  • Who is working on this: Thomas
  • What needs to be done: Support some lighter syntax for functors. Currently you must write functor for each functor argument using this syntax:
module F = functor (X : S) -> functor (Y : T) -> struct end;;

instead we should allow

module F = functor (X : S) (Y : T) -> struct end;;

It might also be nice to have the top-level printer output this shortened version.

Don't ignore the -o option for C files

  • Expertise: ★☆☆☆☆
  • Time: ★★☆☆☆
  • Mantis: 6475
  • Mentor:
  • Who is working on this: vbgl
  • What needs to be done: Currently ocamlc ignores the -o option for C files. For example, the following command creates code.o in the current directory, not the build directory.
  • Status: merged
ocamlc -c -o build/code.o src/code.c

The task is to take -o into account when compiling C.

Improve functor syntax (2)

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: None
  • Mentor: Leo
  • Who is working on this: Thomas
  • What needs to be done: Support some lighter syntax for functors in module types. Currently you must write functor for each functor argument using this syntax:
module type F = functor (X : S) -> functor (Y : T) -> T;;

instead we should support:

module type F = functor (X : S) (Y : T) -> T;;

It might also be nice to have the top-level printer output this shortened version.

Improve functor syntax (3)

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: None
  • Mentor: Leo
  • Who is working on this: Thomas
  • What needs to be done: Support some lighter syntax for functors in module types. Currently you must give a name to all functor arguments:
module type F = functor (X : S) -> T;;

but if you do not need to use the argument then you should not have to name it. This would mean supporting:

module type F = functor S -> T;;

In these cases it might also be reasonable to not require the functor keyword.

  • Status: a less controversial version was merged after discussion. The parentheses are still needed, but you can now use an underscore when you don't want to name functor arguments:
module F = functor (_ : X) -> struct end

Add "handler case" exception syntax

  • Expertise: ★★★☆☆
  • Time: ★★★☆☆
  • Mantis: 6318
  • Mentor: Leo
  • Who worked on this: Jeremy
  • What needed to be done: Add the following construct
try 
  expr1 
with 
  Exn -> expr2
| val p -> expr3

The semantics of this is that if expr1 raises Exn then expr2 is evaluated. Otherwise the value of expr1 is bound to the pattern p and expr3 is evaluated. Note that this allows calls in expr3 to be tail calls, which can be very useful.

  • Resolution: Patch submitted to Mantis (6318). New patch submitted after discussion on mantis.

Value printer should detect cycles

  • Expertise: ★★☆☆☆
  • Time: ★★★☆☆
  • Mantis: 6228
  • Mentor: Leo
  • Who worked on this: Stephen
  • What needed to be done: Stop the value printer (i.e. the part of the toplevel that prints values) from looping dozens of times on recursive values.
# let rec x = `Foo x;;
val x : [> `Foo of 'a ] as 'a =
  `Foo
    (`Foo
       (`Foo
          (`Foo
             (`Foo
                (`Foo
                   (`Foo
                      (`Foo
                         (`Foo
                            (`Foo
                               (`Foo
                                  (`Foo
                                     (`Foo
                                        (`Foo
                                           (`Foo
                                              (`Foo
                                                 (`Foo
                                                    (`Foo
                                                       (`Foo
                                                          (`Foo
                                                             (`Foo
                                                                (`Foo
                                                                   (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    (`Foo
                                                                    ...))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

Resolution: patch submitted to Mantis. See also the pull request on Github.

Error-enabled warnings are always on line 1

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: 6112
  • Mentor: Leo
  • Who worked on this: Raphael
  • What needed to be done: Remove the line number from error enabled warnings, or better yet, use the location of the warning itself.
$ cat error.ml
let a () = 3
let b () = 4
let c () = a(); b()
$ ocamlc -warn-error A error.ml
File "error.ml", line 4, characters 11-14:
Warning 10: this expression should have type unit.
File "error.ml", line 1:
Error: Error-enabled warnings (1 occurrences)
  • Resolution: Patch submitted to mantis

Add code_of_unix_error() to C interface of Unix module

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: 4919
  • Who worked on this: vbmithr
  • What needed to be done: add an inverse of the unix_error_of_code function to unixsupport.c, unixsupport.h and the corresponding Windows files (unixsupport.c, unixsupport.h).
  • Resolution: Extended goswin's patch to the win32 version of unixsupport.{c,h}, wrote a simple test program for it and updated the issue on Mantis.

Add command-line options to stop the compiler at certain stages

  • Expertise: ★★☆☆☆
  • Time: ★★☆☆☆
  • Mantis: 6102
  • Who worked on this: Jon Ludlam / Euan Harris
  • What needed to be done: It would be occasionally useful to stop compilation just after parsing, or just after type-checking but without outputting anything unless there are errors, etc. A regular way to support this would be to allow stopping after any phase of the compiler (or at least: parsing, typing, lambda and cmm).
  • Resolution: Wrote patch and updated the issue on Mantis

Add "-impl-suffix" and "-intf-suffix" options to ocamldep

  • Expertise: ★★☆☆☆
  • Time: ★☆☆☆☆
  • Mantis: 3725
  • Who worked on this: vbmithr
  • What needed to be done: Add "-impl-suffix" and "-intf-suffix" options to ocamldep that specify additional file extensions to be treated as ".ml" and ".mli" files respectively. This would make it much easier for ocamldep to handle generated source files. "-impl-suffix" should probably also be added to the compiler.
  • Resolution: Found that "-ml-synonym" and "-mli-synonym" already existed for ocamldep. Updated the mantis issue to reflect this. Wrote a patch to add "-impl-suffix" to the compiler and created a Mantis issue for it (6110).

Add "Filename.get_extension"

  • Expertise: ★☆☆☆☆
  • Time: ★☆☆☆☆
  • Mantis: 5807
  • Who worked on this: Jon Ludlam / Euan Harris / Mike McClurg
  • What needed to be done: The is a Filename.chop_extension function that returns the part of the filename without the extension (e.g. "foo" from "foo.mli"). A function that returned the extension would also be useful.
  • Resolution: A patch (actually two competing patches) were written and the mantis issue was updated.

Properly handle integer literals that are too large

  • Expertise: ★★☆☆☆
  • Time: ★★★☆☆
  • Mantis: 3582
  • Who worked on this: David Sheets
  • What needed to be done: currently the literal denoting the integer following the highest representable value at a particular type is treated as a negative value:
# 4611686018427387904;;
- : int = -4611686018427387904
# 9223372036854775808L;;
- : int64 = -9223372036854775808L
# 2147483648l;;
- : int32 = -2147483648l

Instead all out-of-range integer literals should be treated as errors:

# 4611686018427387904;;
Characters 0-19:
  4611686018427387904;;
  ^^^^^^^^^^^^^^^^^^^
Error: Integer literal exceeds the range of representable integers of type int

See the discussion in Mantis 3302 for why this is not entirely trivial.

  • Resolution: Xavier explicitly fixed this for int_of_string et al in 2009 but also acknowledged the lexing bug as intentional. We're not certain what the appropriate resolution is or why. See mantis for more details.

Check the return code of lseek

  • Expertise: ★☆☆☆☆
  • Time: ★☆☆☆☆
  • Mantis: 5350
  • Who worked on this: David Sheets
  • What needed to be done: check the return code of lseek in the read_trailer function and report a suitable error.
  • Resolution: Moved to close report as superfluous (regardless of codebase analysis). Xavier Leroy agreed it was superfluous, but fixed it anyway to make the code clearer (r13959).

The toplevel should have a -no-init option

  • Expertise: ★★☆☆☆
  • Time: ★☆☆☆☆
  • Mantis: 6071
  • Who worked on this: David Sheets
  • What needed to be done: Add a "-no-init" option to the toplevel that prevents loading a ".ocamlinit" file.
  • Resolution: A patch was written, submitted, and merged for a "-noinit" option to toploop and opttoploop.

Use String.unsafe_blit instead of String.blit in Buffer

  • Expertise: ★★☆☆☆
  • Time: ★☆☆☆☆
  • Mantis: 3560
  • Mentor: ?
  • Who is working on this: Philippe https://github.com/ocaml/ocaml/pull/15
  • What needs to be done: It seems that buffer already does enough checks to allow it to use unsafe_blit instead of blit. Check whether this is the case, and then either add a patch to the Mantis issue or a comment explaining why it would not be safe.
  • Status: pull request submitted

Improve error reporting for functional comparisons

  • Expertise: ★☆☆☆☆
  • Time: ★☆☆☆☆
  • Mantis: 4539
  • Mentor: ?
  • Who is working on this: @nbraud proposed a (trivial) patch
  • What needs to be done: We currently have this behaviour:
# sin < tan;;
Exception: Invalid_argument "equal: functional value".

but we'd like this behaviour

# sin < tan;;
Exception: Invalid_argument "compare: functional value".

Improve "class should be virtual" message

  • Expertise: ★★☆☆☆
  • Time: ★☆☆☆☆
  • Mantis: 6182
  • Mentor: Leo
  • Who worked on this: Stephen
  • What needed to be done: Give a more sensible error message for the case that a method is declared virtual within an immediate object. E.g.
# let o = object method virtual foo : int end;;
Error: This class should be virtual.
       The following methods are undefined : foo
  • Resolution: A patch was written and a Mantis issue created for it, and the patch was merged.

Infix constructors

  • Expertise: ★★☆☆☆
  • Time: ★★★☆☆
  • Mantis: None
  • Mentor: Leo
  • Who is working on this: Mike McClurg, Jeremy
  • What needs to be done: add support for user-defined infix constructors like (::+) or (::>). This mostly needs some small changes in the lexer and parser, as well as some simple changes to the top-level's value printer.
  • Resolution: @drup has submitted a pull request

Add support for [@tailcall] annotations

  • Expertise: ★★★☆☆

  • Time: ★★★☆☆

  • Mantis:

  • Mentor:

  • Who worked on this: @c-cube

  • What needed to be done: It's easy at present to inadvertently turn tail calls into calls that consume stack space, leading to runtime errors when the previously tail recursive code runs out of stack. For example, changing

    let rec foldl op acc = function
       [] -> acc
     | x :: xs -> foldl op (op x acc) xs

    to add an exception handler

    let rec foldl op acc = function
       [] -> acc
     | x :: xs -> try foldl op (op x acc) xs with Not_found -> assert false

    changes the function so that it's no longer tail recursive.

    Proposal: add support for an annotation [@tailcall] that causes the compiler to emit a warning when added to a non-tail call. For example, annotating the recursive call to foldl in the second implementation will result in a warning, because the call is not a tail call:

    let rec foldl op acc = function
       [] -> acc
     | x :: xs -> try foldl op (op x acc) xs [@tailcall] with Not_found -> assert false

    The suggested implementation technique is to propagate the annotation through the compiler until the point at which the tail call is detected (e.g. when APPTERM rather than APPLY is emitted).

  • Status: Pull request merged

Clone this wiki locally