It's been about six months since I blogged about Fing. I've only touched the code a couple of times since then, so I will restart the series by describing the module organisation as it stands today, in the process of developing version 0.2
Fortunately, I wrote all this down six months ago on the fing github wiki, so if you want the details, including module contents, look there. This is a module-level overview.
Util
Utilities. That usually means: utilities that ship with Haskell but not with F#.
Types
The basic types, plus basic operations on them: fold, map, string formatting.
Everything below this line depends on Util and Types (except for Opt).
ParsedTypes
string → internal type representation. For example, user entered types.
FSharpTypes
F# Powerpack Metadata → internal type representation.
CSharpTypes
C# Reflection representation → internal type representation. This is not implemented yet; maybe it should be called DotNetTypes instead.
Search
Search for functions matching a given type.
Everything below this line depends on everything above this line (mostly).
Fing
The public interface: string → list<result> and related operations.
Opt
Command line parsing. I can't believe this isn't part of the standard library.
Program depends on Fing and Opt
Program
Command line interface. To be augmented later by other kinds of interfaces, probably an ASP one next.
Most of my time so far has been refactoring and working on the woefully incomplete tests. Earlier I made a conscious decision to push out a number of features without testing so that I'd have something people could use. Now I'm coming back through and writing the missing tests.
My approach was to build a decent database of types for testing. Most of my tests then assert that a property holds about all the types. This is a lot like QuickCheck, but without the random generation. I personally think it serves me better, because I manually generated all the complex cases of the grammar without recursion on the obvious cases. I could be missing stupid-simple cases, of course. (Also I didn't want to mess with installing F#'s port of QuickCheck—without typeclasses, I assume that it's kind of klunky and painful.)
For example, my newest test asserts that, for all types, if you shuffle the order of type variables, then run Types.index, you will get the original type back. This holds because (1) Types.index overwrites type variables with ones in canonical order and (2) all my test cases were manually created with type variables in canonical order. Actually (2) is a bad idea; it's OK for parser testing but is overly simple when you start testing semantics.
The more I think about it, the more I think I may need something like QuickCheck, at least some hacky fuzzing of my existing, over-regular test cases. That should probably be the next major step in the testing of the code, even if F# Quickcheck is painful to install.