Un point que je ne vois pas mentionné explicitement (bien que amon y fasse allusion) est que la racine carrée peut être considérée comme une opération "dérivée": si l'implémentation ne nous la fournit pas, nous pouvons écrire la nôtre.
Étant donné que la question est étiquetée avec la conception de la langue, nous pourrions envisager une description indépendante de la langue. Bien que de nombreuses langues aient des philosophies différentes, il est très courant à travers les paradigmes d'utiliser l'encapsulation pour préserver les invariants; c'est-à-dire pour éviter d'avoir une valeur qui ne se comporte pas comme le suggère son type.
Par exemple, si nous avons une implémentation d'entiers utilisant des mots machine, nous voulons probablement encapsuler la représentation d'une manière ou d'une autre (par exemple pour empêcher les décalages de bits de changer le signe), mais en même temps nous avons toujours besoin d'accéder à ces bits pour implémenter des opérations comme une addition.
Certains langages peuvent implémenter cela avec des classes et des méthodes privées:
class Int {
public Int add(Int x) {
// Do something with the bits
}
private List<Boolean> getBits() {
// ...
}
}
Certains avec des systèmes de modules:
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
Certains à portée lexicale:
(defun getAdder ()
(let ((getBits (lambda (x) ; ...
(add (lambda (x y) ; Do something with the bits
'add))
Etc. Cependant, aucun de ces mécanismes n'est nécessaire pour implémenter la racine carrée: il peut être implémenté en utilisant l' interface publique de type numérique, et donc il n'a pas besoin d'accéder aux détails de l'implémentation encapsulée.
Par conséquent, l'emplacement de la racine carrée se résume à la philosophie / aux goûts de la langue et du concepteur de la bibliothèque. Certains peuvent choisir de le mettre "à l'intérieur" des valeurs numériques (par exemple, en faire une méthode d'instance), certains peuvent choisir de le mettre au même niveau que les opérations primitives (cela peut signifier une méthode d'instance, ou cela peut signifier vivre en dehors de la valeurs numériques, mais à l' intérieur du même module / classe / espace de noms, par exemple en tant que fonction autonome ou méthode statique), certains pourraient choisir de le placer dans une collection de fonctions "d'assistance", certains pourraient choisir de le déléguer à des bibliothèques tierces.
1.sqrt()
valide?