Posso usar metaprogramação mesmo que nem todos os meus colegas a entendam?

102

Emprego muita metaprogramação para evitar tarefas repetitivas e criar abstrações mais seguras de usar.

Recentemente, mudei para um novo emprego, onde estou trabalhando em uma equipe maior e isso preocupa alguns de meus colegas, porque eles não o compreendem.

Eu sempre tento aproveitar todo o potencial da linguagem, mas alguns (não todos) dos meus colegas percebem isso como um risco (alguns aceitam a abordagem).

Concordo que é um problema escrever código que ninguém mais na equipe possa compreender. Por outro lado, somos todos desenvolvedores profissionais de C ++ e acho que devemos aspirar a um padrão mais alto do que escrever C com classes.

Minha pergunta é: quem está certo, o que devo fazer?

Esclarecimento: Tentar aproveitar todo o potencial do idioma, não significa que eu jogue TMP em todos os problemas. C ++ é uma caixa de ferramentas e, para mim, a proficiência em C ++ é ser capaz de usar todas as ferramentas da caixa e escolher a ferramenta certa para um trabalho específico.

kamikaze
fonte
38
Em última análise, isso é baseado em opiniões. Pessoalmente, faço uma regra para não usar recursos tão complexos que sejam acidentalmente concluídos por Turing - como a metaprogramação de modelos C ++.
Kilian Foth
24
Os modelos @KilianFoth não são "acidentalmente" completos de Turing. Eles estavam sempre a intenção de ser ferramentas poderosas de abstração
Caleth
73
Código que ninguém pode entender não é um padrão mais alto.
gburton
37
@Caleth Herb Sutter os chama acidentalmente como Turing-complete . Claro, eles foram feitos para serem poderosos recursos de abstração, mas não creio que eles tenham a intenção de permitir construções tão misteriosas e indecidíveis quanto a integridade de Turing permitir. E certamente, sua sintaxe não foi projetada para tornar essa metaprogramação menos intransparente do que necessária.
usar o seguinte comando
26
Dicotomia falsa. Você pode programar com um "padrão mais alto" e deixar para trás C com classes, adotar C ++ moderno, usar modelos (por exemplo, o STL), bem como const, no () casting, sem ponteiro aritmético, semântica de valor, semântica de valores, muita bondade, sem cabeçalho ibnto TMP. Se você não vê a luz do dia entre C-com-classes e TMP, está fazendo algo errado.
Kate Gregory

Respostas:

185

Metaprogramação está OK. O que você está tentando fazer não está bem.

Uso metaprogramação o tempo todo no meu trabalho. É uma ferramenta poderosa que pode ser usada para fazer muitas coisas de maneira mais legível e sustentável. Também é um dos mais difíceis de entender os estilos de programação existentes, por isso realmente precisa ser mantido. Gosto quando posso reduzir 1000 linhas de código para 50, mas tento limitá-lo dessa forma.

A questão não é metaprogramação, mas isso:

Por outro lado, somos todos desenvolvedores profissionais de C ++ e acho que devemos aspirar a um padrão mais alto do que escrever C com classes.

É aqui que você entra em apuros. Você tem uma opinião. É bom ter uma opinião de que a metaprogramação é boa. É bom ter uma opinião de que todos devemos aspirar a ser melhores desenvolvedores de C ++.

Não é bom obrigar seus colegas e futuros contratados que terão que manter o código que você escreveu para concordar com sua opinião. Esse é o trabalho do seu chefe. Seu chefe é quem deve se preocupar em garantir que seu código seja sustentável a longo prazo. Eles (espero) têm muito mais experiência comercial, porque acredite em mim quando digo que é uma decisão de negócios, não uma decisão ideológica.

É bom querer metaprograma. É bom querer ensinar os outros a metaprogramas. Mas entenda que também é bom que outras pessoas escolham não aprender a metaprograma, e isso será verdade até que você esteja em uma posição de poder. (e, como segredo da indústria: quando você finalmente é um desenvolvedor líder, em uma posição de poder, você não está em uma posição de poder. Há alguém controlando os perseguidores que estão no poder).

