The following 2 functions
let episodeDict1 (a: obj) =
match a with
| :? (Episode -> _) as generator ->
let episodes = [D; W; M]
let values = episodes |> List.map generator
List.zip episodes values
| :? _ as value -> [D, value; W, value; M, value]
|> dict |> Dictionary
let episodeDict2: obj -> Dictionary<Episode, _> = function
| :? (Episode -> _) as generator ->
let episodes = [D; W; M]
let values = episodes |> List.map generator
List.zip episodes values |> dict |> Dictionary
| :? _ as value -> [D, value; W, value; M, value] |> dict |> Dictionary
do the same thing, however the second cannot be marked inline
let inline episodeDict2…
FS0832 Only functions may be marked ‘inline’
Which seems really weird.
Can someone explain?
>Solution :
In your case, the two functions are really equivalent and so the compiler could be smarter and figure this out. However, the problem is that the second function is defined as a "value" that is not "syntactic function", i.e., it is not defined as let func x y z = .... The compiler uses a simple rule and only allows inlinding of syntactic functions.
The reason for this is that, when you have a function that is not defined as a syntactic function, it may not be possible to inline it. For example:
let foo =
let mutable counter = 0
fun () -> counter <- counter + 1; counter
If you took the body of this definition and placed it into the place where the function is used, it would change the meaning of the program! For example foo () + foo () returns 3, but if you did the inlining naively:
( let mutable counter = 0
fun () -> counter <- counter + 1; counter ) () +
( let mutable counter = 0
fun () -> counter <- counter + 1; counter ) ()
You would get 2 as the result! Again, you could imagine more clever compiler dealing with this – but I believe the F# decision here is reasonable – have a simple rule that is easy to understand (and ensures you get the right thing).