For the sake of using literate programming (i.e. cweb) in F#, I need to be able to forward declare functions (i.e. use them before defining them). I came up with two ways, both of them unpleasing. Can you think of something better (easier to use for the programmer)?
Nice, but doesn't work with polymorphic functions
// This can be ugly
let declare<'a> = ref Unchecked.defaultof<'a>
// This has to be beautiful
let add = declare<float -> float>
let ``function I want to explain that depends on add`` nums = nums |> Seq.map !add
add := fun x -> x + 1.
Ugly, but works with everything
// This can be ugly
type Literate() =
static member Declare<'a, 'b> (ref : obj ref) (x : 'a) : 'b =
unbox <| (unbox<obj -> obj> !ref)
static member Define<'a, 'b> (func : 'a -> 'b) (ref : obj ref) (f : 'a -> 'b) =
ref := box (unbox<'a> >> f >> box)
// This has to be beautiful
let rec id (x : 'a) : 'a = Literate.Declare idImpl x
and idImpl = ref null
let f () = id 100 + id 200
Literate.Define id idImpl (fun x -> x)