Por que x < y < z
geralmente não está disponível em linguagens de programação?
Nesta resposta concluo que
- embora essa construção seja trivial de implementar na gramática de um idioma e crie valor para os usuários,
- As principais razões pelas quais isso não existe na maioria dos idiomas devem-se à sua importância em relação a outros recursos e à falta de vontade dos órgãos de governo dos idiomas em
- chatear os usuários com possíveis alterações
- mover para implementar o recurso (ou seja: preguiça).
Introdução
Eu posso falar da perspectiva de um pythonista sobre esta questão. Sou usuário de um idioma com esse recurso e gosto de estudar os detalhes de implementação do idioma. Além disso, eu estou um pouco familiarizado com o processo de alterar linguagens como C e C ++ (o padrão ISO é governado pelo comitê e versionado por ano).
Documentação e implementação do Python
A partir dos documentos / gramática, vemos que podemos encadear qualquer número de expressões com operadores de comparação:
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
| "is" ["not"] | ["not"] "in"
e a documentação declara ainda:
As comparações podem ser encadeadas arbitrariamente, por exemplo, x <y <= z é equivalente a x <y y = = z, exceto que y é avaliado apenas uma vez (mas em ambos os casos z não é avaliado quando x <y é encontrado ser falso).
Equivalência Lógica
tão
result = (x < y <= z)
é logicamente equivalente em termos de avaliação de x
, y
, e z
, com a excepção de que y
é avaliado duas vezes:
x_lessthan_y = (x < y)
if x_lessthan_y: # z is evaluated contingent on x < y being True
y_lessthan_z = (y <= z)
result = y_lessthan_z
else:
result = x_lessthan_y
Novamente, a diferença é que y é avaliado apenas uma vez (x < y <= z)
.
(Observe, os parênteses são completamente desnecessários e redundantes, mas eu os usei para o benefício de outros idiomas, e o código acima é bastante legal em Python.)
Inspecionando a árvore de sintaxe abstrata analisada
Podemos inspecionar como o Python analisa operadores de comparação encadeados:
>>> import ast
>>> node_obj = ast.parse('"foo" < "bar" <= "baz"')
>>> ast.dump(node_obj)
"Module(body=[Expr(value=Compare(left=Str(s='foo'), ops=[Lt(), LtE()],
comparators=[Str(s='bar'), Str(s='baz')]))])"
Portanto, podemos ver que isso realmente não é difícil para o Python ou qualquer outra linguagem analisar.
>>> ast.dump(node_obj, annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE()], [Str('bar'), Str('baz')]))])"
>>> ast.dump(ast.parse("'foo' < 'bar' <= 'baz' >= 'quux'"), annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE(), GtE()], [Str('bar'), Str('baz'), Str('quux')]))])"
E, ao contrário da resposta atualmente aceita, a operação ternária é uma operação de comparação genérica, que pega a primeira expressão, uma iterável de comparações específicas e uma iterável de nós de expressão para avaliar conforme necessário. Simples.
Conclusão sobre Python
Pessoalmente, acho que a semântica de alcance é bastante elegante, e a maioria dos profissionais de Python que eu conheço encorajaria o uso do recurso, em vez de considerá-lo prejudicial - a semântica é claramente declarada na documentação de boa reputação (como observado acima).
Observe que o código é lido muito mais do que está escrito. As mudanças que melhoram a legibilidade do código devem ser adotadas, sem descontar o aumento de espectros genéricos de Medo, Incerteza e Dúvida .
Então, por que x <y <z normalmente não está disponível nas linguagens de programação?
Eu acho que há uma confluência de razões que se concentram na importância relativa do recurso e no momento / inércia de mudança permitidos pelos governadores das línguas.
Perguntas semelhantes podem ser feitas sobre outros recursos de idioma mais importantes
Por que a herança múltipla não está disponível em Java ou C #? Não há uma boa resposta aqui para qualquer uma das perguntas . Talvez os desenvolvedores tenham sido preguiçosos, como Bob Martin alega, e as razões apresentadas são apenas desculpas. E herança múltipla é um tópico bastante grande na ciência da computação. É certamente mais importante que o encadeamento do operador.
Soluções alternativas simples
O encadeamento do operador de comparação é elegante, mas não é tão importante quanto a herança múltipla. E assim como Java e C # têm interfaces como solução alternativa, todas as linguagens para várias comparações - você simplesmente encadeia as comparações com "e" s booleanos, o que funciona com bastante facilidade.
A maioria dos idiomas é governada por comitê
A maioria das línguas está evoluindo por comitê (em vez de ter um ditador benevolente sensato para a vida como o Python). E especulo que esse assunto não tenha recebido apoio suficiente para sair de seus respectivos comitês.
Os idiomas que não oferecem esse recurso podem mudar?
Se uma linguagem permitir x < y < z
sem a semântica matemática esperada, isso seria uma mudança radical. Se não o permitisse, seria quase trivial adicionar.
Quebrando mudanças
Em relação aos idiomas com alterações de quebra: atualizamos os idiomas com mudanças de comportamento - mas os usuários tendem a não gostar disso, principalmente os usuários de recursos que podem estar com problemas. Se um usuário confiar no comportamento anterior de x < y < z
, provavelmente protestaria em voz alta. E como a maioria das línguas é governada por um comitê, duvido que tenhamos muita vontade política para apoiar essa mudança.