C'est un peu subjectif, mais j'espère avoir une meilleure compréhension des facteurs qui rendent un opérateur clair à utiliser vs obtus et difficile. J'ai récemment envisagé des conceptions de langage, et un problème sur lequel je reviens toujours est de savoir quand faire une opération clé dans la langue en tant qu'opérateur et quand utiliser un mot clé ou une fonction.
Haskell est quelque peu connu pour cela, car les opérateurs personnalisés sont faciles à créer et souvent un nouveau type de données est fourni avec plusieurs opérateurs pour être utilisé dessus. La bibliothèque Parsec, par exemple, est livrée avec une tonne d'opérateurs pour combiner les analyseurs, avec des gemmes comme >.
et .>
je ne me souviens même pas de ce qu'ils signifient en ce moment, mais je me souviens qu'ils étaient très faciles à travailler une fois que j'avais mémorisé ce ils signifient réellement. Un appel de fonction tel leftCompose(parser1, parser2)
qu'aurait été mieux? Certainement plus verbeux, mais plus clair à certains égards.
Les surcharges d'opérateurs dans les langages de type C sont un problème similaire, mais confondu avec le problème supplémentaire de surcharger la signification des opérateurs familiers comme +
avec de nouvelles significations inhabituelles.
Dans toute nouvelle langue, cela semble être un problème assez difficile. En F #, par exemple, la conversion utilise un opérateur de conversion de type dérivé mathématiquement, au lieu de la syntaxe de conversion de style C # ou du style VB détaillé. C #: (int32) x
VB: CType(x, int32)
F #:x :> int32
En théorie, un nouveau langage pourrait avoir des opérateurs pour la plupart des fonctionnalités intégrées. Au lieu de def
ou dec
ou var
pour la déclaration de variable, pourquoi pas ! name
ou @ name
ou quelque chose de similaire. Cela raccourcit certainement la déclaration suivie de la liaison: @x := 5
au lieu de declare x = 5
ou la let x = 5
plupart du code va nécessiter beaucoup de définitions de variables, alors pourquoi pas?
Quand un opérateur est-il clair et utile, et quand est-il obscurcissant?
+
pour la concaténation de chaînes ou <<
pour les flux). Avec Haskell, en revanche, un opérateur est soit juste une fonction avec un nom personnalisé (c'est-à-dire non surchargé) ou une partie d'une classe de type, ce qui signifie que bien qu'il soit polymorphe, il fait la même chose logique pour chaque type, et a même le même type de signature. Il en >>
va de même >>
pour chaque type et ne sera jamais un peu décalé.