¿Está bien usar metaprogramación aunque no todos mis colegas lo entiendan?

102

Utilizo mucha metaprogramación para evitar tareas repetitivas y construir abstracciones más seguras de usar.

Recientemente me mudé a un nuevo trabajo donde estoy trabajando en un equipo más grande y esto preocupa a algunos de mis colegas, porque no lo comprenden.

Siempre trato de aprovechar todo el potencial del lenguaje, pero algunos (no todos) de mis colegas lo perciben como un riesgo (algunos agradecen el enfoque).

Estoy de acuerdo en que es un problema escribir código que nadie más en el equipo pueda comprender. Por otro lado, todos somos desarrolladores profesionales de C ++ y creo que deberíamos aspirar a un estándar más alto que escribir C con clases.

Mi pregunta es, ¿quién tiene razón, qué debo hacer?

Aclaración: Tratar de aprovechar todo el potencial del lenguaje no significa que arroje TMP a cada problema. C ++ es una caja de herramientas y, para mí, el dominio de C ++ consiste en poder utilizar todas las herramientas de la caja y elegir la correcta para un trabajo en particular.

kamikaze
fuente
38
Esto es en última instancia basado en la opinión. Personalmente, establezco una regla para no usar funciones tan complejas que se completen accidentalmente con Turing, como la metaprogramación de plantillas de C ++.
Kilian Foth
24
Las plantillas de @KilianFoth no se completan "accidentalmente" con Turing. Siempre pretendieron ser poderosas herramientas de abstracción
Caleth
73
El código que nadie puede entender no es un estándar más alto.
gburton
37
@Caleth Herb Sutter los llama accidentalmente Turing-complete . Claro, estaban destinados a ser poderosas características de abstracción, pero no creo que estuvieran destinados a permitir construcciones tan arcanas e indecidibles como lo permite la integridad de Turing. Y ciertamente, su sintaxis no fue diseñada para hacer que esa metaprogramación sea menos intransparente de lo necesario.
Leftaroundabout
26
Falsa dicotomía. Puede programar en un "estándar más alto" y dejar atrás C con clases, adoptar C ++ moderno, usar plantillas (por ejemplo, el STL) así como const, no () casting, sin aritmética de puntero, semántica de valores, mucha bondad, sin encabezado ibnto TMP. Si no ve la luz del día entre C-with-classes y TMP, lo está haciendo mal.
Kate Gregory

Respuestas:

185

La metaprogramación está bien. Lo que intentas hacer no está bien.

Uso metaprogramación todo el tiempo en mi trabajo. Es una herramienta poderosa que se puede utilizar para hacer muchas cosas de una manera más fácil de leer y mantener. También es uno de los estilos de programación más difíciles de comprender, por lo que realmente necesita ganarse la vida. Me gusta cuando puedo reducir 1000 líneas de código a 50, pero trato de limitarlo como tal.

El problema no es la metaprogramación, sino esto:

Por otro lado, todos somos desarrolladores profesionales de C ++ y creo que deberíamos aspirar a un estándar más alto que escribir C con clases.

Aquí es donde te metes en problemas. Tienes una opinion. Está bien tener una opinión de que la metaprogramación es buena. Está bien tener una opinión de que todos debemos aspirar a ser mejores desarrolladores de C ++.

No está bien obligar tanto a sus colegas como a los futuros empleados que tendrán que mantener el código que escribió para aceptar su opinión. Ese es el trabajo de tu jefe. Su jefe es el que debe preocuparse por asegurarse de que su código sea mantenible a largo plazo. Ellos (con suerte) tienen mucha más experiencia en negocios, porque créanme cuando digo que es una decisión comercial, no una decisión ideológica.

Está bien querer metaprogramar. Está bien querer enseñar a otros a metaprogramar. Pero comprenda que también está bien que otros elijan no aprender a metaprogramar, y eso será cierto hasta que estén en una posición de poder. (y, como un secreto de la industria: cuando finalmente eres un desarrollador líder, en una posición de poder, no estás en una posición de poder en absoluto. Hay alguien que controla las cadenas monetarias que está en el poder).

Si desea alentarlos a que estén de acuerdo con la metaprogramación, comience con poco . Comience con un sencillo enable_ifque haga que la API sea más fácil de leer. Luego comente la luz del día . Entonces, tal vez encuentre un caso en el que una metafunción de plantilla convierta 10 clases repetitivas grandes en 1 clase con 10 pequeños ayudantes. Comenta el demonio. Obtenga comentarios Encuentra lo que la gente piensa al respecto. Esté bien si le dicen que no lo haga. Encuentre un nicho donde la metaprogramación se mantenga tan a fondo que todos sus colegas (de mala gana) estén de acuerdo en que era la herramienta adecuada para el trabajo.

Como cuento, una vez escribí una hermosa biblioteca, usando una extensa metaprogramación. Se hizo exactamente lo que necesitábamos en el momento, cuando no hay otro enfoque podría obtener remotamente cerca. En realidad, cambió la dirección de la aplicación en la que estaba escribiendo. Pero fue metaprogramación. Solo una o dos personas en toda mi compañía podían leerlo.

Más tarde, mi colega le dio otra puñalada al problema. En lugar de aprovechar la metaprogramación para hacer con precisión lo que se necesitaba, trabajó con el liderazgo para relajar las limitaciones que se habían puesto en el problema de modo que la metaprogramación no fuera necesaria. Quizás más exactamente, la metaprogramación era menos necesaria. Pudo limitarlo a lo que la metaprogramación hace mejor.

La biblioteca resultante está ahora en condiciones de ser utilizada en un mercado notablemente amplio, y eso no es en gran parte debido al hecho de que el nuevo código puede ser mantenido por una gama mucho más amplia de desarrolladores. Estoy orgulloso de allanar el camino con la metaprogramación, pero es el código de mi colega el que llegará al público más amplio, y hay buenas razones para ello.

Cort Ammon
fuente
72
Reemplace la "metaprogramación" con algún otro estilo, técnica, tecnología, biblioteca, ¡y la respuesta sigue siendo excelente!
Andrejs
44
Su jefe es el que debe preocuparse por asegurarse de que su código sea mantenible a largo plazo. La mayoría de los jefes ni siquiera saben qué es la mantenibilidad del código. No tienen prácticamente ningún conocimiento técnico, por lo que no confiaría en sus decisiones que tienen un carácter político.
t3chb0t
44
@ t3chb0t: Un jefe experimentado sabe cuánto dinero debe gastarse en servicio al cliente (es decir, corrección de errores y nuevas funciones) y cómo minimizar ese costo. La mantenibilidad es la herramienta más poderosa para ese propósito. Es posible que ese jefe no conozca los detalles técnicos, pero debería ser capaz de construir un equipo en el que se pueda confiar en ese punto.
Mouviciel
25
@DDrmmr Establecí el tono para alguien que cree que los programadores deberían usar la metaprogramación para elevar el estándar. No creo que deba reducirse a donde el miembro del equipo menos capacitado pueda mantenerlo. Debería reducirse a donde el equipo puede mantenerlo, y quizás aún más fuerte, debería reducirse a donde el equipo puede mantenerlo sin usted . De lo contrario, uno se está escribiendo un trabajo.
Cort Ammon
15
@Joshua Lo que he encontrado es que no existe tal cosa como "código que no necesita mantenimiento".
Cort Ammon
39

En primer lugar, este es el problema del equipo, y debes resolverlo con el equipo. Si tiene una copia de seguridad del equipo para programar utilizando ciertos elementos y construcciones, hágalo; si no, hable con ellos y si no puede convencerlos y exponga un argumento sólido de por qué "su enfoque" es claramente mejor, será mejor que no lo use.

Tenga en cuenta que el uso de metaprogramación de plantillas en C ++ siempre es una compensación: claro, a veces puede ayudar a diseñar ciertas partes de una aplicación más SECAS, y definitivamente es útil para crear bibliotecas altamente eficientes y altamente reutilizables.

Por otro lado, estos beneficios tienen cierto costo: el código se vuelve más abstracto, a menudo mucho más difícil de leer, mucho más difícil de depurar y mucho más difícil de mantener. Esto hace que la utilidad de la metaprogramación en la programación de aplicaciones a menudo sea cuestionable. Por lo tanto, suponiendo que no va a crear el próximo STL, cada vez que tenga la tentación de usar metaprogramación, pregúntese si esos inconvenientes realmente valen la pena. Y si no está seguro, discuta esto con su revisor durante la revisión del código.

Doc Brown
fuente
Estoy de acuerdo, pero discútalo con QA antes de ponerlo en código. No tiene sentido crear algo que será rechazado.
shawnhcorey
8
Qué tal: "Estoy de acuerdo. Pero ..." Cambiarlo a "a" cambia completamente el significado. Siempre se debe discutir algo inusual con el control de calidad antes de dedicarle tiempo. Usted dijo que esta discusión debería tener lugar en la revisión del código, después de que se dedique el tiempo.
shawnhcorey
@shawnhcorey: claro, si "QA" en su organización es responsable de los estándares de codificación. Sin embargo, en mi humilde opinión, este no es el rol típico de "QA": en la mayoría de las organizaciones que conozco, el término "QA" se refiere a un grupo de personas que hacen el aseguramiento de la calidad de una manera de caja negra, no responsables de qué elementos de un lenguaje de programación deberían ser usado y cual no. Esas personas rara vez están lo suficientemente calificadas en programación para discutir tales detalles.
Doc Brown
2
@shawnhcorey: ese es exactamente mi punto, el rol de control de calidad varía mucho en las diferentes organizaciones. En muchas organizaciones, las personas de control de calidad no tienen idea de la programación, por lo que probablemente no sean las correctas para discutir un tema de este tipo.
Doc Brown
2
@shawnhcorey: bueno, por un lado escribiste "QA es un término genérico", por otro lado, tienes un rol y una responsabilidad de QA muy específicos en mente, me parece un poco contradictorio.
Doc Brown
18

Mi opinión general: si tiene una opción, como suele ser el caso, entre las siguientes tres opciones:

  • Escriba muchas estructuras de código no triviales repetidamente a mano;
  • Utilice la metaprogramación de plantillas C ++ para automatizar la generación de código;
  • Utilice algún otro mecanismo de generación de código, como macros u otro lenguaje de programación para generar archivos fuente C ++

luego, la metaprogramación de la plantilla, realizada correctamente, probablemente sea la más legible y mantenible de las tres opciones. Este es el argumento que haría al equipo, si estuviera en su posición. Los ejemplos con código real ayudarían a convencerlos.

Cuando usa la Metaprogramación de plantillas ( TMP ) para evitar la repetición, debe usarla para construir abstracciones bien documentadas y cuidadosamente probadas que localicen la complejidad dentro del código TMP, lo que facilita la escritura del código correcto del cliente. Este es el diseño de la biblioteca estándar de C ++.

No creo que podamos juzgar quién tiene razón o no sin ver un ejemplo del tipo de código que está tratando de escribir.

Brian
fuente
2
También puede usar copiar + pegar en lugar de escribirlo a mano ;-)
Paŭlo Ebermann
44
@ PaŭloEbermann: ¡Diablos, no!
Joshua
2
@ PaŭloEbermann, una tienda en la que estaba llamado ese enfoque, "comienzo-marca-error, fin-marca-error, copia-error, copia-error, copia-error".
Kelly S. French
12

Los desarrolladores de software deberían aspirar a escribir código que funcione, que funcione obviamente, que pueda probarse, revisarse, depurarse y adaptarse cuando se necesiten cambios. Si escribir "C con clases" logra esto, entonces está bien.

Y estos son los estándares con los que debe medir su código. Especialmente: ¿Funciona obviamente, se puede probar, se puede revisar, se puede depurar y se puede adaptar cuando sea necesario?

gnasher729
fuente
9

Un argumento de compasión:

¿Su trabajo le da tiempo libre para aprender o, como alternativa, puede convencer a sus jefes de que asignen algunas horas para aprender estas características del lenguaje?

De lo contrario, usarlos es esencialmente darles un trabajo extra no remunerado. Puede pensar que un programador de C ++ debería conocer todo el lenguaje, o algo así, pero un punto académico no alivia la carga que le impondrá. Sus colegas tienen hijos, padres enfermos, cónyuges enfermos o, simplemente, una vida social razonable que no implica aprender C ++. El oponente más vocal de su propuesta puede ser flojo, o pueden estar pasando por un mal momento y no necesitan mierda extra en su vida en este momento.

André Paramés
fuente
8

El código debe escribirse primero para que los humanos lo lean, y solo de manera incidental para que el compilador lo analice.

Ahora, lo que debe recordar acerca de TMP no trivial es que está restringiendo la cantidad de personas que pueden leer ese código, puede ser una compensación válida, pero diría que es una compensación mucho más razonable en las bibliotecas y en los casos en que tiene un pequeño equipo de expertos especialistas, entonces está en una aplicación más grande

Cuando saca todos los trucos en el libro, impone costos a todos los demás, ya que ahora necesitan entender el lenguaje, incluidos todos los casos de esquina de abogados que ha explotado, también impone un costo en la contratación en el que ha elevado el listón trabajar en la aplicación de una manera útil, ahora quizás valga la pena, pero tenga cuidado con los costos ...

Para mí, escribir un poco más, tal vez incluso algo de duplicación de código, pero que puedo poner delante del Sr. "C con clases más STL" cuando necesita modificación es mucho más útil que algo de TMP increíblemente elegante que solo yo puedo mantener (Y por lo tanto se mantendrá para siempre). Recuerde también que el tipo C con clases podría ser el experto en la materia, y esa experiencia suele ser mucho más valiosa que ser un abogado de idiomas.

Olvidé quién lo dijo, pero "Todo el mundo sabe que depurar es más difícil que escribirlo en primer lugar, así que si lo programa de la manera más inteligente posible, ¿cómo lo depurará alguna vez?".

Incluso si puedo escribir realmente C ++ moderno, generalmente prefiero no hacerlo, significa que tengo que hacer menos programación de mantenimiento.

Dan Mills
fuente
7

No, no deberías. Usted está empleado para producir código que satisfaga una especificación. Este código tiene que ser mantenible, no un viaje de ego. Podría ser atropellado por un autobús mañana, por lo que alguien debe poder recoger su código y avanzar en la tarea en cuestión. Sin embargo, es positivo tratar de convencer a sus empleadores de que incorporen nuevas técnicas en sus estándares de programación.

Darryl SCOTT
fuente
3
Usted está empleado para producir código que satisfaga una especificación. sí, pero lo estás olvidando también al mejor de los conocimientos .
t3chb0t
2

La única forma de responder a esta pregunta en contexto es observar los problemas específicos y la forma específica en que los resolvió con meta programación. A menos que publique el código aquí, no podemos saber si se ha involucrado en una complicación innecesaria que es divertida para usted solo "resolviendo" un problema inexistente; o si empleó todo el poder del idioma para escribir una solución simple y elegante que no está disponible por otros medios.

Si es lo último, le animo a que continúe haciéndolo junto con su equipo.Todo buen equipo debe hacer revisiones de código significativas que discutan no solo los problemas de estilo, sino también si la solución del programador utiliza el mejor enfoque, usa las características de lenguaje apropiadas, es mantenible y comprobable, etc. Su solución de meta programación debe completar una de esas sesiones de revisión, probablemente un toda la tarde. Los programadores que rechazan su enfoque deben diseñar alternativas (como la generación de código con perl, la duplicación de código, etc.) y mostrar cómo funciona según los criterios mencionados, en comparación con su solución. Su trabajo, como su "oponente" amistoso en el argumento, es mostrar que es una forma de hacer el trabajo rápidamente, que el mantenimiento es fácil, las pruebas son fáciles y el código es realmente legible una vez que supere el obstáculo de analizando la gramática graciosa.

La mayoría de los programadores son flojos y disfrutan de soluciones elegantes y pequeñas. Si el suyo es uno, es probable que pueda convencerlos, especialmente si las alternativas demostradas no son suficientes.

Peter A. Schneider
fuente
0

No hay una sola respuesta correcta a esta pregunta.

Porque lo primero que debe preguntarse es: ¿en qué situación se encuentra su empleo? De hecho, algunas personas se emplean como monos de código para codificar especificaciones, otras se emplean como jugadores de equipo, otras se emplean como trabajadores del conocimiento o expertos.

El único resultado final constante es que debe verlo desde la perspectiva de su empleador, ya que esencialmente esto significa ser un empleado. A veces, lo más conveniente para su empleador es empujar a sus colegas para que sean mejores y dominen las técnicas avanzadas. Sin embargo, en una situación diferente, podría crear muchos problemas y responsabilidades y poner en peligro el éxito de los proyectos en los que está involucrado.

Ichthyo
fuente
-4

La pregunta no es realmente si la metaprogramación está bien o no, sino más bien si está bien ser mejor que los demás en el equipo, así que aquí hay algunos puntos controvertidos sobre cómo lo veo ...


Recientemente me mudé a un nuevo trabajo donde estoy trabajando en un equipo más grande y esto [metaprogramación] preocupa a algunos de mis colegas, porque no lo comprenden.

