Um ponto que não vejo mencionado explicitamente (embora amon faça alusão a ele) é que a raiz quadrada pode ser pensada como uma operação "derivada": se a implementação não fornecer isso para nós, podemos escrever nossos próprios.
Como a pergunta está marcada com design de linguagem, podemos considerar uma descrição independente de idioma. Embora muitas línguas tenham filosofias diferentes, é muito comum entre paradigmas usar encapsulamento para preservar invariantes; ou seja, para evitar ter um valor que não se comporte conforme o tipo sugerido.
Por exemplo, se tivermos alguma implementação de números inteiros usando palavras de máquina, provavelmente queremos encapsular a representação de alguma forma (por exemplo, para evitar que mudanças de bits alterem o sinal), mas ao mesmo tempo ainda precisamos acessar esses bits para implementar operações como Adição.
Alguns idiomas podem implementar isso com classes e métodos privados:
class Int {
public Int add(Int x) {
// Do something with the bits
}
private List<Boolean> getBits() {
// ...
}
}
Alguns com sistemas de módulos:
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
Alguns com escopo lexical:
(defun getAdder ()
(let ((getBits (lambda (x) ; ...
(add (lambda (x y) ; Do something with the bits
'add))
E assim por diante. No entanto, nenhum desses mecanismos é necessário para implementar a raiz quadrada: ele pode ser implementado usando a interface pública de um tipo numérico e, portanto, não precisa acessar os detalhes da implementação encapsulada.
Portanto, a localização da raiz quadrada se resume à filosofia / gostos da linguagem e do designer da biblioteca. Alguns podem optar por colocá-lo "dentro" dos valores numéricos (por exemplo, torná-lo um método de instância), outros podem optar por colocá-lo no mesmo nível das operações primitivas (isso pode significar um método de instância ou pode viver fora do valores numéricos, mas dentro do mesmo módulo / classe / espaço para nome, por exemplo, como uma função autônoma ou método estático), alguns podem optar por colocá-lo em uma coleção de funções "auxiliares", outros podem optar por delegá-lo a bibliotecas de terceiros.
1.sqrt()
válido?