Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007770OCamltoplevelpublic2018-04-11 12:042018-04-16 15:43
Assigned To 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0007770: Improved API for toplevel printers
DescriptionThe current API for toplevel printers is not particularly convenient. It either require manual work from the user or ocamlfind predicate tricks.
One potential solution would be to annotate type declarations:

  type foo = ...
  [@@printer pp_foo]

When the toplevel tries to print an object of type foo, we lookup the definition, find the annotation, and that's it.

This ticket aims to discus the design of this before I start implementing it. There are various potential choices. `pp_foo` will be almost always declared *after* the current module, so we can't really typecheck at declaration time.
1. We assume `pp_foo` is local to the current module and we check its type once we are done with the rest of the module.
2. We don't typecheck anything statically and instead check dynamically, just like `#install_printer`. This solution also allows printers that are not local to the current scope (as long as they are in scope for printing, it's fine).
3. We wait for modular implicit, which provide a similar solution to the problem.

Opinions ?
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
dbuenzli (reporter)
2018-04-11 14:20

Nice to look at this Garbiel ! Can be related to [^] point 5.

I guess these annotations will go in cmis ? Didn't think it through but what about annotating the pretty printer with the type instead ?

If two annotations declare the same type the last one loaded takes over. This also has the advantage of being able to override or provide alternate pretty printers by simply loading a cmi.
dbuenzli (reporter)
2018-04-11 14:28
edited on: 2018-04-11 14:31

In fact I guess you don't even need to specify the type. You'd just have an [@@toploop] annotation and any function that sports this annotation when a cmi is loaded automatically given to #install_printer. Not sure if that's feasible though.

EDIT That's actually what Jérémie suggested here: [^]

drup (reporter)
2018-04-11 14:42

I didn't know jeremy got the same idea. Yes, the annotations would go in the cmis.

I'm not very convinced by the idea of annotating the printers since module types are loaded lazily in OCaml, in particular with module aliases.

Basically, if you have a Foo_printers module, or even Foo.Printers where Printers is a module alias, unless the cmi is loaded by other means (like calling Foo_printers.pp explicitly), the printer annotation will never be seen.
Annotating on the type avoids the issue.
Having your printers depend on which cmi the typechecker decided to load seem very unfriendly to me.

As far as order of printer is concerned, I would go like this:
- Starts from the type proposed by -short-alias
- For each type alias, try to find a printer at the type definition, if unsuccessful, resolve *one* layer of alias, and try again.
frisch (developer)
2018-04-11 18:15

An alternative approach would be to use some naming convention (deriving-like). For a value of a type [Foo.Bar.my_type], the toplevel would look e.g. for a printer
called [print_my_type] of type [Format.formatter -> Foo.Bar.my_type -> unit] in module [Foo.Bar].

This is a bit ad hoc but for the toplevel this might be ok.
drup (reporter)
2018-04-15 14:21

firsch: That's strictly less powerful than 1, and not much easier to implement. It's also far less flexible/retro-compatible. It doesn't even really help all that much for a future migration to a modular implicit based approach.
dim (developer)
2018-04-16 13:58

The reason I suggested annotating the printer rather than the type is that if you annotate the type, you end up typing the printer identifier twice. It seems to me that toplevel printers are generally defined in the same module as the types themselves, so the typer should see them.
drup (reporter)
2018-04-16 15:43

dim: This means you have one reasonable case (printer is local) and the other cases which might or might not work depending on the whims of the typechecker. I think it makes more sense to either support that one good case (proposition 1) or all the cases (proposition 2).

- Issue History
Date Modified Username Field Change
2018-04-11 12:04 drup New Issue
2018-04-11 14:20 dbuenzli Note Added: 0019010
2018-04-11 14:28 dbuenzli Note Added: 0019012
2018-04-11 14:31 dbuenzli Note Edited: 0019012 View Revisions
2018-04-11 14:42 drup Note Added: 0019013
2018-04-11 18:15 frisch Note Added: 0019014
2018-04-15 14:21 drup Note Added: 0019033
2018-04-16 13:58 dim Note Added: 0019038
2018-04-16 15:43 drup Note Added: 0019039

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker