¿"If (0 == value) ..." hace más daño que bien? [cerrado]

49

Esta es una de las cosas que más odio cuando lo veo en el código de otra persona. Sé lo que significa y por qué algunas personas lo hacen de esta manera ("¿y si accidentalmente pongo '=' en su lugar?"). Para mí es muy parecido a cuando un niño baja las escaleras contando los pasos en voz alta.

De todos modos, aquí están mis argumentos en contra:

  • Interrumpe el flujo natural de leer el código del programa. Nosotros, los humanos, decimos "si el valor es cero" y no "si el cero es valor".
  • Los compiladores modernos te advierten cuando tienes una tarea en tu condición, o en realidad si tu condición consiste solo en esa tarea, lo cual, sí, parece sospechoso de todos modos
  • No debe olvidar poner el doble '=' cuando compara valores si es un programador. Es mejor que olvides poner "!" cuando se prueba la no igualdad.
mojuba
fuente
17
Tampoco me importa mucho, pero está bastante lejos de mi lista personal de manías.
Adam Crossland el
77
Y los programadores pierden el doble '=' a veces. Es un error fácil de cometer y uno que es muy fácil de pasar por alto.
Sange
8
¿Cómo es que esto no es constructivo o no es una pregunta real?
TheLQ
77
Esto está cerrado, así que aquí está mi breve opinión: ¿cómo puede la gente recordar escribir 0 == valuepero no recordar escribir ==? Me refiero a blimey, si estás pensando en ello, ¿por qué no escribirlo correctamente para empezar?
Dr. Hannibal Lecter
3
@muntoo: Según los compiladores, muchas cosas son "correctas", no creo que sea un buen punto de referencia.
Dr. Hannibal Lecter

Respuestas:

59

Ah, sí, "condicionales de Yoda" ("¡Si el valor es cero, ejecute este código que debe!"). Siempre apunto a cualquiera que diga que es "mejor" en herramientas como lint (1). Este problema particular se ha resuelto desde finales de los años 70. La mayoría de los lenguajes modernos ni siquiera compilan una expresión como if(x = 10), ya que se niegan a forzar el resultado de la asignación a un booleano.

Como han dicho otros, ciertamente no es un problema, pero provoca un poco de disonancia cognitiva.

TMN
fuente
32
+1 para "condicionales de Yoda". De hecho LOL'd en eso. :)
Bobby Tables
3
Aunque la disposición está bien, me opongo a la comparación a cero en lugar de yeso booleano llano, if(!value).
SF.
1
Entonces, ¿considera que las asignaciones dentro de un condicional son un error?
44
"La mayoría de los lenguajes modernos ni siquiera compilarán esto" El problema surge cuando estás usando un lenguaje que coacciona silenciosamente el resultado de la asignación a un booleano. El lenguaje más popular que se me ocurre es JavaScript. Es por eso que siempre uso yoda condicionales incluso en Java para no olvidar hacerlo cuando escribo javascript. Me cambio entre los dos con la frecuencia suficiente para que pueda (y ha sido) un problema.
Sam Hasler
3
¿Alguien sabe de un compilador que no compilará if (0 == x)?
Kristopher Ives
56

Es desagradable porque impone un impuesto mental pequeño, pero notable.

La gente lee de izquierda a derecha en prácticamente todos los lenguajes de programación (y la mayoría de los lenguajes naturales).

Si veo 123 == x, la forma en que lo analizo mentalmente es:

  • 123- ¿Y qué? información incompleta
  • == - bueno, 123 es 123, por qué probarlo ...
  • x- Ok, eso es lo que nos preocupa. Solo ahora tengo el contexto.
  • Regrese para reconsiderar 123y por qué x se compara con él.

Cuando veo x == 123el análisis mental es:

  • x- Proporciona contexto, sé de qué se trata la condición. Puedo elegir ignorar el resto. Basado en el flujo anterior, tengo una buena idea de por qué y qué vendrá (y me sorprendería si es diferente).
  • == - Ya me lo imaginaba.
  • 123 - Sip.

La interrupción es pequeña (en un ejemplo simple), pero siempre lo noto.

