Considérer ce qui suit:
if(a == b or c)
Dans la plupart des langues, cela devrait être écrit comme suit:
if(a == b or a == c)
ce qui est un peu lourd et répète des informations.
Je sais que ma syntaxe d'échantillon ci-dessus est légèrement maladroite, mais je suis sûr qu'il existe de meilleures façons de transmettre l'idée.
Pourquoi plus de langues ne le proposent-elles pas? Y a-t-il des problèmes de performances ou de syntaxe?
a == b or c
, et il n'est même pas bien lu à mon humble avis.Réponses:
Le problème de syntaxe est - qu'il nécessite une syntaxe.
Quelle que soit la syntaxe de votre langue, les personnes qui l'utilisent doivent l'apprendre. Sinon, ils courent le risque de voir du code et de ne pas savoir ce qu'il fait. Ainsi, il est généralement considéré comme une bonne chose si une langue a une syntaxe simple qui gère proprement de nombreux cas.
Dans votre exemple spécifique, vous essayez de prendre un opérateur infixe (une fonction qui prend deux arguments mais est écrite
Argument1 Operator Argument2
) et essayez de l'étendre à plusieurs arguments. Cela ne fonctionne pas très bien parce que l'intérêt des opérateurs d'infixe, dans la mesure où il y en a un, est de placer l'opérateur entre les deux arguments. L'extension à(Argument1 Operator Argument2 MagicallyClearSymbol Argument3...)
ne semble pas ajouter beaucoup de clartéEquals(Arg1,Arg2,...)
. Infix est également généralement utilisé pour émuler des conventions mathématiques que les gens connaissent, ce qui ne serait pas le cas d'une syntaxe alternative.Il n'y aurait pas de problèmes de performances particuliers associés à votre idée, à part que l'analyseur aurait à gérer une grammaire avec une ou deux autres règles de production, ce qui pourrait avoir un léger effet sur la vitesse d'analyse. Cela peut faire une différence pour un langage interprété ou compilé JIT, mais probablement pas une grande différence.
Le plus gros problème avec l'idée est juste que faire beaucoup de cas spéciaux dans une langue a tendance à être une mauvaise idée .
la source
.
. Ils seraient donc écrits commearg1 op (arg2, arg3)
. Pas vraiment beau, mais nécessaire à certains endroits dans le contexte de cette langue.if my_var in (a, b)
alors? n'est-ce pas plus une question d'utiliser le bon outil pour le travail?a == b or c
tandis que d'autres le veulenta == b or c but not d
. IMO, c'est là que les fonctions / bibliothèques utilitaires viennent à la rescousse.f().Equals(a,b,c)
; pourrait être évaluée car(var temp=f(); temp.Equals(a)||temp.Equals(b)||temp.Equals(c))
cette syntaxe serait parfaite, mais si elle est évaluée commeint[] arr = {a,b,c}; f().Equals(arr);
cela ne serait pas si bonne, surtout si un nouveau tableau devait être créé pour chaque appel.Parce que ce n'est pas un problème, et sa résolution n'apporte pratiquement aucun avantage, mais sa mise en œuvre entraîne un coût non nul.
Les fonctions existantes basées sur la plage et telles que pratiquement tous les langages offrent peuvent parfaitement fonctionner dans cette situation si elles évoluent à une taille où
a == b || a == c
elles ne le coupent pas.la source
in_array($a, [$b, $c, $d, $e, $f])
. : PCertaines langues ont de telles fonctionnalités. Par exemple, en Perl6, nous pouvons utiliser des jonctions , qui sont des «superpositions» de deux valeurs:
Les jonctions nous permettent d'exprimer les opérations sur un ensemble de données de manière assez succincte, de la même manière que les opérations scalaires se répartissent sur les collections dans certaines langues. Par exemple, en utilisant Python avec numpy, la comparaison peut être répartie sur toutes les valeurs:
Cependant, cela ne fonctionne que pour les types primitifs sélectionnés.
Pourquoi les jonctions sont-elles problématiques? Étant donné que les opérations sur une jonction se répartissent sur les valeurs contenues, l'objet de jonction lui-même se comporte comme un proxy pour les appels de méthode - quelque chose que peu de systèmes de type en dehors de la frappe de canard peuvent gérer.
Les problèmes de système de type peuvent être évités si de telles jonctions ne sont autorisées que comme syntaxe spéciale autour des opérateurs de comparaison. Mais dans ce cas, ils sont tellement limités qu'ils n'ajoutent pas une valeur suffisante pour être ajoutés à une langue saine. Le même comportement pourrait être exprimé en utilisant des opérations d'ensemble ou en précisant manuellement toutes les comparaisons, et la plupart des langues ne croient pas à l'ajout d'une syntaxe redondante s'il existe déjà une solution parfaitement adaptée.
la source
2 in [1, 2, 3]
. D'un autre côté, si numpy a un.all()
ou quelque chose, le python ordinaire équivalent n'est pas aussi concis.==
opérateur, nous pouvons également utiliser à la<
place - où en êtes-vousin
maintenant? Jonctions sont plus générales que d' inclure des tests d'adhésion, parce que les opérations sur la jonction de distribuer sur tous les membres -(x|y).foo
estx.foo|y.foo
, jusqu'à ce que la jonction est finalement effondré à une valeur unique. Le code NumPy fourni montre une traduction exactement équivalente mais plus détaillée des jonctions Perl6, en supposant des types primitifs.Dans les langues avec des macros, il est facile d'ajouter quelque chose comme ça s'il n'est pas déjà là. Envisagez la raquette
Dans d'autres langues sans métaprogrammation, vous pouvez peut-être reformuler cela en vérifiant l'appartenance à une liste / liste, peut-être:
la source
Dans certaines langues (populaires), l'
==
opérateur n'est pas transitif. Par exemple, en JavaScript0
est égal aux deux''
et'0'
, mais alors''
et'0'
ne sont pas égaux les uns aux autres. Plus de ces bizarreries en PHP.Cela signifie que
a == b == c
cela ajouterait une autre ambiguïté, car cela pourrait donner un résultat différent selon qu'il est interprété comme(a == b) & (a == c)
ou(a == b) & (a == c) & (b == c)
.la source
Dans la plupart des langues, cela devrait être trivialement réalisable en écrivant une
In
fonction, alors pourquoi en faire une partie du langage réel?Linq, par exemple, l'a fait
Contains()
.D'accord, pour tous vous pédants, voici mon implémentation en C #:
la source
a == b || a == c
plusieurs fois, peut - être qu'il est temps pourequals_any(a, {b, c})
if (a > (b or c))
etif (a mod (b or c) == 2)
.i
variable. Et dans l'ensemble, cela semble être écrit après une longue journée :) Parce que mettre les deuxreturn true
etreturn false
à l'intérieur de la boucle ici signifie qu'il n'y a aucun moyen que cela se produise au-delà de la première itération. Vous ne comparez que le premiervalue
. Soit dit en passant, pourquoi ne pas l'utiliserAny
comme @Bob l'a suggéré et le simplifierreturn values.Any(value => Object.Equals(obj, value));
"if (a == b ou c)" fonctionne dans la plupart des langues: si a == b ou si c n'est pas négatif, nul ou nul.
Se plaindre qu'il est verbeux manque le point: vous ne devriez pas empiler une douzaine de choses dans un conditionnel. Si vous devez comparer une valeur à un nombre arbitraire d'autres valeurs, créez un sous-programme.
la source
c
évaluation est booléenne, alors pratiquement n'importe quelle langue peut gérera == b || c
:)if(a == b or c)
. Je dois faire une pause, je pense ...: Pif (a == b or c)
est un pseudo-code pour vérifier s'ila
est égalb
oua
égal àc
. Il ne s'agit pas de vérifier que cec
n'est pas zéro.Habituellement, vous voulez garder votre syntaxe au minimum et permettre à la place à de telles constructions d'être définies dans le langage lui-même.
Par exemple, dans Haskell, vous pouvez convertir n'importe quelle fonction avec deux ou plusieurs arguments en un opérateur infixe à l'aide de raccourcis. Cela vous permet d'écrire:
où
elem
est juste une fonction normale prenant deux arguments - une valeur et une liste de valeurs - et vérifie si le premier est un élément du second.Et si vous souhaitez utiliser à la
and
place deor
? Dans Haskell, vous pouvez simplement utiliser ce qui suit au lieu d'attendre que le fournisseur du compilateur implémente une nouvelle fonctionnalité:la source
Certaines langues offrent cela - dans une certaine mesure.
Peut-être pas comme exemple spécifique , mais prenez par exemple une ligne Python:
Ainsi, certaines langues sont très bien avec des comparaisons multiples, tant que vous l'exprimez correctement.
Malheureusement, cela ne fonctionne pas exactement comme vous vous y attendez pour les comparaisons.
"Que voulez-vous dire, il renvoie True ou 4?" - la location après vous
Une solution dans ce cas, au moins avec Python, est de l'utiliser légèrement différemment:
EDIT: Ce qui suit ferait également quelque chose de similaire, encore une fois en Python ...
Donc, quelle que soit la langue que vous utilisez, il se peut que vous ne puissiez pas le faire, mais que vous devez d'abord regarder de plus près comment la logique fonctionne réellement. En général, il s'agit simplement de savoir ce que vous «demandez» réellement la langue à vous dire.
la source
La méthode indexOf, utilisée sur un tableau, que presque toutes les langues ont, permet de comparer une valeur à plusieurs autres, donc je suppose qu'un opérateur spécial n'a pas beaucoup de sens.
En javascript qui écrirait:
la source
Vous demandez pourquoi nous ne pouvons pas faire cela:
if(a == b or c)
Python le fait très efficacement, en fait, le plus efficacement avec
set
:Pour les tests d'appartenance, 'set' vérifie que les hachages de l'élément sont les mêmes et ne compare ensuite que l'égalité, donc les éléments, b et c, doivent être lavables, sinon une liste compare directement l'égalité:
la source
Les langages de style APL vous permettent de comparer un scalaire avec chaque élément d'un vecteur en une seule opération. Cela produit un vecteur booléen. Par exemple, je voudrais promouvoir sans vergogne ma calculatrice apl à fonctionnalités minimales, inca ( interprète en ligne ).
Pour réduire cela à une seule valeur, nous pouvons faire une inclusion ou en additionnant et en vérifiant la valeur non nulle.
Ainsi, comme le disent les autres réponses, le problème est la syntaxe. Dans une certaine mesure, des solutions de syntaxe ont été trouvées, au prix peut-être lourd de l'apprentissage du paradigme des tableaux.
la source