I would like to propose an alternative compilation structure for building F# projects. I’m currently calling it an F# manifest, though the actual idea is less focused on the creation of a single file and rather on a different, language-first approach to building projects. My idea stems from a technique I’ve started using more regularly and that I’ve seen from Tomas Petricek. This technique uses compiler directives for toggling
#load commands for F# Interactive. Using these, you can typically run a script or compile and run an executable. The overall process would roughly appear as follows:
- Look for a Main.fs or Manifest.fsx file.
- If a Manifest.fsx file doesn’t exist, generate the Manifest.fsx from
- Do this for all referenced files so that the Manifest.fsx lists the dependencies for the primary script
- Search for references without a path in the local directory, then the GAC, and finally NuGet
Why an alternate build system?
Today I saw a question about docs for F#x on the F#x mailing list. The first reply, from Art, referenced Tomas’ FSharp.Formatting project. I hadn’t seen Tomas’ project in some time, so I went to check it out. The last I looked at it, FSharp.Formatting provided a Markdown parser. Tomas has extended it to cover a much larger feature set, including a version of literate programming. Literate programming was the ultimate goal of my halted focco project. As I had always intended of pulling in several of Tomas’ other projects to finish focco, and FSharp.Formatting now provides many of those features, I will now be moving what I can from focco over to FSharp.Formatting.
That was what I had originally planned to write about. Instead, worn out from the holidays, I lost focus and instead started thinking too much about true literate programming. (Disclaimer: I have not investigated Tomas’ implementation in any detail, so some of what follows may be inaccurate.) Knuth’s idea of “literate” programming allow programmers to write for people and use a tool to strip out the code and re-organize it for the computer. This sort of thing is more necessary in languages such as F# and Pascal you must first declare a procedure or function before you can use it. Neither focco nor FSharp.Formatting currently addresses this.
Before literate programming in F# is really possible, we need a build system that can work more directly from raw files. Well, that’s not entirely true, but I’ve long wished to see less XML and more F# in my F# builds.
Is this really a necessity to literate programming in F#?
No, of course not. I just found myself thinking through all this and thought I would write it down for posterity. If I really thought it necessary, I would have instead started writing some code to feel this out. Instead, I’m planning to get some sleep and try to focus and get F# project support added to FSharp.Formatting. Once that is done, we’ll see about allowing a mechanism to allow authors to list their code in an arbitrary manner and then reassemble it. And after that, maybe a look at a new build system is in order.
And no, I haven’t forgotten about FAKE. If nothing else, I would probably make this an optional extension via FAKE. Then again, you can already do some of this with a single .fsx script several loose .fs files, and some assemblies.