Se você deseja incentivá- los a concordar com a metaprogramação, comece pequeno . Comece com um enable_ifque facilite a leitura da API. Em seguida, comente a luz do dia . Talvez encontre um caso em que uma metafunção de modelo transforme 10 grandes classes repetitivas em 1 classe com 10 pequenos ajudantes. Comente o que há com isso. Obter feedback. Descubra o que as pessoas pensam sobre isso. Fique bem se eles disserem para não fazê-lo. Encontre um nicho em que a metaprogramação seja mantida tão completamente que seus colegas concordem (relutantemente) que era a ferramenta certa para o trabalho.

Como um conto, escrevi uma bela biblioteca uma vez, usando uma extensa metaprogramação. Ele fez exatamente o que precisávamos no momento, quando nenhuma outra abordagem poderia se aproximar remotamente. Na verdade, mudou a direção do aplicativo em que eu estava escrevendo. Mas foi metaprogramação. Somente uma ou duas outras pessoas em toda a minha empresa puderam lê-lo.

Mais tarde, meu colega deu outra facada no problema. Em vez de alavancar a metaprogramação para fazer exatamente o que era necessário, ele trabalhou com a liderança para diminuir as restrições impostas ao problema, de modo que a metaprogramação não era necessária. Talvez com mais precisão, a metaprogramação fosse menos necessária. Ele foi capaz de limitar o que a metaprogramação faz melhor.

A biblioteca resultante agora está em posição de ser usada em um mercado notavelmente amplo, e isso certamente não é em grande parte devido ao fato de que o novo código pode ser mantido por uma gama muito maior de desenvolvedores. Tenho orgulho de abrir o caminho com a metaprogramação, mas é o código do meu colega que atingirá o público em geral, e há boas razões para isso.

Cort Ammon
fonte
72
Substitua "metaprogramação" por outro estilo, técnica, tecnologia, biblioteca e a resposta ainda é ótima!
187 Andrejs
4
Seu chefe é quem deve se preocupar em garantir que seu código seja sustentável a longo prazo. A maioria dos chefes nem sabe o que é manutenção de código. Eles praticamente não têm conhecimento técnico, então eu não confiaria nas decisões deles que têm um caráter político.
T3chb0t
4
@ t3chb0t: Um chefe experiente sabe quanto dinheiro deve ser gasto em atendimento ao cliente (ou seja, correção de bugs e novos recursos) e como minimizar esse custo. A manutenção é a ferramenta mais poderosa para esse fim. Esse chefe pode não conhecer detalhes técnicos, mas deve ser capaz de formar uma equipe confiável nesse ponto.
Mouviciel 4/03/18
25
@DDrmmr Eu dei o tom para alguém que acredita que os programadores devem usar metaprogramação para elevar o padrão. Não acho que deva ser confundido com o local onde o membro da equipe menos qualificado pode mantê-lo. Deve ser embaçado até onde a equipe pode mantê-lo, e talvez ainda mais forte, deve estar embaçado até onde a equipe pode mantê-lo sem você . Caso contrário, alguém está escrevendo um trabalho para si mesmo.
Cort Ammon
15
@ Josué O que eu descobri é que não existe algo como "código que não precise de manutenção".
precisa
39

Primeiro e acima de tudo, esse é um problema da equipe, e você deve resolvê-lo com a equipe. Se você tiver backup da equipe para programar usando certos elementos e construções, faça-o; caso contrário, discuta-o com eles e se você não conseguir convencê-los e argumentar com firmeza por que "sua abordagem" é claramente melhor, será melhor não usá-la.

Observe que o uso da meta-programação de modelos no C ++ é sempre uma troca: com certeza, às vezes, pode ajudar a projetar certas partes de um aplicativo com mais DRY, e é definitivamente útil para criar bibliotecas altamente eficientes e altamente reutilizáveis.

Por outro lado, esses benefícios têm um certo custo: o código fica mais abstrato, geralmente muito mais difícil de ler, muito mais difícil de depurar e muito mais difícil de manter. Isso torna questionável a utilidade da metaprogramação na programação de aplicativos. Portanto, supondo que você não criará o próximo STL, toda vez que tentar usar a metaprogramação, pergunte a si mesmo se essas desvantagens realmente valem a pena. E se você não tiver certeza, discuta isso com seu revisor durante a revisão do código.

