mobrien:Well, now that I think about it, it's probably that the compiler can look through the call graph and see if it's all deterministic. So if thats the case then it's a value. Otherwise if there is some non deterministic functions in the call graph it's considered a function.
So just by looking at my code above you can see that it's all deterministic and thus a value.
Just a wild guess.... Am I close? :)
m
Not quite... in general it's impossible to know if something is deterministic, so the compiler uses a much simpler scheme.
For top level definitions, something is a value if it doesn't take parameters. For instance, given the two definitions:
let now = System.DateTime.Now
let add x y = x + y"now" is a value, and will never change. add is a function taking two arguments, and each time both arguments are supplied, the definition on the right will be evaluated to give the return value.
However, when defining .NET classes, things become more complicated, because classes can contain fields, methods, events, properties, etc. Properties are re-evaluated whenever they are gotten, and DateTime.Now is a property, which is why the value appears to change over time.
Things can also be a bit confusing when using functions in a first-class way. For instance:
let myFun =
let time = System.DateTime.Now
fun () -> System.DateTime.Now - timeHere, myFun is a value (which happens to be a function!), and its definition is only evaluated once (so, in particular, "time" is only ever set once, when myFun is first defined). However, calling the myFun function then results in the evaluation of the function's body (that is, the right hand side of the last line of myFun's definition, which calls System.DateTime.Now and subtracts the original time).
-Keith