As Reed mentioned, functions can be defined within modules a la other ML languages, but they can also be defined on types like other .NET languages (and in fact modules are also compiled to classes). Within F#, modules can be open
ed to access the functions without having to use the module name each time, and modules are automatically created on a per-file basis if they aren't explicitly declared.
As to why there are separate cos
, etc. functions instead of merely relying on .NET's built-in Math.Cos
, etc., there are probably several reasons:
- Uniformity:
cos
looks much more idiomatic in F# than calling the static method System.Math.Cos
.
- Static constraints:
cos
doesn't just work on float
s in F#, it also works on float32
s and on any type which exposes a static Cos
method, so you can create your own types to which the cos
function can be applied.
I'd guess that truly free functions aren't allowed because there are many .NET languages which don't expose convenient access to them, so using them would present a barrier to cross-language interoperability. The CLR itself does support free functions, and some languages such as C++/CLI do use them, but most languages compile functions into classes (even if that's not how it looks from a source code perspective, as in F#).