En un lenguaje de tipos dinámicos, ¿es mala idea devolver diferentes tipos de datos?

Daniel Kaplan pregunta:

Vengo de un entorno Java el cual es un lenguaje con tipos estáticos. En Java, tienes que devolver un sólo tipo por cada método. Por ejemplo, no puedes tener un método que condicionalmente devuelva un String y condicionalmente devuelva un Integer. Pero en JavaScript es posible.

En un lenguage de tipos estáticos entiendo porqué esto es una mala idea. Si cada método devolviera Object (del cual heredan las demás clases) entonces tú y el compilador no tiene idea de con qué están tratando. Tienes que descubrir tus errores en tiempo de ejecución.

Pero en un lenguaje con tipos dinámicos, podría no haber ni siquiera un compilador. En un lenguaje con tipos dinámicos, no es obvio para mí por qué una función que devuelve múltiples tipos es una mala idea. Mi experiencia en lenguajes con tipos estáticos me hace evitar escribir tales funciones pero temo que me esté cerrando a una característica que podría hacer mi código más limpio en maneras que no puedo ver.

Mainma responde:

Hay casos donde devolver diferentes tipos es aceptable:

Ejemplo 1.

sum(2, 3) -> Int
sum(2.1, 3.7) -> float

En algunos lenguajes de tipos estáticos, esto involucra sobrecargas “overloads”, podríamos considerar que han muchos métodos, cada uno devolviendo un tipo fijo predefinido. En lenguajes dinámicos la misma función puede ser implementado como:

var sum = function (a, b){
return a + b;
};

Ejemplo 2.

Imagina que tu obtienes una respuesta de un componente OpenID/OAuth. Algunos proveedores de OpenID/OAuth pueden contener más información por ejemplo la edad de la persona.

var user = authProvider.findCurrent();
// user es ahora:
// {
// provider: 'Facebook',
// name: {
//   firstName: 'Hello',
//   secondName: 'World'
//   },
// email: 'hello.world@example.com',
// age: 27
// }

Otros podrían tener lo mínimo, podría ser una dirección de correo o el seudónimo.

var user = authProvider.findCurrent();
// user es ahora:
// {
// provider: 'Google',
// email: 'hello.world@example.com'
// }

Otra vez la misma función, diferentes resultados.

Aquí, el beneficio de devolver diferentes tipos es importante en el contexto donde no te importa los tipos e interfases sino lo que contienen los objetos. Por ejemplo, imagina un sitio web que contiene lenguaje de adultos. Entonces el “findCurrent()” podría ser algo así:

var user = authProvider.findCurrent();
if (user.age || 0 >= 16) {
// La persona soporta lenguaje de adultos
allowShowingContent();
} else if (user.age) {
// OpenID/OAuth da la edad pero la persona parece muy joven para ver el contenido
} else
// OpenID/OAuth no te va a devolver la edad. Tienes que preguntar.
askForAge();
}

 

Refactorizar esto en código donde cada proveedor te dará su propia función la cual devolverá un tipo bien definido no sólo degradará el código y causará duplicación de código sino que no traerá ningún beneficio. Uno podría terminar con horrores de código como:

var age;
if (['Facebook','Yahoo','Blogger','LiveJournal'].contains(user.provider)) {
age = user.age;
}

En Java se puede usar Generics para devolver un tipo de dato diferente y todavía soporta la seguridad de tipos. Simplemente especificas que tipo quieres que te devuelva en el parámetro generic de la llamada a la función.

En JavaScript desde que es un lenguaje dinámico, devolver “object” parece la mejor opción.

De seguro “dynamic” sólo envuelve una variable “object” con algo de seguridad de tipos en tiempo de ejecución.

Stack Exchange, Ars Technica.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s