Announcing Scrod, like Haddock but faster

Direct link to web app playground: https://scrod.fyi

Direct link to release with binaries and other assets: Release 1.0.0.0 · tfausak/scrod · GitHub

17 Likes

:wave: Trading off speed for accuracy is an interesting idea. I suppose worse implies:

  • no name resolution and therefore no automatically generated hyperlinks,
  • no type checking and therefore no type inference when function type signatures are missing.

Is this an accurate assessment?

1 Like

Yup, that’s exactly right!

For name resolution, Scrod has enough information to guess, but it can’t tell for certain. So it doesn’t even try. But in theory something consuming Scrod’s output could try to do ad hoc name resolution using the list of imported modules.

Another consequence of no type checking is that the module may not even compile! This is actually really useful with the VSCode extension, because you can preview documentation while you’re editing a module (as long as there are no parse errors, of course).

3 Likes

This is good!
We should move haddock out of GHC tree so we can have alternatives likes these.

Didn’t Haddock recently move into GHC?

At any rate, Scrod only depends on haddock-library. I didn’t feel like it being part of GHC was an issue.

1 Like

well, it was a while ago haha. Hope I can do some work on haddock at zurich hack

2 Likes

This is very cool. Haddock currently has an open issue which makes it incompatible with Liquid Haskell. Make verification succeed with haddock enabled · Issue #2188 · ucsd-progsys/liquidhaskell

Does it happen to work with LH if I drop haddock comments?

Ah, I didn’t think to test with Liquid Haskell. Without actually trying, it should work. Scrod doesn’t run plugins at all. The GHC options for enabling them are simply ignored. And my understanding is that LH annotations are comments like {-@ … @-}, which would also be ignored.

Here’s an example showing that the LH plugin and annotations are ignored: Scrod

2 Likes

I have been using Scrod to help document some of my recent work - the immediate visual feedback is incredibly helpful and completely removes the pain of having to 1) rebuild docs 2) relaunch the server 3) reload the web page just to see your changes. :smiling_face_with_three_hearts:

if I could offer some positive feedback? Improve support for the module descriptor - if I do this:

{-|
Module      : TheModule
Description : Synopsis
Copyright   : (c) 2026 Some Person
License     : BSD-3
Maintainer  : me@my.com
Stability   : experimental
Portability : POSIX

Full description
-}

It just sort of mashes all of the attributes on a single line, and it seems to render it like regular documentation text instead of recognizing the first stanza as potentially being the module stanza.

2 Likes

Sure, I’ll add that. Issue here: Support module description fields · Issue #357 · tfausak/scrod · GitHub

I’ve never really understood the point of those module headers though. Module is redundant, it’s just the module name. Description is also redundant, it’s just the module documentation. Copyright, License, and Maintainer duplicate the same fields in the package description (Cabal file). Stability has been hilariously useless everywhere I’ve seen it, like Control.Monad saying it’s “provisional”. And same for Portability; somehow Control.Exception is “non-portable”?

Also syntactically it’s annoying. Why use a custom syntax just for these fields, when there’s a perfectly good definition list syntax: [term]: definition?

Anyway, rant aside this should be relatively simple to implement.

3 Likes

Heh perhaps I never realized how useless they are before, because I have not done enough Haddock documentation, because I have not had an ergonomic tool to use…

1 Like

Works now :slight_smile: Scrod

2 Likes

Oh, maybe it could work with MicroHs.

1 Like

Currently Scrod is tightly coupled to GHC. I think it would be possible to build something similar around MicroHs. Hopefully the GHC stuff is pretty well quarantined in Scrod’s codebase, but I designed it to only support GHC.

Would it be possible to completely ignore function bodies, as these are IIRC never used in documentation? Because then, parse errors in function bodies wouldn’t be an issue.

I’d imagine this improving the developer experience when using it in VSCode or HLS or some such.

It might be possible in theory, but I don’t think GHC’s parser can be convinced to do that. Also Scrod does use the function body (to get the parameter names, if they exist). For example: Scrod

Oh snap! Haddock doesn’t do that, does it? :thinking: Can you annotate arguments?

Though it’s still only the section before the =, so the RHS of the function definition isn’t actually used. I wonder if that could be done, somehow. Even if a completely different parser has to be created.

What Haddock needs is more involved, but - anecdotally - I first tried to write graphex’s parser using the GHC parser. But that was a pain in the butt, so I just wrote something for what graphex needs (imports) using megaparsec in a quick sitting.

I definitely am glad I went that way. I didn’t consider it, but not failing when irrelevant stuff is borked is a nice side effect.

1 Like

Nope! As far as I know, Haddock does not retain function arguments at all.

I don’t think so. You can document their types, of course. I think any documentation connected to the binding itself is simply dropped by GHC.

This line of thinking reminds me of Kmett’s Coda and monoidal parsing: Reddit - The heart of the internet

I did consider going down this route for Scrod. However I wanted to leverage GHC (and Haddock) as much as possible to avoid another haskell-src-exts situation where Scrod handles things differently than GHC and I’m constantly trying to fix the problems.

1 Like