Poner el valor primero puede ser una buena idea si desea llamar la atención sobre él, por ejemplo if (LAUNCH_NUKES == cmd). Normalmente esta no es la intención.

dbkk
fuente
55
Exactamente. En los idiomas naturales, la constante siempre llega al final por la misma razón: si la luz es roja ...
mojuba
2
@mojuba Cierto, es casi universal. Curiosamente, hay algunos lenguajes naturales donde el objeto viene antes que el sujeto (orden OVS / OSV), pero todos son oscuros.
dbkk
1
Por otro lado, algunos de nosotros tendemos a leer los símbolos antes de la variable. Son más llamativos. Así que voy a analizar fuera de =o ==antes 123o x, y terminan por no molestarse en traducir el código de Inglés en mi cabeza.
Izkata
Además, la mayoría de los compiladores avisarán si se le solicita correctamente, a menos que uno use llaves adicionales, por lo que intenta resolver un problema.
Deduplicador
47

¿Perjudicial? No. Funciona de cualquier manera.

¿Mala práctica? Debatible, en el mejor de los casos. Es simple programación defensiva.

¿Vale la pena perder el sueño? Nah

Wonko el cuerdo
fuente
8
Y cuando lo leo, entiendo el código de inmediato, que es para mí la razón más importante para debatir un estilo de codificación. Estoy totalmente de acuerdo, no vale la pena perder el sueño.
Jeff Siver el
17

Esto es básicamente flaimbait.

No, no hace más daño que bien. Sencillo.

¿Mas palabras?

Argumento del compilador? Erm, ish, tal vez, no confíes demasiado en el cumplidor para salvarte de ti mismo.

"No deberías olvidar" - bueno, duh - no, por supuesto, no deberías mientras tanto estoy cansado, he estado codificando todo el día, he tenido que usar dos idiomas diferentes y, a veces, solo a veces, ser humano lo hago un error.

El punto de este tipo de comportamiento es que es defensivo, no está ahí porque esperas cometer errores más de lo que tienes seguro porque esperas colapsar ... pero si lo haces, es bueno estar cubierto.

¿Difícil de leer? Te estás quejando de que un programador decente debería tener == cableado (que hace todo tipo de suposiciones deficientes) pero que el mismo programador decente no puede leer 0 == valor ??

No hace daño, tiene beneficios potenciales, pregunta tonta, deja que otros lo hagan si quieren y siguen adelante.

Murph
fuente
66
Creo que el valor 0 == no es natural para aquellos que estudiaron álgebra mucho antes de estudiar programación.
mojuba el
44
Ese no es el punto: sí, tiene razón, no se lee bien, pero una gran parte de lo que nosotros, como programadores, escribimos no se acumula exactamente como lenguaje natural y es una cuestión de cómo interpretan qué ves
Murph
44
Bravo ... Sin mencionar el hecho de que, debido a que se lee de forma poco natural, usted está inclinado a prestarle más atención y, por lo tanto, detectar posibles errores.
mocj
77
@mocj - Por lo tanto, ¿todos deberíamos codificar de la manera más obtusa posible para asegurarnos de que las personas que leen nuestro código realmente necesiten leer nuestro código?
Kaz Dragon
66
@mocj - Aprecio eso, pero tu argumento fue que el "tartamudeo del cerebro" mientras lees el condicional de Yoda es algo bueno. Estoy haciendo la pregunta de que, si ese es el caso, ¿deberíamos apuntar a escribir todo el código para causar "tartamudeos cerebrales"? Pregunta genuina
Kaz Dragon
11

No lo llamaría daño, pero es desagradable. Entonces no, no diría que sí.

como se llame
fuente
10

Nunca he sentido que todo el '¿y si olvido un =?' Alguna vez tuvo mucho peso. Sí, puede hacer un error tipográfico, pero todos hacemos errores tipográficos, parece una tontería cambiar todo el estilo de codificación porque tiene miedo de cometer un error. ¿Por qué no hacer que todas sus variables y funciones estén en minúsculas sin signos de puntuación, porque algún día puede olvidar poner en mayúscula algo u olvidar un guión bajo?

GSto
fuente
55
Ese no es el punto de la pregunta, el punto es "es dañino", y no lo es. Una irritación muy leve en el peor de los casos, pero no dañina.
Murph el
1
En lenguajes dinámicos, absolutamente, puede escribir mal un símbolo y perder el tiempo más tarde buscando la fuente de su error
mojuba
3
con todo respeto, cuando haya pasado una noche (o dos) y encuentre que la fuente (en código C ++) es a = en lugar de ==, tendría algo de peso.
DevSolo el
2
@DevSolo: Creo que eso debería suceder realmente una o dos veces en tu carrera, pero no más que eso
mojuba
9

Algunas personas lo usan para dejar en claro exactamente lo que está haciendo un condicional. Por ejemplo:

Camino 1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

Camino 2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

Algunas personas sienten que el segundo ejemplo es más conciso, o invertir argumentos ilustra el punto de una prueba (condicional) antes de la prueba misma.

En realidad, no me importa de ninguna manera. Tengo mis manías sobre el estilo y el más grande es la inconsistencia. Entonces, hazlo de la misma manera, de manera consistente y no me importará leer tu código.

Mezclar hasta el punto en que parece que seis personas diferentes con su propio estilo distintivo trabajaron en él de una vez, me molesta un poco.

Tim Post
fuente
44
El segundo ejemplo me hizo decir "¿eh?" El primero es mucho más legible. Gran ejemplo :)
Mateen Ulhaq 01 de
6

Para mí, es un simple condicionamiento. Como alguien que aprendió (en los años 90) C y C ++, me acostumbré a ello y aún lo uso, a pesar de que se explican los motivos.

Una vez que está "condicionado" para mirar el lado izquierdo en busca de la "constante", se convierte en una segunda naturaleza.

También lo uso solo para equivalencia (o equivalencia negada), no para mayor / menor que.

Estoy completamente de acuerdo con la respuesta de @ Wonko.

DevSolo
fuente
5

El único caso en el que me parece útil es cuando la parte variable del if es bastante larga y ver los valores hace que el código sea más fácil de leer. Los idiomas de espacio de nombres punteados tienen los mejores ejemplos de esto.

Por ejemplo, algo en lo que trabajé con el inicio de sesión único tuvo una situación en la que podría tener dos sesiones simultáneas si ocurriera un cierto tipo de error y se recuperó de cierta manera, así que tengo que agregar un controlador que estaba dentro y si se veía algo como esto:

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

Es cierto que en este ejemplo hay otras formas de hacer esto, pero este sería un caso en el que la versión número primero es potencialmente más legible.

Cuenta
fuente
2
Creo que la palabra clave aquí es "otras formas de hacer esto";)
mojuba
en este caso sí, pero en algunos casos este sigue siendo el resultado más legible. Mi único punto es que hay algunas razones legítimas para hacer esto además de combatir el lenguaje o el comportamiento ide y escribir-o
Bill
Para ser honesto, tengo dificultades con las condiciones de Yoda para <= y> =. El signo == es una cuestión diferente, porque en mi cabeza solo puedo cambiar los símbolos, pero en su caso necesito recordar que count () tiene que ser mayor o igual a 2, y es bastante molesto derivarlo de un signo más pequeño o igual
Alex
3

Y sin embargo, se producen los errores. Y a veces desea una asignación en un operador de bucle donde de otro modo podría verificar la igualdad, o al menos es una práctica estándar usarla.

De alguna manera lo sostengo. El consejo que he seguido (posiblemente de Code Complete) es mantener lo que debería ser el valor más bajo a la izquierda en las comparaciones. Estuve discutiendo esto con un colega antes y él pensó que era una locura, pero me he acostumbrado mucho.

Entonces yo diría:

if ( 0 <= value )

Pero también diría:

if ( value <= 100 )

Igualdad, tenderé a verificar con la variable de la izquierda, sin embargo, es más legible.

glenatron
fuente
1
Estoy acostumbrado a usar if(y > x)todo el tiempo. A menos que ysea ​​una constante.
Mateen Ulhaq
Solía ​​hacerlo de esa manera, pero una vez que tuve la idea de tener los valores más bajos a la izquierda, descubrí que mi código es mucho más legible de un vistazo.
glenatron