Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

218
Vistas
¿En qué se diferencia inyectar una función impura de llamarla?

Estoy leyendo un libro donde dice que una forma de manejar funciones impuras es inyectarlas en la función en lugar de llamarla como en el ejemplo a continuación.

llamada de función normal:

 const getRandomFileName = (fileExtension = "") => {
 ...
 for (let i = 0; i < NAME_LENGTH; i++) {
 namePart[i] = getRandomLetter();
 }
 ...
};

inyectar y luego llamar a la función:

 const getRandomFileName2 = (fileExtension = "", randomLetterFunc = getRandomLetter) => {
 const NAME_LENGTH = 12;
 let namePart = new Array(NAME_LENGTH);
 for (let i = 0; i < NAME_LENGTH; i++) {
 namePart[i] = randomLetterFunc();
 }
 return namePart.join("") + fileExtension;
};

El autor dice que tales inyecciones podrían ser útiles cuando intentamos probar la función, ya que podemos pasar una función cuyo resultado conocemos a la función original para obtener una solución más predecible.

¿Hay alguna diferencia entre las dos funciones anteriores en términos de ser puras, ya que entiendo que la segunda función sigue siendo impura incluso después de ser inyectada?

almost 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Una función impura es solo una función que contiene uno o más efectos secundarios que no se pueden deshabilitar de las entradas dadas.

Eso es si muta los datos fuera de su alcance y no produce de manera predecible la misma salida para la misma entrada.

En el primer ejemplo NAME_LENGTH se define fuera del alcance de la función, por lo que si ese valor cambia, el comportamiento de getRandomFileName también cambia, incluso si proporcionamos la misma fileExtension de archivo cada vez. Del mismo modo, getRandomLetter se define fuera del alcance, y casi con certeza produce una salida aleatoria, por lo que sería inherentemente impuro.

En el segundo ejemplo, todo está referenciado en el alcance de la función o se le pasa o se define en él. Esto significa que podría ser puro, pero no necesariamente. Nuevamente, esto se debe a que algunas funciones son inherentemente impuras, por lo que dependería de cómo se defina randomLetterFunc .

Si lo llamamos con

 getRandomFileName2('test', () => 'a');

...entonces sería puro, porque cada vez que lo llamamos obtendríamos el mismo resultado.

Por otro lado si lo llamamos con

 getRandomFileName2(
 'test', 
 () => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.charAt(Math.floor(25 * Math.random()))
);

Sería impuro, porque llamarlo cada vez daría un resultado diferente.

almost 4 years ago · Santiago Trujillo Denunciar

0

Hay más de una cosa en juego aquí. En un nivel, como explica la respuesta de Fraser, suponiendo que getRandomLetter es impuro (al no ser determinista), getRandomFileName también lo es.

Al menos, al hacer getRandomFileName2 una función de orden superior , al menos le da la oportunidad de ser una función pura . Suponiendo que getRandomFileName2 no realice ninguna otra acción impura, si le pasa una función pura, será transitivamente pura.

Si le pasa una función impura, también será, transitivamente, impura.

Darle a una función la oportunidad de ser pura puede ser útil para las pruebas, pero no implica que el diseño sea funcional. También puede usar la inyección de dependencia y Test Doubles para hacer que los objetos sean deterministas, pero eso no los hace funcionales .

En la mayoría de los lenguajes, incluido JavaScript, no puede obtener ninguna garantía de las funciones como valores de primera clase. Una función de una 'forma' (tipo) particular puede ser pura o impura, y no puede verificar esto ni en tiempo de compilación ni en tiempo de ejecución.

En Haskell, por otro lado, puedes declarar explícitamente si una función es pura o impura. Para tener siquiera la opción de llamar a una acción impura, una función debe ser declarada impura.

Por lo tanto, la oportunidad de ser impuro debe declararse en tiempo de compilación. Incluso si pasa una 'implementación' pura de un tipo impuro, la función receptora de orden superior todavía parece impura.

Si bien algo como lo descrito en el OP sería técnicamente posible en Haskell, haría que todo fuera impuro, por lo que no sería la forma en que lo hace.

Lo que haga en su lugar depende de las circunstancias y los requisitos. En el OP, parece que necesita exactamente 12 valores aleatorios. En lugar de pasar una acción impura como argumento, puede generar 12 valores aleatorios en el 'shell impuro' del programa y pasar esos valores a una función que luego puede permanecer pura.

Hay más en juego que solo probar. Si bien la capacidad de prueba es agradable, el diseño sugerido en el OP seguramente será impuro 'en producción' (es decir, cuando se componga con un generador de valor aleatorio adecuado).

Las acciones impuras son más difíciles de entender y sus interacciones pueden ser sorprendentes. Las funciones puras, por otro lado, son referencialmente transparentes , y la transparencia referencial cabe en tu cabeza .

Sería una buena idea tener como objetivo funciones puras siempre que sea posible. Es poco probable que el getRandomFileName2 propuesto sea puro cuando se compone con un generador de valores aleatorios 'reales', por lo que se garantiza un diseño más funcional.

almost 4 years ago · Santiago Trujillo Denunciar

0

Cualquier cosa que contenga random (o Date o cosas por el estilo). Se considerará impuro y difícil de probar porque lo que devuelve no depende estrictamente de sus entradas (siempre diferentes). Sin embargo, si se inyecta la parte aleatoria de la función, la función se puede hacer "pura" en el conjunto de pruebas reemplazando cualquier aleatoriedad inyectada con algo predecible.

 function getRandomFileName(fileExtension = "", randomLetterFunc = getRandomLetter) {}

se puede probar llamándolo con una función "getLetter" predecible en lugar de una función aleatoria:

 getRandomFileName("", predictableLetterFunc)
almost 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda