Yes, sure; but I usually don't create global functions for math. My global functions are usually overloaded factory functions that create a group of related types, such as a group of weak(...) functions to create different types of weak-reference-holding containers.
I don't like when functions appear as properties like that. In extreme cases we can end up with something like x.log(10).sin.pow(3) which is just not very readable for me as a math expression. I am used to old school FORTRAN-style math expressions.
I guess I would prefer pow(sin(log(x)), 3), but all the type inference of using static members with prefixed . (requireing the base type to be inferred) adds a lot of type checker complexity for large expressions.
Would be nice to have something like C++'s scoped using, so that these functions can temporarily be made members of the global name space (there are way less members of the global name space then there are static members on all types)
I haven't found that to be exorbitant; since all of these are "homogeneous" (i.e., whatever type is the argument, that will be the type of the result), the type checker doesn't seem to have trouble at all. In the standard library, we already have .pi, .infinity, .nan, and other static members that are idiomatically written with the leading dot.
At the risk of some self-promotion (not that it really benefits me in any material way), I explored this design option in my protocol-based library NumericAnnex. The purpose was to see if various design options were practical and ergonomic to use. You'll see that I settled on the .sin(x) notation--it's pretty readable in the end, and it really does play well with the type checker.
FYI, the standard library implementations of generic numeric functions sometimes implement fast-paths for known types. Perhaps something like that is also an option here?
For example (ignore the FIXME, we're talking about the "else" branch):
EDIT: Also, isn't that preview so awesome? I'm really loving these forums...