if i>0 : return sqrt(i)
elif i==0: return 0
else : return 1j * sqrt(-i)
VS
if i>0:
return sqrt(i)
elif i==0:
return 0
else:
return 1j * sqrt(-i)
Dados os exemplos acima, não entendo por que praticamente nunca vejo o primeiro estilo nas bases de código. Para mim, você transforma o código em um formato tabular que mostra claramente o que você deseja. A primeira coluna pode ser virtualmente ignorada. A segunda coluna identifica a condição e a terceira coluna fornece a saída desejada. Parece, pelo menos para mim, direto e fácil de ler. No entanto, eu sempre vejo esse tipo simples de situação de caso / troca sair no formato estendido e recuado por tabulação. Por que é que? As pessoas acham o segundo formato mais legível?
O único caso em que isso pode ser problemático é se o código for alterado e ficar mais longo. Nesse caso, acho perfeitamente razoável refatorar o código no formato longo e recuado. Todo mundo faz isso da segunda maneira, simplesmente porque é do jeito que sempre foi feito? Sendo um advogado do diabo, acho que outro motivo pode ser porque as pessoas acham dois formatos diferentes, dependendo da complexidade das declarações if / else, que são confusas? Qualquer insight seria apreciado.
fonte
if
se estiver na mesma linha.Respostas:
Um motivo pode ser que você não está usando idiomas populares.
Alguns contra-exemplos:
Haskell com guardas e com padrões:
Erlang com padrões:
Emacs lisp:
Geralmente, vejo que o formato da tabela é bastante popular entre as linguagens funcionais (e, em geral, baseadas em expressões), enquanto a quebra de linhas é mais popular em outras (principalmente baseada em instruções).
fonte
if-else
declarações literais ainda estão espalhadas por várias linhas, quando não são efetivamente um simples ternário.É mais legível. Algumas razões pelas quais:
No minuto em que você tentar fazer isso, você será reescrito em instruções de várias linhas. O que significa que você acabou de perder tempo!
Além disso, as pessoas inevitavelmente adicionam algo como:
Não é muito frequente fazer isso antes de você decidir que esse formato é muito melhor que sua alternativa. Ah, mas você pode incorporar tudo em uma linha! enderland morre por dentro .
Ou isto:
O que é muito, muito chato. Ninguém gosta de formatar coisas assim.
E por último, você começará a guerra santa do problema de "quantos espaços para abas". O que é renderizado perfeitamente na tela como formato de tabela pode não renderizar na minha, dependendo das configurações.
A legibilidade não deve depender das configurações IDE de qualquer maneira.
fonte
:
posição -> fazendo uma diferença no CVS, de repente se torna mais difícil entender o que realmente está mudando. Isso também é válido para condição versus corpo. Tê-los em linhas separadas significa que, se você alterar apenas um deles, as diferenças mostram claramente que apenas a condição mudou, não o corpo.Acredito firmemente em 'o código é lido muitas vezes, escrito poucas - então a legibilidade é muito importante'.
Uma coisa importante que me ajuda quando leio o código de outras pessoas é que segue os padrões 'normais' que meus olhos são treinados para reconhecer. Consigo ler a forma recuada com mais facilidade porque já a vi tantas vezes que é registrada quase automaticamente (com pouco esforço cognitivo da minha parte). Não é porque é 'mais bonita' - é porque segue as convenções com as quais estou acostumado. Convenção supera 'melhor' ...
fonte
Juntamente com as outras desvantagens já mencionadas, o layout tabular aumenta as chances de conflitos de mesclagem de controle de versão que requerem intervenção manual.
Quando um bloco de código alinhado tabularmente precisa ser realinhado, o sistema de controle de versão tratará cada uma dessas linhas como tendo sido modificadas:
Agora, suponha que nesse meio tempo, em outro ramo, um programador tenha adicionado uma nova linha ao bloco de código alinhado:
A fusão desse ramo falhará:
Se o código que está sendo modificado não tivesse usado o alinhamento tabular, a mesclagem seria bem-sucedida automaticamente.
(Essa resposta foi "plagiada" do meu próprio artigo, desencorajando o alinhamento tabular no código).
fonte
Os formatos de tabela podem ser muito bons se as coisas sempre se ajustarem à largura atribuída. Se algo exceder a largura alocada, no entanto, muitas vezes será necessário ter parte da tabela que não esteja alinhada com o restante ou ajustar o layout de tudo o mais na tabela para ajustar-se ao item longo .
Se os arquivos de origem forem editados usando programas projetados para trabalhar com dados em formato de tabela e puderem lidar com itens muito longos usando um tamanho de fonte menor, dividindo-os em duas linhas na mesma célula, etc., pode fazer sentido usar tabular formatos com mais frequência, mas a maioria dos compiladores deseja arquivos de origem livres dos tipos de marcação que esses editores precisariam armazenar para manter a formatação. Usar linhas com quantidades variáveis de recuo, mas nenhum outro layout não é tão bom quanto a formatação tabular no melhor dos casos, mas não causa quase tantos problemas no pior caso.
fonte
Existe a declaração 'switch' que fornece esse tipo de coisa para casos especiais, mas acho que não é disso que você está perguntando.
Já vi declarações em formato de tabela, mas deve haver um grande número de condições para que valha a pena. 3 se as instruções são melhor exibidas no formato tradicional, mas se você tivesse 20, é muito mais fácil exibi-las em um grande bloco formatado para torná-lo mais claro.
E aí está o ponto: clareza. Se facilitar a visualização (e seu primeiro exemplo não for fácil de ver onde está o delimitador:), formate-o para se adequar à situação. Caso contrário, atenha-se ao que as pessoas esperam, pois isso é sempre mais fácil de reconhecer.
fonte
switch
.switch
era uma necessidade.switch
é mau, mas instanciar um dicionário, em seguida, executando uma pesquisa sobre ele para fazer ramificação trivial não é mau ...Se sua expressão é realmente fácil, a maioria das linguagens de programação oferece o operador?: Branching:
Este é um formato tabular curto e legível. Mas a parte importante é: vejo de relance qual é a ação "principal". Esta é uma declaração de retorno! E o valor é decidido por certas condições.
Se, por outro lado, você possui ramificações que executam códigos diferentes, acho muito mais legível recuar esses blocos. Porque agora existem ações "principais" diferentes, dependendo da instrução if. Em um caso, jogamos, em um caso, registramos e retornamos ou simplesmente retornamos. Existe um fluxo de programa diferente, dependendo da lógica, portanto, os blocos de código encapsulam os diferentes ramos e os tornam mais proeminentes para o desenvolvedor (por exemplo, leitura rápida de uma função para captar o fluxo do programa)
fonte
?
e:
são mais difíceis de identificar do que asif
/else
keywords e / ou devido ao "ruído" adicional dos símbolos.Como enderland já disse, você está supondo que só tenha um "retorno" como a ação e que possa marcar esse "retorno" no final da condição. Eu gostaria de dar alguns detalhes extras sobre por que isso não será bem-sucedido.
Não sei quais são os seus idiomas preferidos, mas estou codificando em C há muito tempo. Existem vários padrões de codificação em torno dos quais o objetivo é evitar alguns erros de codificação padrão, impedindo construções de código propensas a erros, na codificação inicial ou durante a manutenção posterior. Eu estou mais familiarizado com o MISRA-C, mas existem outros, e geralmente todos eles têm regras semelhantes porque estão lidando com os mesmos problemas no mesmo idioma.
Um erro popular que os padrões de codificação costumam abordar é esse pequeno problema:
Isso não faz o que você pensa que faz. No que diz respeito a C, se x é 10, então você chama
do_something()
, masdo_something_else()
é chamado independentemente do valor de x . Somente a ação imediatamente após a instrução "if" é condicional. Pode ser o que o codificador pretendia; nesse caso, existe uma armadilha em potencial para os mantenedores; ou pode não ser o que o codificador pretendia; nesse caso, há um erro. É uma pergunta de entrevista popular.A solução nos padrões de codificação é exigir chaves entre todas as ações condicionais, mesmo que sejam de linha única. Agora temos
ou
e agora funciona corretamente e é claro para os mantenedores.
Você notará que isso é totalmente incompatível com o formato de tabela.
Algumas outras linguagens (por exemplo, Python) analisaram esse problema e decidiram que, como os codificadores estavam usando espaços em branco para deixar o layout claro, seria uma boa idéia usar espaços em branco em vez de chaves. Então, em Python,
faz as chamadas para ambos
do_something()
edo_something_else()
condicional em x == 10, enquantosignifica que apenas
do_something()
é condicional em x edo_something_else()
é sempre chamado.É um conceito válido e você encontrará alguns idiomas para usá-lo. (Eu vi pela primeira vez no Occam2, quando.) Novamente, porém, você pode ver facilmente que o seu formato de tabela é incompatível com o idioma.
fonte
O layout tabular pode ser útil em alguns casos limitados, mas há poucas vezes em que é útil com if.
Em casos simples?: Pode ser uma escolha melhor. Em casos médios, uma opção geralmente é mais adequada (se o seu idioma tiver uma). Em casos complicados, você pode achar que as tabelas de chamadas são mais adequadas.
Houve muitas vezes em que refatorar o código que eu o reorganizei para ser tabular para tornar seu padrão óbvio. Raramente é o caso que deixo assim, pois na maioria dos casos existe uma maneira melhor de resolver o problema depois que você o entende. Ocasionalmente, uma prática de codificação ou padrão de layout o proíbe; nesse caso, um comentário é útil.
Houve algumas perguntas sobre
?:
. Sim, é o operador ternário (ou, como eu gosto de pensar, o valor se). na primeira tentativa de corar esse exemplo é um pouco complicado para?: (e usar em excesso?: não ajuda na legibilidade, mas prejudica), mas com algumas reflexões solução.fonte
if ? do stuff : do other stuff
. Mesma ordem que um if / else.Não vejo nada de errado com o formato da tabela. Preferência pessoal, mas eu usaria um ternário como este:
Não há necessidade de repetir
return
todas as vezes :)fonte
do_something() if condition() else do_something_else()
, nãocondition() ? do_something() : do_something_else()
.