Recentemente, eu estava desenvolvendo um conjunto de padrões de codificação para nossa empresa. (Somos uma nova equipe que se ramifica em um novo idioma para a empresa.)
No meu primeiro rascunho, defino o objetivo de nossos padrões de codificação como melhorar a legibilidade, a manutenção, a confiabilidade e o desempenho. (Ignorei gravabilidade, portabilidade, custo, compatibilidade com padrões anteriores etc.)
Um dos meus objetivos ao escrever este documento foi promover a idéia de simplicidade de código. A idéia era que deveria haver apenas uma chamada de função ou operação por linha. Minha esperança era que isso aumentasse a legibilidade. É uma ideia que eu carreguei da nossa língua anterior.
No entanto, questionei a suposição por trás desse impulso:
A simplicidade sempre melhora a legibilidade?
Existe um caso em que escrever código mais simples diminui a legibilidade?
Deve ser óbvio, mas por "mais simples", não quero dizer "mais fácil de escrever", mas menos coisas acontecendo por linha.
fonte
a = b
é uma operação,b + c
é uma segunda, o que significaa = b + c
é 2 operações. O encadeamento de 2 funções / operadores ainda é legível:,foo(bar())
oua = foo()
.Respostas:
"Simples" é uma palavra usada em excesso. "Legível" pode ser lucrativamente definido como "simples de entender"; nesse caso, aumentar (essa medida de) simplicidade por definição aumenta a legibilidade, mas acho que não é isso que você quer dizer. Eu escrevi sobre isso em outro lugar , mas geralmente algo pode ser chamado de "mais simples", sendo mais abstrato (nesse caso, menos conceitos podem expressar mais fenômenos) ou mais concreto (nesse caso, um conceito não requer tanto conhecimento de fundo) conhecimento para entender em primeiro lugar). Estou argumentando que, dependendo da perspectiva, um conceito mais abstrato pode ser razoavelmente chamado de mais simples que um conceito mais concreto, ou vice-versa . Isso, mesmo que "abstrato" e "
Vou usar como exemplo algum código Haskell que escrevi há algum tempo. Fiz uma pergunta no stackoverflow sobre o uso da mônada List para calcular um contador no qual cada dígito poderia ter uma base diferente. Minha solução final (sem conhecer muito Haskell) parecia:
Uma das respostas reduziu isso para:
Qual destes itens é "mais simples" de entender (isto é, mais legível) depende inteiramente de quão confortável o leitor se tornou com operações monádicas (abstratas) (e, nesse caso, de código sem pontos). Um leitor que se sinta muito confortável com esses conceitos abstratos preferirá ler a versão (mais curta) mais abstrata, enquanto um que não se sentir confortável com essas operações preferirá ler a versão (mais longa) mais concreta. Não há uma resposta sobre qual versão é mais legível e válida para todos.
fonte
mapM
é bastante idiomático eenumFromTo
faz exatamente o que diz na lata. Em geral, acho que é realmente mais fácil cometer erros isolados se você expandir o código - há simplesmente mais código para cometer um erro. Isso é especialmente evidente em coisas como loops e procedimentos de ordem superior em outros idiomas. , mas acho que é um princípio geral.Se o seu padrão de codificação é sobre "Legibilidade, Manutenção, Confiabilidade e Desempenho" , basta indicar isso .
Não tente prescrever como alcançar essas coisas, pois sempre haverá situações em que há um contra-exemplo.
O que você precisa prescrever é algo que fará com que o código seja quebrado se não for respeitado também. Os traços estilísticos não quebram o código e devem ser sugestões (desde que a maioria da equipe concorde que é Legibilidade, o restante deve ser a preferência do desenvolvedor (com revisão do código para que a pressão dos colegas lembre as pessoas de que outras pessoas precisam ler o código)) .
fonte
Menos "itens por linha", simplicidade e legibilidade não são a mesma coisa. Pode-se pegar um algoritmo não documentado obscuro incrivelmente complicado e codificá-lo com 1 instrução por linha em vez de 2, e ele não se tornará muito mais legível.
Menos "material por linha" também pode exigir o fornecimento de desenvolvedores com grandes monitores altos para ver os blocos de código agora se espalharem mais verticalmente. Ou causar cansaço visual ao ler fontes menores.
A legibilidade é sua própria métrica, que geralmente requer um compromisso entre várias outras métricas mais facilmente mensuráveis. Pré-restrinja todas as outras métricas e o compromisso não se torna mais possível, resultando em código menos legível.
fonte
Sempre? - NÃO
Ironicamente, atingir o nível certo de simplicidade pode ser uma tarefa complexa. Eu acho que a chave está com moderação. A simplicidade também pode estar nos olhos de quem vê, por isso, se você pensar demais - apenas deixe em paz ou volte mais tarde.
Pessoalmente, quando tento voltar e simplificar algo que escrevi, concentro-me nas áreas em que mudei de idéia ou tentei algumas coisas para conseguir o que queria. Essas áreas geralmente podem ser suavizadas. Em seguida, basta fazer algumas passagens pelo código para torná-lo mais legível sem espalhar tanto as coisas que você está pulando por todo o lado para descobrir o que está acontecendo em uma depuração.
fonte
Se eu optar pela simplicidade, posso escrever um código como este:
Mas se eu for de legibilidade, vou preferir isso:
Por outro lado,
1000
é muito mais legível e simples do que a1e3
menos que você trabalhe com números em notação científica o tempo todo.Este é um exemplo degenerado de um padrão muito mais geral que você pode encontrar em quase qualquer lugar - criar algo com blocos muito simples pode rapidamente se tornar ilegível / ineficiente / ruim de várias maneiras diferentes. Generalizar e reutilizar, por outro lado, é mais difícil a princípio ("o que é isso
e
?! Eles quiseram escrever1343
?", Alguém poderia dizer), mas pode ajudar muito a longo prazo.fonte
100
é necessário realizar duas multiplicações e duas adições (0+10*(0+10*1)
). No entanto, tendo se acostumado a essa notação, você nem percebe isso. Isso mostra novamente como a noção de simplicidade pode ser subjetiva.Não necessariamente. Se você tem uma operação complexa, essa complexidade precisa ir a algum lugar. Reduzir o número de "coisas" que aparecem em uma linha significa apenas que ocupará mais linhas, o que pode ser prejudicial para a legibilidade do código se tornar sua rotina "alta" demais para caber em uma tela.
fonte
G=0
, mas acho que você é louco. Se você não estiver, está perdendo o meu ponto. Certamente você pode abstrair os detalhes irrelevantes, mas não é irrelevante se os seus requisitos dizem que são relevantes. Se você ler novamente, nunca afirmei que toda a complexidade é necessária - apenas que alguma complexidade é inerente aos requisitos e não pode ser eliminada.Clareza + Padrões + Reutilização de código + Bons comentários + Bom design pode melhorar a legibilidade .
A simplicidade nem sempre está na mão do desenvolvedor, devido à natureza dos algoritmos e à complexidade da estrutura do aplicativo atualmente.
Pegue as páginas da web simples que executam tarefas simples. Dada uma rotina de classificação, não é possível simplificar a lógica, mas você pode torná-la mais clara com comentários, usando nomes de variáveis significativos, tendo a escrita de maneira estruturada etc.
fonte
Não. Eu já vi muitos casos em que fazer várias coisas mais simples em uma linha é menos complexo do que ter várias linhas.
Há uma troca entre menos código e código mais simples.
Em geral, eu recomendaria o código mais simples, a menos que você tenha certeza de que fazê-lo em menos linhas seja melhor. Eu preferiria ter código "muito detalhado" sobre código "muito complexo".
fonte
"Torne as coisas o mais simples possível, mas não mais simples" - uma paráfrase frequente de Albert Einstein
A simplicidade melhora tudo . Para diferentes valores de simplicidade, é claro. São menos linhas de código? Talvez. É um executável menor? Possivelmente. É algo que sua equipe precisa concordar? Absolutamente .
fonte
A simplicidade sempre melhora a legibilidade? Sim. Uma declaração por linha é sempre mais simples? Não. Muitas línguas possuem um operador ternário, que, uma vez entendido, é mais simples e fácil de entender do que as atribuições equivalentes if / else.
Em idiomas que permitem que várias variáveis sejam definidas em uma linha, isso costuma ser mais simples e fácil de entender do que seja o equivalente.
Outro exemplo: expressões regulares fazem muito, geralmente em apenas uma linha, e o equivalente sem regex é frequentemente muito mais difícil de ler. / \ d {3} [-] \ d {3} - \ d {4} / é o equivalente a uma chamada de função com pelo menos vários comentários e é mais fácil de entender do que o corpo da função correspondente.
fonte
Legibilidade e simplicidade são termos subjetivos que, dependendo da pessoa e do contexto, geralmente, mas nem sempre, andam juntos.
Um termo mais objetivo é concisão - algo que, em princípio, você poderia contar contando caracteres, embora existam algumas falhas nisso. Concisão parece implicar simplicidade e legibilidade, mas existem (pelo menos na minha opinião) exceções.
Um pedaço de código mais longo (e sem dúvida mais complexo) pode ser mais legível se expressar melhor a intenção. Se sua definição de simplicidade se importa com a intenção é outra coisa subjetiva - você pode definir a complexidade em termos da estrutura sintática e da entropia da teoria da informação, por exemplo, sem nenhuma referência a intenções.
Portanto, um nome de variável mais longo e bem escolhido pode ...
Da mesma forma, eu poderia escrever
if (some_boolean == true)
. Em comparação com a alternativa equivalenteif (some_boolean)
, isso ...É claro que este provocará um protesto em massa - para muitas pessoas, isso sempre prejudica a legibilidade também. Para mim, depende muito da fonte do booleano - por exemplo, o nome da variável (ou nome do método ou o que for) pode não expressar claramente que o valor é "valor de verdade". Claro, o
if
diz algo, mas ainda cheira. Mas muitas pessoas vão me chamar de idiota por acreditar nisso.O que é mais uma evidência da subjetividade geral, é claro.
fonte
Todos estão faltando algumas definições fundamentais . Simples, a partir da raiz simplex , significa uma dobra . Simples significa fazer uma coisa . Fácil, a partir da facilidade raiz , significa estar perto . Fácil significa que está por perto . Os exemplos de código simples fornecidos em outras respostas não são exatamente o que aparecem.
Veja a exibição do rotsor de um valor muito grande. Ele diz que isso é simples . Na minha opinião, não é simples. É fácil. É fácil digitar o número de 0s necessários.
A versão legível é simples. Faz uma coisa. Ele expressa o número, descrevendo seu tamanho em uma finalidade de notação criada para esta função.
Você poderia descrever o snippet de código "simples" de Aidan como fazendo uma coisa? Ele contém 10 linhas de código (sem contar os comentários) e pelo menos 7 blocos (como eu os contaria). Se você seguir os comentários, verá que ele faz pelo menos quatro coisas!
Porém, uma das recomendações para reescrever esse código foi uma declaração. Aidan afirma que um leitor teria que estar familiarizado com declarações monádicas, código livre de ponteiros etc. Isso é bom. Esses conceitos são singulares e independentes de aprender.
Você verá que o código verdadeiramente simples é mais legível do que o código fácil , porque faz apenas uma coisa. Pode ser necessário sair e aprender mais "uma coisa" para entender o código simples. Mas deve sempre ser mais legível.
fonte
Eu diria, talvez com um pouco de controvérsia, absolutamente não .
Você poderia me dar uma classe com 200 funções-membro em sua interface pública, e pode ser a interface pública mais humanamente legível por aí. Pode ser uma alegria apenas ler casualmente esse código e sua documentação. No entanto, eu não chamaria isso de "simples", porque, apesar da legibilidade, eu teria que me preocupar com a forma como todas essas funções interagem umas com as outras e, potencialmente, tomar cuidado com casos complicados resultantes de uso indevido.
Eu preferiria uma classe com 20 funções-membro que não eram tão fáceis de ler para 200, porque "legibilidade" não é a principal prioridade para mim em termos de prevenção de erros humanos e melhoria da capacidade de manutenção do código (a facilidade com que nós podemos mudar isso, ie).
No entanto, tudo isso depende de nossa definição pessoal de "simplicidade". "Legibilidade" normalmente não varia que descontroladamente entre nós, a menos que alguém tenha adquirido tanto conhecimento e fluência que consideram regex a ser muito "legível", por exemplo, esquecendo o resto de nós meros mortais.
Simplicidade
Houve um tempo, há muito tempo, em que pensei que "simplicidade" significava "o mais fácil de ler possível". Então, eu escreveria o código C com muitas funções de conveniência, tentando melhorar a sintaxe e facilitar a leitura e gravação das coisas.
Projetei bibliotecas muito grandes, ricas e de alto nível como resultado, tentando modelar uma função para todo pensamento humano natural: ajudantes sobre ajudantes sobre ajudantes, tudo para moldar o código do cliente para uma sintaxe mais legível. O código que escrevi na época pode ter sido o mais "legível", mas também o mais "inatingível" e "complexo".
Lisp
No entanto, tive uma breve paixão pelo LISP em meados dos anos 90 (retardatário). Isso mudou toda a minha idéia de "simplicidade".
LISP não é a linguagem mais legível. Felizmente, ninguém pensa que extrair CDRs e CARs enquanto invoca uma função recursiva com um monte de parênteses aninhados é muito "legível".
No entanto, depois de lutar para envolver meu cérebro na estranha sintaxe da linguagem e em maneiras totalmente recursivas de fazer as coisas, isso mudou permanentemente minha ideia de simplicidade.
O que descobri com o código que escrevi no LISP é que não estava mais cometendo erros sutis, embora a astúcia de pensar dessa maneira tenha me cometido erros mais flagrantes (mas esses são fáceis de identificar e corrigir). Eu não estava entendendo mal o que uma função estava fazendo e perdendo um efeito colateral sutil e imprevisto. Eu estava tendo um tempo mais fácil em geral, fazendo alterações e escrevendo programas corretos.
Após o LISP, a simplicidade para mim passou a ser minimalismo, simetria, flexibilidade, menos efeitos colaterais, menos funções mais flexíveis que se combinam de uma infinita variedade de maneiras.
Apreciei a mentalidade de que o código mais confiável de todos é o código que não existe. Embora seja apenas uma métrica grosseira, costumo ver o potencial de falta de confiabilidade do código com base em sua quantidade. Buscar a máxima conveniência e legibilidade sintática tende a aumentar essa quantidade por um grande fator.
Minimalismo
Com a mentalidade LISP incorporada em mim, passei a preferir APIs minimalistas. Prefiro uma biblioteca com menos, mas mais confiáveis, funções flexíveis que sejam menos convenientes e com potencialidade mais difícil de ler do que uma que ofereça um monte de ajudantes "convenientes" e que possam facilitar a leitura do código, mas potencialmente tropeçar mais problemas com falta de confiabilidade e surpresas resultantes de mal-entendidos sobre o que uma dessas milhares de funções faz.
Segurança
Outra coisa sobre o LISP era a segurança. Ele promoveu efeitos colaterais mínimos e funções puras, e foi aí que eu não me via mais cometendo erros sutis, mesmo que a dificuldade de ler e escrever no idioma aumentasse os erros mais flagrantes que eu conseguia detectar 10 segundos depois.
Funções puras e estados imutáveis se tornaram preferíveis a mim sempre que eu podia pagar, mesmo que a sintaxe de:
... é um pouco menos direto e distante do pensamento humano do que:
Legibilidade VS. Simplicidade
Mais uma vez, o LISP não é a linguagem mais "legível". Ele pode incluir muita lógica em uma pequena seção de código (possivelmente mais de um pensamento humano por linha). Idealmente, prefiro um pensamento humano por linha para "legibilidade", mas não é necessariamente para "simplicidade".
Com esse tipo de definição de "simples", às vezes "simples" pode, na verdade, competir um pouco com "legível". Isso está considerando coisas mais do ponto de vista do design de interface.
Uma interface simples significa que você precisa aprender muito menos coisas para usá-la e, potencialmente, tem maior confiabilidade e menos problemas como resultado de seu minimalismo. Uma documentação abrangente sobre o assunto pode caber em um livreto, e não em um grande volume de livros. No entanto, pode exigir mais trabalho pesado e produzir código menos legível.
"Simples" para mim melhora nossa capacidade de entender a funcionalidade em nosso sistema em um nível amplo. "Legível" para mim melhora nossa capacidade de conectar cada pequena linha de código à linguagem natural e ao pensamento e pode acelerar nossa compreensão do que uma linha de código faz, especialmente se não somos fluentes na linguagem.
Regex é um exemplo do que considero "extremamente simples". É "simples demais e ilegível" para o meu gosto pessoal. Há um ato de equilíbrio para mim entre esses extremos, mas a regex tem essa qualidade de simplicidade semelhante à LISP como eu a defino: minimalismo, simetria, incrível flexibilidade, confiabilidade etc. O problema para mim com a regex é que é tão simples que tornou-se tão ilegível ao ponto que acho que nunca vou me tornar fluente nisso (meu cérebro simplesmente não funciona dessa maneira e invejo as pessoas que podem escrever código regex fluentemente).
De qualquer forma, essa é minha definição de "simplicidade", e é completamente independente da "legibilidade" e às vezes pode até interferir na outra, levando a um ato de equilíbrio entre uma biblioteca mais "sintaticamente conveniente" e legível, mas maior, ou uma "biblioteca sintaticamente" biblioteca inconveniente ", menos legível e ainda menor. Eu sempre achei as verdadeiras prioridades de "conveniência da compreensão" e de "manutenção" alinhadas com as últimas, com a forte preferência pelo minimalismo, mesmo a algum custo de legibilidade e sintaxe humana mais natural (mas não ao ponto de regex) . YMMV.
fonte
Sempre? - SIM
Atingir o nível certo de simplicidade é uma tarefa complexa e difícil. Mas sempre vale a pena, pois sempre melhora a legibilidade. Eu acho que a chave é um entendimento profundo. Simplicidade é um absoluto, medido por "novos conceitos" por "pedaço" de código. Alguns novos conceitos significam mais simples.
Concentre-se em áreas onde existe um denso conjunto de conceitos e encontre maneiras de "dividir" ou "resumir" ou "abstrair". Faça algumas passagens pelo código para torná-lo mais simples e legível.
Uma boa abstração vale seu peso em ouro. Uma boa abstração torna isso mais simples - e consequentemente mais legível.
fonte
As perguntas me lembram esta resposta no Stack Overflow, particularmente esta citação (substitua qualidade pela simplicidade):
Eu acho que é importante ter em mente que um padrão de codificação codificado para todos os seus benefícios não tornará bons programadores dos ruins. Uma palavra como 'simples' pode ser interpretada de maneira diferente por pessoas diferentes (veja a resposta de Aidan Cully), mas isso pode não ser uma coisa tão ruim. Os programadores juniores ainda precisam ter seu código revisado pelos programadores seniores e aprender por que a interpretação dos programadores seniores de 'simples' é melhor que a sua.
fonte
Uma chamada de função por linha é mais simples? Vamos tentar um exemplo!
O que você acha? Uma chamada por linha é realmente mais simples?
fonte