Doc Brown
fonte
Concordo, mas discuto-o com o controle de qualidade antes de inseri-lo no código. Não faz sentido criar algo que será rejeitado.
Shawnhcorey 03/03
8
Que tal: "Eu concordo. Mas ..." Alterar para "para" altera completamente o significado. Sempre se deve discutir algo incomum com o controle de qualidade antes que o tempo seja gasto. Você declarou que essa discussão deve ocorrer na revisão do código, após o tempo gasto.
precisa saber é o seguinte
@ shawnhcorey: claro, se o "controle de qualidade" da sua organização for responsável pelos padrões de codificação. No entanto, esse IMHO não é o papel típico de "controle de qualidade" - na maioria das organizações que eu conheço, o termo "controle de qualidade" refere-se a um grupo de pessoas que fazem garantia de qualidade em uma caixa preta, não responsável por quais elementos de uma linguagem de programação devem ser usado e quais não. Essas pessoas raramente são qualificadas o suficiente em programação para discutir esses detalhes.
Doc Brown
2
@ shawnhcorey: esse é exatamente o meu ponto, o papel do controle de qualidade varia muito em diferentes organizações. Em muitas organizações, o pessoal de controle de qualidade não tem idéia de programação, portanto provavelmente não é o ideal para discutir esse tópico.
Doc Brown
2
@ shawnhcorey: bem, por um lado, você escreveu "QA é um termo genérico" - por outro, você tem um papel e uma responsabilidade muito específicos em QA - parece um pouco contraditório para mim.
Doc Brown
18

Minha opinião geral: se você tiver uma escolha, como geralmente acontece, entre as três opções a seguir:

  • Digite muitas estruturas de código não triviais repetidamente à mão;
  • Use a metaprogramação de modelos C ++ para automatizar a geração de código;
  • Use algum outro mecanismo de geração de código, como macros ou alguma outra linguagem de programação para gerar arquivos de origem C ++

a metaprogramação de modelos, feita corretamente, provavelmente será a mais legível e sustentável das três opções. Esse é o argumento que eu faria para a equipe, se estivesse na sua posição. Exemplos com código real ajudariam a convencê-los.

Ao usar a Metaprogramação de modelos ( TMP ) para evitar repetição, você deve usá-lo para construir abstrações bem documentadas e cuidadosamente testadas que localizam a complexidade no código TMP, facilitando a gravação correta do código do cliente. Esse é o design da biblioteca padrão C ++.

Não acho que possamos julgar quem está certo ou errado sem ver um exemplo do tipo de código que você está tentando escrever.

Brian
fonte
2
Você também pode usar cópia + colar em vez de digitá-la à mão ;-)
Paulo Ebermann
4
@ PaŭloEbermann: Parreira não!
Joshua
2
Na PaŭloEbermann, uma loja em que eu chamei essa abordagem de "erro de marca de início, erro de marca de fim, cópia de bug, cópia de bug, cópia de bug".
Kelly S. Francês
12

Os desenvolvedores de software devem aspirar a escrever código que funcione, que funcione obviamente, que possa ser testado, revisado, depurado e que possa ser adaptado quando forem necessárias alterações. Se escrever "C com classes" conseguir isso, tudo bem.

E esses são os padrões contra os quais você deve medir seu código. Especialmente: Funciona obviamente, pode ser testado, pode ser revisado, pode ser depurado e pode ser adaptado quando necessário?

gnasher729
fonte
9

Um argumento da compaixão:

Seu trabalho oferece tempo livre para aprender ou, alternativamente, você pode convencer seus chefes a alocarem algumas horas para aprender esses recursos de idioma?

Caso contrário, usá-los é essencialmente dar a eles um trabalho extra não remunerado. Você pode pensar que um programador de C ++ deve conhecer toda a linguagem, ou algo assim, mas um ponto acadêmico não alivia o fardo que você lhes impõe. Seus colegas têm filhos, pais doentes, cônjuges doentes - ou inferno, apenas uma vida social razoável que não envolve aprender C ++. O oponente mais vocal da sua proposta pode ser preguiçoso - ou pode estar passando por um momento difícil e não precisa de nada extra na vida deles agora.

André Paramés
fonte
8

O código deve ser escrito primeiro para que os humanos leiam e, incidentalmente, para o compilador analisar.

Agora, o que deve ser lembrado sobre o TMP não trivial é que você está restringindo o número de pessoas que podem ler esse código; pode ser uma troca válida, mas eu argumentaria que é muito mais uma troca razoável nas bibliotecas e onde você tem um Se uma pequena equipe de especialistas estiver em uma aplicação maior.

