Skip to content
This repository has been archived by the owner on Aug 3, 2024. It is now read-only.

--show-interface appears to be encoded in Json, but the doc part is raw Haskell show output! #920

Closed
kindaro opened this issue Aug 26, 2018 · 8 comments

Comments

@kindaro
Copy link
Contributor

kindaro commented Aug 26, 2018

Try it yourself:

Consider the following example module:

module Example where

-- | I am a comment.
--
-- >>> I am an example.
-- I am the result.

c = undefined

Let us obtain a Json representation of its haddock:

% haddock --dump-interface=Example.interface Example.hs
% haddock --show-interface=Example.interface 2> Example.interface.json
% cat Example.interface.json | jq

What we will see is this:

{
  "link_env": {
    "$main$Example$c": "Example"
  },
  "inst_ifaces": [
    {
      "module": "$main$Example",
      "is_sig": false,
      "info": {
        "description": null,
        "copyright": null,
        "maintainer": null,
        "stability": null,
        "protability": null,
        "safety": "Safe",
        "language": null,
        "extensions": []
      },
      "doc_map": {
        "$main$Example$c": {
          "meta": {
            "version": null
          },
          "doc": "DocAppend (DocParagraph (DocString \"I am a comment.\")) (DocExamples [Example {exampleExpression = \"I am an example.\", exampleResult = [\"I am the result.\"]}])"
        }
      },
      "arg_map": {},
      "exports": [
        "$main$Example$c"
      ],
      "visible_exports": [
        "$main$Example$c"
      ],
      "options": [],
      "fix_map": {}
    }
  ]
}

Everything looks nice and tidy, except that the doc section appears to be a show output. Upon inspection, indeed:

Haddock.Interface.Json

    ...
 63                                                                                                      
 64 jsonDoc :: Doc Name -> JsonDoc                                                                       
 65 jsonDoc doc = jsonString (show (bimap (moduleNameString . fst) nameStableString doc))                
 66                                                                                                      
    ...

I do not exactly understand what the bimap is doing, but I am certainly unhappy with the overall approach.

Why is it a problem:

I want to programmatically access the contents of haddocks. From the fact that --show-interface outputs Json, I had an impression that it promises cross language interoperability. But hardly can I make a use of the doc field as it is currently presented, with Haskell-specific syntax.

  • At the very least, if my program is in Haskell, it means that I need to depend on a specific version of haddock-library (from which, as I researched, the string originates) or maintain a duplicate of a 27 constructor long data type.
  • If my program is in another language, I am in for writing a parser for this same 27 constructor long data type.
    • Actually, I am in for some trouble anyway, since DocH is not an instance of Read. But with Haskell, I could probably standalone derive it.

What can be done:

I see two ways we can go from here:

A. Write a more comprehensive jsonDoc function, and even a jsonDocH function to accompany it.

  • Pros:
    • Everything is Json.
  • Cons:
    • If any program was somehow managing to use this field, it will break
      • But recall that this field is currently not machine readable.

B. Write or derive an instance Read DocH.

  • Pros:
    • The output does not change, thus backwards compatibility is 100%.
  • Cons:
    • Ugly.
    • DocH representation may change at any time.
    • Hard to parse with other languages.
    • Forces the dependency on haddock-library.

C. Do nothing, wontfix.

  • Pros:

    • Nothing has to be done.
  • Cons:

    • Same as B.

I am anxious to hear from the maintainers. If there is consensus, I can craft a pull request in no time.

@harpocrates
Copy link
Collaborator

I doubt anybody's actually programmatically using the DocH part of --show-interface. The output is mainly used by people trying to debug interfaces (since haddock interface files are otherwise not human readable). I'd personally be slightly inclined toward option A - although that is likely to make manually reading the JSON a bit harder.

I want to programmatically access the contents of haddocks. From the fact that --show-interface outputs Json, I had an impression that it promises cross language interoperability. But hardly can I make a use of the doc field as it is currently presented, with Haskell-specific syntax.

I think the right way to do this is via readInterfaceFile (exported by haddock-api). Why not go through that (and read the binary interfaces directly)?

@kindaro
Copy link
Contributor Author

kindaro commented Aug 27, 2018

@harpocrates Thank you for answering, Alec!

why not read the binary interfaces directly   I want a single compiled instance of my application to work across multiple versions of Haddock. So, I would much rather call the haddock executable as necessary, and make a best effort at parsing what it says, than nail my build to a particular version of haddock-api.

on manually reading the json   I do not understand why you think that "manually reading the JSON" will be harder when it is actually JSON, rather than some arbitrary mix of JSON and internal representation. Can you elaborate on this? Actually, do you mean "manually writing a JSON parser" or "human reading JSON from screen"?

on my further action   What is my further action? Do I need to wait for more commentary, or should I start working on option A?

@harpocrates
Copy link
Collaborator

Actually, do you mean "manually writing a JSON parser" or "human reading JSON from screen"?

More of the latter. I use --show-interface with jq to extract sub-components of the interface file dump. I've never been interested in programmatically exploring the structure of a DocH, so its show is a good enough semi-compact representation.

I think you should wait for @alexbiehl's take on this.

@kindaro
Copy link
Contributor Author

kindaro commented Jul 10, 2019

@alexbiehl @harpocrates I am waiting, but it has been almost a year!

@harpocrates
Copy link
Collaborator

harpocrates commented Mar 30, 2020

@kindaro I think it is safe to say no one else is going to comment. I personally think we should go with option A. Even when I debug with them (JSON dumps of interface files), it is programmatic. Are you still interested in doing this?

@kindaro
Copy link
Contributor Author

kindaro commented Mar 30, 2020

@harpocrates  Better late than never! It is not at the moment my highest priority, but I promise to create a pull request within a month from now.

@kindaro
Copy link
Contributor Author

kindaro commented Apr 9, 2020

@harpocrates  Delivered! See #1159.

@harpocrates
Copy link
Collaborator

Fixed in d8aaaba.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants