One point that I don't see mentioned explicitly (although amon alludes to it) is that square root can be thought of as a "derived" operation: if the implementation doesn't provide it for us, we can write our own.
Since the question is tagged with language-design, we might consider some language-agnostic description. Although many languages have different philosophies, it is very common across paradigms to use encapsulation to preserve invariants; i.e. to avoid having a value which doesn't behave as its type would suggest.
For example, if we have some implementation of integers using machine words, we probably want to encapsulate the representation somehow (e.g. to prevent bit shifts from changing the sign), but at the same time we still need access to those bits to implement operations like addition.
Some languages may implement this with classes and private methods:
class Int {
public Int add(Int x) {
// Do something with the bits
}
private List<Boolean> getBits() {
// ...
}
}
Some with module systems:
signature INT = sig
type int
val add : int -> int -> int
end
structure Word : INT = struct
datatype int = (* ... *)
fun add x y = (* Do something with the bits *)
fun getBits x = (* ... *)
end
Some with lexical scope:
(defun getAdder ()
(let ((getBits (lambda (x) ; ...
(add (lambda (x y) ; Do something with the bits
'add))
And so on. However, none of these mechanisms are needed for implementing square root: it can be implemented using the public interface of a numeric type, and hence it doesn't need access to the encapsulated implementation details.
Hence the location of square root comes down to the philosophy/tastes of the language, and of the library designer. Some may choose to put it "inside" the numeric values (e.g. make it an instance method), some may choose to put it at the same level as the primitive operations (this might mean an instance method, or it might mean living outside the numeric values, but inside the same module/class/namespace, e.g. as a standalone function or static method), some might choose to put it in a collection of "helper" functions, some might choose to delegate it to third-party libraries.
1.sqrt()
be valid?Sqrt(x)
looks much more natural thanx.Sqrt()
If that means prepending the function with the class in some languages I'm OK with that. If it were an instance method thenx.GetSqrt()
would be more appropriate to indicate that it's returning a value rather than modifying the instance.