Les preocupa que seas mejor que ellos. Eso es bueno. Serás el nuevo experto. Acabas de destruir su mundo de status quo.


Siempre trato de aprovechar todo el potencial del lenguaje, pero algunos (no todos) de mis colegas lo perciben como un riesgo (algunos agradecen el enfoque).

Claro, a nadie le gusta ser menos hábil que cualquier otra persona, por lo que están tratando de evitar que uses técnicas que son demasiado complejas para ellos. O no pueden comprenderlo o no lo harán, porque ahora se sienten seguros.


Estoy de acuerdo en que es un problema escribir código que nadie más en el equipo pueda comprender.

Yo no. Creo que está mostrando tu experiencia.


Mi pregunta es, ¿quién tiene razón, qué debo hacer?

Debe usar todas sus habilidades para escribir el mejor código que pueda escribir y no mirar hacia atrás a aquellos que no lo entienden. De lo contrario, te quedarás atascado en su nivel y serás un simple codificador. Es bueno ser mejor que otros, y es bueno esforzarse por ser mejor que ellos. Nunca obtendrás ninguna experiencia nueva si no intentas usar algo nuevo o hacer las cosas de manera diferente.


Sé que voy a ser rechazado, pero así es como se ve. No es un crimen ser mejor que otros en el equipo, y no es un crimen usar tus habilidades. Es solo que todos tienen miedo de admitirlo ... porque están en el lado no calificado y odian que el nuevo chico de repente pueda hacer algo que no puede. Si fueran inteligentes, le pedirían ayuda y consejos y no criticarían su código por ser incomprensible.


EDITAR

Parece haber mucha confusión sobre esta pregunta. Como muestran los comentarios, muchas personas piensan que se trata de la legibilidad general del código. No, no es. Se trata de si ciertas características / construcciones del lenguaje deben prohibirse o evitarse porque algunos miembros del equipo no las entienden.

Mi respuesta es no . No deberían estar prohibidos. Si quieres prohibir algo, ¿cómo lo harías? Tendría que preparar algún tipo de cuestionario para averiguar qué pueden y qué no pueden aprender los miembros de su equipo, o más bien no quieren aprender, ya que creo que todas las características del lenguaje son útiles en algún lugar, por lo que conocerlas y poder usarlas siempre es bueno y cuanto más sepa, mejor código podrá escribir. También necesitaría una escala para definir qué características son principiantes, intermedias o avanzadas.

Para demostrar cuán tontas son tales restricciones, tomemos un ejemplo realmente simple: va a ser contratado como ingeniero de software pero su futuro jefe le dice que no se le permitirá usar do/whilebucles porque hay un par de personas en el equipo que nunca los ha usado antes y que tampoco lo harán porque siempre han estado usando forbucles para todo, por lo que los encuentran do/whileconfusos.

Ahora crees que esto es estúpido y loco, ¿no? Pero también está prohibiendo otras características. Algunas personas pueden usarlas y otras no quieren aprenderlas.

¿Por qué debería producir un código peor si sabe que hay algo que le permite hacer lo mismo con mucho menos esfuerzo y, sin embargo, resulta en un código robusto mucho más legible?

Y no importa si usa solo funciones de lenguaje básicas o avanzadas, puede usar cualquiera de las dos para producir un código igualmente incomprensible e imposible de mantener, por lo que este es un tema completamente diferente.

t3chb0t
fuente
10
Esta respuesta es horrible. La
metaprogramación
99
En mi experiencia, cualquiera que sienta firmemente que tiene un nivel significativamente más alto de experiencia que el resto de su equipo ha sido víctima del efecto Dunning-Kruger. Eso no quiere decir que algunas personas no sean mucho más hábiles que otras, o que en este caso , el resto del equipo no sea realmente incompetente ... pero un verdadero experto siempre se centrará en el código simple y en el panorama general. ingeniería (incluida la contabilidad de los efectos del equipo a lo largo del tiempo) en lugar de solo programar puntos de estilo.
Daniel Pryden
3
Escribir código que otros no puedan leer no prueba que eres mejor que ellos. Demuestra que no puede escribir código legible.
Stig Hemmer
3
@StigHemmer aparentemente no entendió la pregunta y está cambiando el tema. No se trata de código no legible, sino de código incomprensible para otros debido a su falta de conocimiento.
t3chb0t
44
@ t3chb0t Mi punto era que estos dos son lo mismo.
Stig Hemmer