Rust: Eliminar operador ternario

Creado en 29 ene. 2012  ·  29Comentarios  ·  Fuente: rust-lang/rust

Uno de los comentarios que se me quedó grabado después del anuncio de 0.1 fue que alguien preguntaba por qué tenemos un operador ternario, ya que es funcionalmente igual que nuestras expresiones if . Simpatizo con este sentimiento

Últimamente me he sentido cauteloso con la rápida incorporación de funciones al lenguaje y creo que deberíamos ser más cautelosos a la hora de comprometernos con cosas que realmente no necesitamos. Uno de los mandatos originales tras el anuncio de Rust fue centrarse en eliminar funciones (está en las preguntas frecuentes del idioma), y no creo que haya ninguna forma de argumentar que hemos tenido éxito en eso.

Es cierto que el operador ternario es una característica de bajo mantenimiento, pero su eliminación también es de bajo impacto.

A-frontend E-easy

Comentario más útil

Acordado. Ojalá hubiera hecho de JS un lenguaje de expresión. ¿La gran división de declaración / expresión motiva?: Pero Rust está libre de eso, y if-else basta.

/ser

Todos 29 comentarios

Estoy de acuerdo. Me preguntaba por qué también teníamos el operador ternario.

Acordado. Ojalá hubiera hecho de JS un lenguaje de expresión. ¿La gran división de declaración / expresión motiva?: Pero Rust está libre de eso, y if-else basta.

/ser

Como usuario muy pesado del operador?: En C / C ++, prefiero la sintaxis compacta. También creo que se formatea mejor cuando la expresión es demasiado larga para caber en una sola línea:

let x = some_very_long_condational
     ? if_true
     : if_false

let x = if some_very_long_condational 
     { if_true}
     else { if_false}

La sintaxis puede empeorar, en mi opinión, si if_true y if_false no caben en una sola línea. Por ejemplo, dónde deben colocarse los tirantes.

Solo mis dos centavos.

Me gusta:

let x = if some_very_long_condational { 
                 if_true
           } else { 
                 if_false
           }

Agrega algunas líneas adicionales (la "línea else" y el corchete final), pero lo mantiene limpio y puede agregar tanto código como desee en cualquiera de las dos.

Utilizo mucho el operador ternario en C ++, pero creo que la sintaxis es pobre. ¿Tienes que ver el? y: en medio de un mar de otros tokens para ver que es incluso un condicional. Con expresión-si tiene el token inicial que indica al lector "aquí viene un condicional".

Bueno, sigo prefiriendo la sintaxis del operador ?: . Encuentro que su elección de formato es demasiado detallada, especialmente para los casos simples en los que if_true y if_false son una sola expresión (en oposición a varias declaraciones que terminan en una expresión).

Sin embargo, no me opondré muy enérgicamente si se elimina el operador? :.

También estoy usando ?: todas partes, pero sigo pensando que eliminarlo sería una buena idea: libera dos (!) Sigilos ASCII en nuestra sintaxis de expresión. Piense en todas las otras cosas increíblemente crípticas que podríamos hacer con ellos.

Un uso no críptico sería permitirlos como parte del nombre del predicado.
Por ejemplo, "¿vacío? ()" En lugar de "is_empty ()".

@marijnh ++ :)

Personalmente me importa un comino. Igor abogó por ternario en https://mail.mozilla.org/pipermail/rust-dev/2010-November/000110.html

Esto se hizo en pull req # 1705.

    return parent.index_of(child_a) < offset_b ? -1 : 1

se ve infinitamente mejor que

    return if parent.index_of(child_a) < offset_b {
        -1 
    } else {
        1
    }

Si tenemos que ser pitonías sobre esto,

return -1 if parent.index_of(child_a) < offset_b else 1

sería mucho mejor.

Estoy de acuerdo, no entiendo por qué tuvo que ser eliminado ... Por favor, no obligue a los usuarios de Rust a escribir código innecesariamente pesado / detallado, cuando existe una práctica tan común (operador ternario) en la mayoría, si no en todos los idiomas.

De todos modos, está hecho, pero solo quería agregar mi voz a los que apoyan un estilo de código más limpio.

También extraño esta sintaxis

Creo que hay tres efectos conspiradores en juego aquí, a saber

1) "La gran declaración / expresión dividida" (@BrendanEich);
2) Coerción de no booleanos en contextos booleanos;
3) Incluso los lenguajes 'dinámicos' no suelen tener 'sintaxis dinámica' (macros reales) y 'semántica dinámica' (a la from __future__ import division Python) en estos días.

(1) significa que if ... then ... else ... es algo fundamentalmente diferente de ... ? ... : ... , que es una distinción totalmente prescindible. Hay casos extremos como return , pero en general la distinción no es necesaria.

(2) significa que puede, en muchos idiomas, usar expresiones arbitrarias como pruebas; esto solo parece conveniente siempre y cuando todavía esté usando su primer idioma y se vuelve molesto tan pronto como comienza con el segundo. Como se señaló anteriormente en esta discusión de Reddit , no está claro por qué una lista vacía debería indicar false o true —simplemente escriba if ( d.length == 0 ) ... y ganó _so_ mucha claridad.

(3) significa que está atascado con lo que le dé el comité de idiomas, y sea lo que sea, es probable que el idioma se quede atascado hasta que alguien llegue, bifurque o reescriba el código base y le dé un nuevo nombre. Podría ser diferente; podría haber idiomas que permitan, digamos, use 'ternary conditions'; use 'empty lists are false'; . Hay precedentes de eso. Por supuesto, muchas cosas hablan en contra de esa flexibilidad porque siempre tendrá que tener en cuenta esos "marcadores de desviación" y recordar copiarlos cuando copie y pegue el programa. OTOH, si los meros usuarios pudieran cambiar la sintaxis y la semántica del lenguaje fácilmente y empaquetar dichas prácticas en módulos instalables, eso podría ayudar enormemente en la evolución del lenguaje.

@kevina A veces, la verbosidad no es algo malo, pero estoy de acuerdo en que los operadores ternarios limpian el código muy bien.

@caitp : ¿qué es exactamente lo que está mal?

return if parent.index_of(child_a) < offset_b { -1 } else { 1 }

o una de mis "cláusulas de abrazo" favoritas

return 
    if parent.index_of(child_a) < offset_b { -1 } 
    else                                   {  1 }

... o use un fósforo, especialmente si hay múltiples condiciones ...

return match parent.index_of(child_a) < offset_by {
  true  => -1,
  false => 1
}

... y, por supuesto, si es probable que se reutilice: simplemente muévalo a una función ...

return parent.is_child_before(offset_b)

Mira eso ... tienes opciones ... porque _todo_ es una expresión.

Nunca he querido guardar los _seis caracteres_ que se necesitan para escribir if {} else {} lugar de
() ? : , además de encadenar condicionales adicionales, se ve mucho mejor con if-as-an-expression. (Los operadores ternarios anidados se vuelven complicados muy rápidamente).

En mi opinión: cuando uso if-as-an-expression no veo la necesidad de inyectar tantos espacios en blanco innecesarios. También encuentro que se lee de forma más natural que el operador ternario, y la verbosidad adicional ayuda a separar las dos cláusulas visualmente. Ese es solo mi $0.02

Creo que puede haber leído mal lo que dije (y tenga en cuenta que esto fue hace algún tiempo)

Simplemente estoy señalando que no veo cómo el operador ternario se ve "infinitamente mejor".
En mi opinión, las formas comunes son infinitamente más hermosas que las formas de casos especiales.

El comentario dice que a veces, los condicionales como expresiones son muy útiles, a diferencia de los enunciados condicionales. Dejar caer los aparatos ortopédicos es solo una mejora subjetiva

return parent.index_of(child_a) < offset_b ? -1 : 1

vs

return if parent.index_of(child_a) < offset_b { -1 } else { 1 }

@caitp ¿ es el segundo aquí realmente infinitamente peor que el primero? El if else de Rust sigue siendo una expresión (no una declaración).

Mis pensamientos son:

  • El segundo parece que sería más legible para alguien sin un historial de otros idiomas y
  • Probablemente sería mejor mantener la sintaxis ? bajo la manga para el azúcar futuro (quizás relacionado con Option, etc.)

@mitchmindtree totalmente.

Una vez más, estás malinterpretando lo que decía el comentario.

return if parent.index_of(child_a) < offset_b { -1 } else { 1 } todavía está evaluando el condicional como una expresión (y por lo tanto puede ser un operando para return ).

Las llaves son feas, pero el punto principal es sobre expresiones condicionales, no sobre llaves. Se trata de poder escribir return foo.bar.baz(<conditional operand>) versus if (<conditional operand>) { return foo.bar.baz(1); } else { return foo.bar.baz(2); }

Creo que lo que realmente debemos darnos cuenta es que este problema tiene más de tres años. Teniendo en cuenta que la gente no ha extrañado tanto los ternaries en tres años, creo que es seguro decir que se mantendrán alejados.

@caitp hmm todavía no estoy seguro de estar siguiendo. ¿Estás hablando de óxido en particular? ¿O solo declaraciones frente a expresiones en general?

En óxido todavía puedes hacer

return foo.bar.baz(if cond { 42 } else { 0 })

? (Soy consciente de que no estabas hablando de aparatos ortopédicos, perdón por la confusión: smile_cat :)

En ese momento, en ToT, no había forma de hacer esto en Rust.

No tengo una opinión sólida, pero solo quiero agregar que si ? y : pueden usarse mejor para otras cosas, ¿por qué no usar algo como ?? y ?: lugar, por ejemplo cond ?? 43 ?: 0 ?

¿Por qué cambiar la forma en que los desarrolladores han estado acostumbrados durante decenas de años?

Le sam. 24 de oct. 2015 02:46, Kevin Atkinson [email protected] a
écrit:

No tengo una opinión fuerte, pero solo quiero agregar que sí. y puede
es mejor usarlo para otros agradecimientos, ¿por qué no usar algo como ?? y ?:
en lugar de. entonces tal vez cond? 43?: 0.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/rust-lang/rust/issues/1698#issuecomment -150728625.

@RenaudParis Lo siento, lo que quise decir fue: no tengo una opinión sólida, pero solo quiero agregar que si ? y : pueden usarse mejor para otras cosas, ¿por qué? no use algo como ?? y ?: lugar, por ejemplo cond ?? 43 ?: 0 ?

Una de las razones por las que se eliminó el operador ternario fue que "?" podría usarse para otra cosa en el futuro. Mi sugerencia fue utilizar otro operador. cond ?? 43 ?: 0 aún es más corto que if cond {43} else {0} .

Creo que es correcto eliminarlo, sin embargo, no sería tan malo si no se necesitaran brazaletes para una sola expresión. (Y sí, sé lo doloroso que es esto en el analizador, en mi humilde opinión, vale la pena, la legibilidad es muy importante)

p.ej

if i ==0 
     return i
else 
      1  

o incluso

if i == 0  return i
    else 1  

Este formato es mejor que

 if i == 0   ? return i
      : 1  

o

if i == 0   
      ? return i 
      : 1  

versos

if i ==0 {
      return i
}
else {
    1
}      

bastante feo / difícil de leer para algo tan común.

Se pone peor, pero es más fácil de leer si tiene una política de desarrollo contra los aparatos ortopédicos egipcios.

if i ==0
{
     return i
}
else
{
     1
 }      
¿Fue útil esta página
0 / 5 - 0 calificaciones