Hace un tiempo, hice una pregunta en SO sobre algo escrito en C ++, pero en lugar de obtener una respuesta al problema en cuestión, los comentarios se volvieron locos en mi estilo de codificación, incluso cuando indiqué que era un código WIP y que tenía la intención de limpiarlo más tarde cuando tenía el caso base funcionando. (Obtuve tantos votos negativos que decidí sacar la pregunta, ya que mi representante en SO ya es casi abismal)
Me hizo preguntarme por qué la gente adopta una actitud tan dura como "eres un novato, vete a la mierda". Me acusaron de escribir C ++ como si fuera Java. Algo que no puedo entender y que todavía me desconcierta.
He estado programando en varios idiomas OOP durante varios años, aunque a intervalos. Elijo el idioma para usar en términos de sus bibliotecas disponibles y entornos de ejecución óptimos para el trabajo en cuestión. Adopto patrones de diseño en el código OOP y estoy bastante seguro de que mi uso de patrones es sólido y de que, sabiamente, puedo mantener el mío. Entiendo la caja de herramientas OOP, pero elijo usar las herramientas solo cuando creo que realmente es necesario, no solo usar un truco para mostrar mi ingenio de codificación. (Que sé que no son de primera categoría, pero creo que tampoco están en el nivel n00b).
Diseño mi código antes de escribir una sola línea. Para definir las pruebas, enumero los objetivos de una clase determinada y los criterios de prueba a los que debe cumplir. Debido a que es más fácil para mí crear diagramas de secuencia y luego escribir código, elegí escribir mis pruebas después de que la interfaz se hizo evidente.
Debo admitir que en el código que publiqué en la pregunta, todavía estaba usando punteros, en lugar de usar punteros inteligentes. Yo uso RAII siempre que puedo. Sé que una RAII adecuada significa protección contra los puntos nulos, pero trabajo de forma incremental. Era un trabajo en progreso y tenía la intención de limpiarlo más tarde. Esta forma de trabajar fue condenada enérgicamente.
En mi opinión, debería tener un ejemplo de trabajo primero para poder ver si el caso base es una forma de pensar viable. También pienso que limpiar el código es algo típico de la fase de refactorización ágil, después de que se haya probado el caso base. Debo admitir que, aunque lentamente estoy obteniendo el estándar Cxx, prefiero usar lo que entiendo, en lugar de arriesgarme a usar conceptos que todavía tengo que dominar en el código de producción. Intento cosas nuevas de vez en cuando, pero generalmente en proyectos de juego que tengo a un lado, solo para ese propósito.
[editar] Me gustaría aclarar que la sugerencia de mosquito [1] no apareció en la búsqueda que hice antes de comenzar a hacer mi pregunta. Sin embargo, aunque su sugerencia cubre un aspecto de la pregunta, la pregunta a la que se vinculó no responde al meollo de mi pregunta, solo parte de ella. Mi pregunta es más sobre la respuesta que obtuve a mi estilo de codificación y los aspectos profesionales de manejar diferentes estilos de codificación y niveles (aparentes) de habilidad. Con mi pregunta anterior sobre SO y su respuesta como un caso puntual. [/editar]
La pregunta entonces es: ¿por qué burlarse de alguien que no usa su estilo de codificación?
Los asuntos / subdivisiones disponibles para mí son:
- ¿Por qué sería una mala práctica de programación usar más código propenso a errores en situaciones de prototipo, si la refactorización lo hace más robusto después?
- ¿Cómo podría un programa escrito en C ++ ser como si estuviera escrito en Java? ¿Qué lo convierte en un mal programa (considerando que indiqué la intención del estilo actual y el trabajo planificado para mejorar?)
- ¿Cómo sería un mal profesional si decidiera usar una construcción que se utiliza en un cierto paradigma de programación (por ejemplo, OOP / DP)?
fuente
int
variables separadas para realizar un seguimiento de la longitud real.Respuestas:
Sin ver el código en cuestión, hay algunas formas de escribir código Java en C ++, algunas peores que otras.
Excepto por el n. ° 1, ninguno de estos hace que un programa de C ++ sea un mal programa, pero tampoco es el tipo de código en el que prefiero trabajar como programador de C ++. (Tampoco me gustaría trabajar con Perl no idiomático o de estilo C, Python no idiomático, etc.) Un lenguaje tiene sus propias herramientas y modismos y filosofía, y un buen código utiliza esas herramientas y modismos en lugar de intentar usar el mínimo común denominador o tratando de reproducir el enfoque de otro idioma. Escribir código no idiomático en un idioma / dominio de problema en particular / lo que sea que no haga que alguien sea un mal programador, solo significa que tienen más que aprender sobre ese idioma / dominio de problema / lo que sea. Y no hay nada de malo en eso; Hay una lista muy larga de cosas sobre las que tengo más que aprender, y C ++ en particular tiene muchísimas cosas que aprender.
Con respecto a la cuestión particular de escribir código propenso a errores con la intención de limpiarlo más tarde, no es en blanco y negro:
Para usar punteros en bruto versus punteros inteligentes como ejemplo, si va a trabajar en C ++, usar RAII y punteros inteligentes son lo suficientemente fundamentales como para que sea más rápido escribir código de esa manera que volver y limpiarlo más tarde. Una vez más, no hacer esto no significa que alguien sea un mal programador, no profesional, etc., pero sí significa que hay más para aprender.
fuente
new
se consideran los powertools. El almacenamiento automático es la herramienta manual.Cada lenguaje de programación tiene un conjunto de expresiones idiomáticas y mejores prácticas, que generalmente conducirán a un código elegante, correcto y eficaz. Aquí hay algunas peores prácticas que están perfectamente bien en algún otro idioma:
for ($i = 0; $i < 42; $i++) { … }
en Perl, pero no en PHP(en Perl, las variables deben declararse y dichos bucles deben iterar en un rango)
new Foo()
en C ++ sin una buena razón, pero no en Java(C ++ no tiene recolección de basura, por lo que se debe usar RAII. De lo contrario, los noobs perderán memoria)
(Python es un lenguaje multi-paradigmático que obliga a "OOP" y admite funciones en el nivel superior)
return null
en Scala, pero no en ningún lenguaje tipo C(porque Scala tiene un
Option
tipo)(porque la pila de Java se desborda rápidamente, mientras que OCaml tiene una optimización de llamada de cola)
Es fácil usar un nuevo idioma como si fuera algo que sabes, y con suerte incluso funcionará. "Puedes escribir Fortran en cualquier idioma". Pero realmente no desea ignorar las características específicas que ofrece el lenguaje X, porque es muy probable que X ofrezca alguna ventaja sobre U.
“ Elijo el idioma para usar en términos de sus bibliotecas disponibles y entornos de ejecución óptimos para el trabajo en cuestión ”, pero si este idioma X es realmente mejor que el idioma U para el trabajo en cuestión también depende de qué tan familiarizado esté ese idioma, o cuánto tiempo llevará familiarizarse lo suficiente como para usarlo bien. No cedería una motosierra pesada solo porque corta la madera más rápido, cuando realmente quiere su vieja navaja porque encaja perfectamente en su mano. A menos que realmente quieras talar un árbol.
Pero su pregunta es más sobre un tema cultural : aprender todas las mejores prácticas lleva mucho tiempo, y los novatos hacen la mayoría de las preguntas, mientras que los gurús las responden. Pero lo que es obvio para un gurú no lo es para un novato, y los gurús a veces lo olvidan. Como novato, la solución es no dejar de hacer preguntas. Sin embargo, uno puede mostrar una apertura para aprender y aplicar las mejores prácticas, por ejemplo, tratando de limpiar su código tanto como sea posible antes de mostrarlo a otros. La mayoría de los idiomas tienen algunas prácticas recomendadas básicas que son fáciles de aprender, incluso cuando toda la curva de aprendizaje es realmente muy larga.
Un problema común es que las personas nuevas en programación ignoran cualquier sangría u otro formato, y luego se confunden porque su programa no funciona. Yo también estaría confundido, y el primer paso para comprender un programa es asegurarme de que esté perfectamente diseñado. Luego, errores simples como una cita de cierre olvidada o una coma faltante de repente se vuelven obvios. Confío en que ya practique un buen formato, y aquí es una metáfora de otras mejores prácticas: las mejores prácticas evitan errores, las mejores prácticas facilitan la búsqueda de errores, la aplicación de las mejores prácticas es antes de encontrar el problema .
Es demasiado barato decir "Lo arreglaré más tarde", cuando arreglarlo ahora hubiera resuelto su problema (también, esa legendaria "fase de limpieza" nunca puede llegar, por lo que la única opción responsable es hacerlo bien el primera vez). Por lo menos, tratar de hacer que su código sea lo mejor posible antes de pedir ayuda a otros hace que sea más fácil para ellos razonar sobre su código, por lo que es una buena decisión.
fuente
optional<T>
yNullable<T>
respectivamente. Además, prácticamente todo el mundo pierde memoria en C ++ sin RAII, novato o no.No soy un desarrollador hardcore de C ++, pero ...
Una cosa a tener en cuenta es que un error en C ++ generalmente significa "comportamiento indefinido". En un idioma seguro, lo peor que podría suceder es una excepción que finalice su programa de inmediato. En C ++, tienes suerte si obtienes un segfault. Es completamente posible que su programa siga haciendo algo sutilmente incorrecto. También podría comportarse correctamente durante un período de tiempo y manifestar errores mucho más tarde, o podría comportarse correctamente todo el tiempo pero eventualmente consumir toda su memoria.
En cualquier caso, solo se necesita un solo error para llevar la ejecución del programa completamente fuera de los rieles a un territorio desconocido. Es probable que para el desarrollador de C ++ a tiempo completo, el "caso base" signifique "ninguna posibilidad de comportamiento indefinido o pérdidas de memoria".
No creo que haya una respuesta a esto que no sea en gran medida especulativa y obstinada. Sin embargo, si desea mi opinión, Java tiende a tener un par de antipatrones asociados, como el hecho de que todo tiene que ser un objeto. Donde en otros idiomas a los que pasa un puntero, funtor, o función, en Java que se suele encontrar toneladas de vacua y en términos muy útil
ThingDoers
,FooFactories
yIFrobnicators
que son sólo funciones en el encubrimiento.Del mismo modo, donde en otros idiomas puede pasar una tupla simple o una estructura sin nombre, en Java para agrupar incluso solo 2 objetos en un contenedor de datos simple, debe predefinir una clase NamedThing de más de 30 líneas con setters, getters y Javadocs. La relativa falta de características de Java obliga a los programadores a hacer dobles volteos orientados a objetos para hacer cosas a veces. El código resultante rara vez es idiomático fuera de Java.
Luego está el hecho de que en C ++ necesita un gráfico de objetos muy simplificado para administrar la memoria manualmente; generalmente un objeto es propiedad de otro objeto exactamente. En Java, no es necesario seguir restricciones tan estrictas, ya que el recolector de basura garantiza que las cosas se limpien cuando no haya más referencias a ellas. Por lo tanto, definitivamente existe el riesgo de una administración de memoria incorrecta si solo translitera el código de Java a C ++.
Finalmente, podría ser solo el elitismo. No voy a fingir que constituyen la mayoría, pero definitivamente he visto un sentimiento de "No necesito un lenguaje que tome mi mano y me impida hacer cosas estúpidas" entre algunos desarrolladores de C ++. En su opinión, C ++ es un lenguaje "real" y si no puede manejar sus idiosincrasias no es un "programador real".
fuente
Ligeramente fuera de la respuesta del tema ...
No se preocupe, este es un "comportamiento" común en cualquier comunidad de expertos. Y sea honesto, si es bueno en cualquier idioma y se encontrará con un código que es "extraño", probablemente también lo criticará. (porque, quiero ENSEÑAR).
Estoy en el mundo de Perl, cuando veré algo como:
en lugar de:
seguro lo comentará - (leer: enseñar al autor) sobre la
join
función.De todos modos, demasiadas críticas son contraproducentes y uno de los mejores ejemplos es el siguiente: (tomado de: http://perl-begin.org/humour/#How_can_I_switch_off_the_T.V..3F )
(Este bit se publicó de forma anónima en un pastebot el 23 de marzo de 2011. Se coloca aquí para la posteridad después de algunas modificaciones).
fuente
Al escribir rápido y sucio con la mente de arreglarlo más tarde, existe el peligro de olvidar algo que necesita arreglar.
En java no tienes que pensar en quién posee un determinado objeto, solo pasas la referencia y te olvidas de que no es nada. Sin embargo, en C ++ debe haber una definición clara de quién posee el objeto y quién es responsable de limpiarlo.
No lo harías; C ++ es un lenguaje multi-paradigmático, soporta OOP bastante bien pero también puede hacer muchas otras cosas. Sin embargo, la mayor parte se reduce al uso de la herramienta correcta para el trabajo en lugar de sacar el martillo cada vez que necesita clavar una punta puntiaguda en un poco de madera.
La razón por la que recibió una mala respuesta es que la mayoría de las personas en SO tienden a juzgar las habilidades por lo idiomático que puede codificar en el idioma que está preguntando. Las personas familiarizadas con C ++ tienden a ponerse de rodillas cuando ven un código incorrecto que parece algo que los ha mordido en el pasado.
fuente