Es un principio de estilo de codificación, por ejemplo, el principio de salida única
Las personas que aún no saben si se trata de una salida única o una salida múltiple todavía están atrapadas a fines de la década de 1960. En aquel entonces, tal discusión era importante ya que estábamos en la infancia del programador estructurado, y había un campo bastante numeroso que proclamaba que los hallazgos detrás del Teorema del Programa Estructurado de Bohm-Jacopini no eran universalmente aplicables a todas las construcciones de programación.
Es algo que debería haberse resuelto hace mucho tiempo. Bueno, se ha resuelto (casi 4 décadas para ser precisos, tanto en la Academia como en la industria), pero las personas (aquellas que están absolutamente a favor o en contra) no han estado prestando atención.
En cuanto al resto de mis respuestas, todo es relativo (¿qué no está en el software?):
- realmente una buena cosa?
Sí. La mayoría de las veces para el caso general, con advertencias específicas para casos extremos y construcciones de programación específicas del lenguaje.
¿Siempre o solo a veces?
La mayor parte del tiempo
¿Cuánta diferencia realmente hace?
Depende
Código legible vs código ilegible. Mayor complejidad (que deberíamos saber ahora aumenta la probabilidad de introducir errores) frente a una complejidad más simple (y, por lo tanto, menor probabilidad de errores). Lenguajes cuyos compiladores no agregan un retorno implícito (por ejemplo, Pascal, Java o C #) y aquellos que predeterminado a int (C y C ++).
Al final, es una habilidad perfeccionada con hombre / horas detrás de un teclado. A veces, está bien tener múltiples declaraciones de retorno, como aquí (en algunos pseudocódigo de Pascal'esque):
function foo() : someType
begin
if( test1 == true )
then
return x;
end
doSomethignElseThatShouldnHappenIfTest1IsTrue();
return somethingElse();
end;
La intención es clara, y el algoritmo es lo suficientemente pequeño y sencillo como para no garantizar la creación de una variable 'flag' que contenga el valor de retorno eventual utilizado en un único punto de retorno. El algoritmo podría estar en error, pero su estructura es tan simple que el esfuerzo para detectar un error es (muy probablemente) insignificante.
A veces no lo es (aquí usando un pseudocódigo tipo C):
switch(someVal)
{
case v1 : return x1;
case v2 : return x2:
case v3 : doSomething(); // fall-through
case v4: // fall-through
case v5: // fall-through
case v6: return someXthingie;
...
...
default:
doSomething(); // no return statement yet
}
Aquí, el algoritmo no tiene una estructura simple, y la declaración de cambio (una de estilo C) permite pasos fallidos que pueden o no hacerse intencionalmente como parte del algoritmo.
Quizás el algoritmo sea correcto, pero esté mal escrito.
O tal vez, por fuerzas externas más allá de la capacidad del programador, esta es la representación real (y correcta) de un algoritmo legítimamente necesario.
Tal vez está mal.
Descubrir la verdad de todo esto requiere mucho más esfuerzo que en el ejemplo anterior. Y aquí hay algo en lo que creo firmemente (tenga en cuenta que no tengo estudios formales para respaldar esto):
Suponiendo un fragmento de código que se supone que es correcto:
Las declaraciones de retorno múltiples aumentan la legibilidad y la simplicidad de dicho fragmento de código, si el fragmento representa un algoritmo simple con una estructura de flujo inherentemente simple. Por simple, no me refiero a pequeño, pero quiero decir inherentemente comprensible o evidencia de sí mismo , lo que no requiere un esfuerzo de lectura desproporcionado (ni inducir a las personas a vomitar, maldecir a la madre de alguien o tragarse una bala cuando tienen que leerlo). )
Una sola declaración de retorno aumenta la legibilidad y la simplicidad de dicho fragmento de código si el valor de retorno se calcula a lo largo de la ejecución del algoritmo o si los pasos en el algoritmo responsable de calcularlo se pueden agrupar en una ubicación dentro de la estructura del algoritmo .
Una sola declaración de retorno disminuye la legibilidad y la simplicidad de dicho fragmento de código si requiere asignaciones a una o más variables de indicador, y las ubicaciones de tales asignaciones no se ubican de manera uniforme en todo el algoritmo.
Las declaraciones de retorno múltiples disminuyen la legibilidad y la simplicidad de dicho fragmento de código si las declaraciones de retorno no se distribuyen uniformemente a través del algoritmo y si demarcan bloques de código mutuamente excluyentes que no son uniformes en tamaño o estructura entre sí.
Esto está estrechamente relacionado con la complejidad de un fragmento de código en cuestión. Y esto a su vez está relacionado con las medidas de complejidad ciclomática y halstead. A partir de esto, se podría observar lo siguiente:
Cuanto mayor sea el tamaño de una subrutina o función, mayor y más compleja es su estructura de flujo de control interno, y mayor es la probabilidad de que tenga que preguntarse si usar declaraciones de retorno múltiples o únicas.
La conclusión de esto es: mantener sus funciones pequeñas haciendo una cosa y solo una cosa (y hacerlo bien). Si exhiben métricas ciclomáticas y de complejidad halstead nominalmente pequeñas, es probable que no solo sean correctas y que se implementen tareas que sean comprensibles, sino que sus estructuras internas también serán relativamente evidentes.
Entonces, y solo entonces puede hacerlo con bastante facilidad y sin perder mucho sueño, puede decidir si usar un solo retorno y múltiples retornos sin correr muchos riesgos de introducir errores con cualquiera de las dos opciones.
También se podría ver todo esto y sugerir que cuando las personas luchan con el tema de los retornos únicos o múltiples, es porque, ya sea por inexperiencia, estupidez o falta de ética laboral, no escriben código limpio y tienden a escribir funciones monstruosas sin tener en cuenta las medidas ciclomáticas y de halstead.