Quando você adota todos os truques do livro, impõe custos a todos os demais, pois agora eles precisam entender o idioma, incluindo todos os casos de advogados que você explorou, também impõe um custo de contratação, pois elevou a fasquia para trabalhar no aplicativo de uma maneira útil, agora talvez valha a pena, mas observe os custos ....

Para mim, um pouco mais de digitação, talvez até alguma duplicação de código, mas que eu possa colocar na frente do Sr. "C com classes mais STL" quando precisar de modificação é muito mais útil do que algo incrivelmente elegante do TMP que só eu posso manter (E, portanto, manterá para sempre). Lembre-se também de que o especialista em C com aulas pode ser o especialista no assunto, e esse conhecimento geralmente é muito mais valioso do que ser um advogado de idiomas.

Eu esqueço quem disse isso, mas "Todo mundo sabe que a depuração é mais difícil do que escrevê-la. Portanto, se você programá-la da maneira mais inteligente possível, como será que você a depurará?".

Mesmo que eu possa escrever realmente em C ++ moderno, geralmente prefiro não, significa que tenho que fazer menos da programação de manutenção.

Dan Mills
fonte
7

Não você não deveria. Você é empregado para produzir código que atenda a uma especificação. Este código deve ser sustentável e não uma viagem ao ego. Você pode ser atropelado por um ônibus amanhã, para que alguém possa pegar seu código e progredir na tarefa em mãos. No entanto, é positivo tentar convencer seus empregadores a incorporar novas técnicas em seus padrões de programação.

Darryl SCOTT
fonte
3
Você é empregado para produzir código que atenda a uma especificação. sim, mas você está esquecendo isso também com o melhor de conhecimento .
T3chb0t
2

A única maneira de responder a essa pergunta no contexto é examinar os problemas específicos e a maneira específica como você os resolveu com a meta programação. A menos que você publique código aqui, não podemos saber se você se entregou a uma complicação desnecessária que é divertida apenas para você "resolver" um problema inexistente; ou se você empregou todo o poder do idioma para escrever uma solução simples e elegante, não disponível por outros meios.

Se for o último, eu encorajo você a continuar fazendo isso junto com sua equipe.Toda boa equipe deve fazer análises significativas de código que discutam não apenas questões de estilo, mas também se a solução do programador usa a melhor abordagem, usa os recursos de linguagem apropriados, é sustentável e testável etc. Sua solução de meta programação deve preencher uma dessas sessões de revisão, provavelmente uma a tarde toda. Os programadores que rejeitarem sua abordagem devem apresentar alternativas (como geração de código com perl, duplicação de código etc.) e mostrar como ele funciona de acordo com os critérios mencionados, em comparação com a sua solução. Seu trabalho, como seu amigável "oponente" na discussão, é mostrar que é uma maneira de fazer o trabalho rapidamente, que a manutenção é fácil, os testes são fáceis e o código é legível assim que você passa pelo obstáculo de analisando a gramática engraçada.

A maioria dos programadores é preguiçosa e desfruta de pequenas soluções elegantes. Se o seu for um, é provável que você possa convencê-los, especialmente se as alternativas demonstradas forem insuficientes.

Peter A. Schneider
fonte
0

Não existe uma única resposta correta para esta pergunta.

Porque a primeira coisa que você deve se perguntar é: em que situação você é colocado pelo seu emprego? Algumas pessoas são realmente empregadas como macacos de código para codificar especificações, outras são empregadas como jogadores de equipe, outras são empregadas como trabalhadores do conhecimento ou especialistas.

A única linha de fundo constante é que você precisa analisá-lo da perspectiva de seu empregador, já que essencialmente isso significa ser um funcionário. Às vezes, é do melhor interesse do seu empregador, de fato, convencer seus colegas a melhorar e dominar técnicas avançadas. No entanto, em uma situação diferente, você pode apenas criar muitos problemas e responsabilidades e comprometer o sucesso dos projetos nos quais está envolvido.

Ichthyo
fonte
-4

A questão não é realmente se a metaprogramação é boa ou não, mas sim se é melhor ser melhor que os outros membros da equipe, então aqui estão alguns pontos controversos sobre como eu a vejo ...


Recentemente, mudei para um novo emprego, onde estou trabalhando em uma equipe maior e isso [metaprogramação] preocupa alguns de meus colegas, porque eles não o compreendem.

Eles estão preocupados que você seja melhor que eles. Isso é bom. Você será o novo especialista. Você acabou de destruir o mundo do status quo deles.


Eu sempre tento aproveitar todo o potencial da linguagem, mas alguns (não todos) dos meus colegas percebem isso como um risco (alguns aceitam a abordagem).

Claro, ninguém gosta de ser menos habilidoso do que qualquer outra pessoa, então eles estão tentando impedi-lo de usar técnicas que são muito complexas para eles. Eles não podem compreendê-lo ou não vão, porque se sentem seguros agora.


Concordo que é um problema escrever código que ninguém mais na equipe possa compreender.

Eu não. Eu acho que está mostrando sua experiência.


Minha pergunta é: quem está certo, o que devo fazer?

Você deve usar todas as suas habilidades para escrever o melhor código possível e não olhar para trás para aqueles que não o entendem. Caso contrário, você ficará preso no nível deles e será apenas um codificador comum. É bom ser melhor que os outros, e é bom se esforçar para ser melhor que eles. Você nunca ganhará nenhuma nova experiência se não tentar usar algo novo ou fazer coisas diferentes.


Eu sei que vou ter voto negativo, mas é assim que parece. Não é crime ser melhor que os outros da equipe, e não é crime usar suas habilidades. Só que todo mundo tem medo de admitir ... porque eles são do lado não qualificado e odeiam que o novo cara possa fazer algo que de repente não pode. Se eles fossem espertos, pediam ajuda e conselhos e não criticavam seu código por ser incompreensível.


EDITAR

Parece haver muita confusão sobre essa questão. Como os comentários mostram, muitas pessoas pensam que é sobre legibilidade geral do código. Não, não é. É sobre se certos recursos / construções de idiomas devem ser proibidos ou evitados, porque alguns membros da equipe não os entendem.

Minha resposta é não . Eles não devem ser proibidos. Se você quer proibir algo, como faria isso? Você precisaria preparar algum tipo de questionário para descobrir o que os membros da sua equipe podem ou não - ou melhor, não querem aprender, pois acho que todos os recursos da languague são úteis em algum lugar, portanto, conhecê-los e poder usá-los é sempre bom e quanto mais você souber, melhor o código poderá escrever. Você também precisaria de uma escala para definir quais recursos são iniciantes, intermediários ou avançados.

Para demonstrar o quão tolas são essas restrições, vamos dar um exemplo muito simples: você será contratado como engenheiro de software, mas seu futuro chefe lhe dirá que não será permitido o uso de do/whileloops, porque existem algumas pessoas a equipe que nunca os usou antes e também não o faz, porque sempre usa forloops para tudo, para que eles considerem do/whileconfusos.

Agora você acha que isso é estúpido e louco, não é? Mas o mesmo está proibindo outros recursos. Alguns podem usá-los e outros não querem aprendê-los.

Por que você deveria produzir código pior se você sabe que existe algo que permite fazer o mesmo com muito menos esforço e ainda assim resultar em um código robusto e muito mais legível?

E não importa se você usa apenas recursos básicos de linguagem ou avançados, você pode usar qualquer um deles para produzir um código igualmente incompreensível e impossível de manter; portanto, este é um tópico totalmente diferente.

t3chb0t
fonte
10
Essa resposta é horrível. Meta-programação não implica a supremacia e vice-versa
polfosol
9
Na minha experiência, quem sente fortemente que possui um nível de experiência significativamente mais alto do que o restante de sua equipe foi realmente vítima do efeito Dunning-Kruger. Isso não quer dizer que algumas pessoas não são muito mais hábeis que outras, ou que , nesse caso , o resto da equipe não é de fato incompetente ... mas um verdadeiro especialista sempre se concentrará em códigos simples e no cenário geral. engenharia (incluindo a contabilização dos efeitos da equipe ao longo do tempo), em vez de apenas programar pontos de estilo.
precisa saber é o seguinte
3
Escrever código que outras pessoas não conseguem ler não prova que você é melhor que eles. Isso prova que você não pode escrever código legível.
Stig Hemmer #
3
@StigHemmer, aparentemente, você não entendeu a pergunta e está mudando de assunto. Não se trata de código não legível, mas de código incompreensível para outros devido à falta de conhecimento.
T3chb0t
4
@ t3chb0t Meu argumento é que esses dois são a mesma coisa.
Stig Hemmer #