Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the colon from the directory name

On Windows, Git cannot check out paths containing : in a directory component, so pulling this commit makes the repository unusable for Windows-based students. Rename the directory to a cross-platform-safe form, such as replacing the colon with a hyphen.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use the mandated README.md filename

On case-sensitive filesystems, Readme.md is different from the required README.md. The delivery rules in research/TEMAS-INVESTIGACION-FUNCIONAL-2026B.md explicitly require that exact filename and state that renaming it is grounds for rejecting the submission, so this file must be renamed before the work can be accepted.

Useful? React with 👍 / 👎.

title: "Proyecto de Investigación --- Programación Lógica y Funcional 2026 \"B\""
subtitle: "Bloque 1: Programación Funcional (nivel introductorio) --- 40 temas de investigación y rúbrica de 5 categorías"
author: "TecNM Campus Tijuana --- Ingeniería en Sistemas Computacionales (ISC-2006)"
date: "Agosto 2026"
lang: es
geometry: "a4paper,margin=2.4cm"
fontsize: 11pt
---

# Efectos secundarios: qué son y por qué la programación funcional busca controlarlos

## Introducción

En programación, una función no siempre se limita a recibir datos y devolver un resultado. También puede modificar una variable global, escribir un archivo, consultar una base de datos o mostrar información en pantalla. Estas interacciones se denominan **efectos secundarios**.

Los efectos son necesarios para que un programa se comunique con el mundo exterior, pero pueden introducir dependencias difíciles de observar. Por ello, la programación funcional busca separarlos y mantenerlos en zonas controladas, mientras la lógica principal se construye con funciones puras. Haskell, por ejemplo, separa las acciones de entrada y salida de su núcleo funcional [1].

## 1. ¿Qué es un efecto secundario?

Un efecto secundario es un cambio observable que ocurre durante la ejecución de una función, además de producir su valor principal. La operación `2 + 3` únicamente devuelve `5`. En cambio, una función que calcula esa suma y también incrementa una variable global produce dos resultados: el valor calculado y una modificación en el estado del programa.

Algunos efectos secundarios comunes son:

- Modificar variables globales u objetos compartidos.
- Leer o escribir archivos.
- Imprimir en la consola o leer del teclado.
- Consultar o actualizar bases de datos.
- Enviar solicitudes por red.
- Consultar la fecha, la hora o números aleatorios.
- Lanzar excepciones.

Estos efectos no son necesariamente errores. Guardar una compra o mostrar una respuesta al usuario son acciones indispensables. El problema aparece cuando el efecto está mezclado con la lógica y no queda claro qué modifica, de qué recursos depende o en qué orden debe ejecutarse.

## 2. Funciones puras y transparencia referencial

Una **función pura** cumple dos condiciones: siempre produce el mismo resultado para las mismas entradas y no modifica información fuera de su alcance [3]. Por ejemplo, `doble(4)` puede sustituirse por `8` sin cambiar el comportamiento del programa. Esta propiedad se llama **transparencia referencial**.

```text
doble(4) + doble(4) ≡ 8 + 8
```

Una función que consulta la hora puede devolver resultados diferentes en cada llamada. Otra que incrementa un contador global modifica el programa incluso si devuelve siempre el mismo número. Ninguna de las dos es pura.

La pureza facilita el razonamiento: para comprender una función pura basta conocer sus parámetros y su resultado. En una función con efectos también se debe investigar el estado previo, el orden de ejecución y los recursos externos involucrados.

## 3. Ejemplo ejecutable en Python

Python no es un lenguaje funcional puro, pero permite aplicar este estilo. En la primera versión se mezclan el cálculo, el estado global y la salida:

```python
descuento = 0.10

def cobrar(precio):
total = precio * (1 - descuento)
print(f"Total: {total:.2f} pesos")
return total

cobrar(100)
```

La función `cobrar` depende de una variable externa y escribe en la consola. Si otro fragmento modifica `descuento`, el resultado será diferente aunque el argumento continúe siendo `100`.

Una alternativa es separar el cálculo puro del efecto:

```python
def calcular_total(precio, descuento):
return precio * (1 - descuento)

def mostrar_total(total):
print(f"Total: {total:.2f} pesos")

total = calcular_total(100, 0.10)
mostrar_total(total)

assert calcular_total(100, 0.10) == 90.0
```

Ahora `calcular_total` recibe todas sus dependencias como argumentos y puede probarse directamente. `mostrar_total` conserva el efecto de salida, pero está identificado y separado. Esta refactorización coincide con la recomendación de extraer funciones puras para reducir dependencias externas [3].

## 4. ¿Por qué controlar los efectos secundarios?

### 4.1 Predictibilidad

Una función pura se comporta como una relación matemática: la misma entrada genera el mismo resultado. Esto evita resultados inesperados causados por variables globales, configuraciones ocultas o cambios en el orden de ejecución.

### 4.2 Pruebas y depuración

Las funciones puras pueden probarse sin preparar archivos, conexiones de red, relojes o bases de datos. Microsoft indica que pueden evaluarse de forma aislada utilizando casos normales y casos límite [4].

### 4.3 Reutilización y composición

Las funciones pequeñas pueden combinarse con mayor seguridad porque intercambian valores explícitos y no modifican información externa.

### 4.4 Concurrencia más segura

Dos operaciones puras no compiten por modificar una misma variable. Esto reduce las condiciones de carrera, aunque no significa que cualquier programa funcional sea automáticamente concurrente.

### 4.5 Optimización

La transparencia referencial puede permitir almacenar resultados, eliminar cálculos que no se utilizan o evaluar expresiones independientes en paralelo. Scala incluso muestra una advertencia cuando una expresión pura aparece en una posición donde su resultado es descartado [5].

## 5. Formas de controlar los efectos

### 5.1 Inmutabilidad

En lugar de modificar una estructura existente, se crea un nuevo valor que contiene los cambios. De esta manera, el flujo de datos es más visible y se conserva el estado anterior.

### 5.2 Dependencias explícitas

Elementos como el reloj, la configuración o el acceso a datos pueden recibirse como argumentos. Durante una prueba pueden sustituirse por valores conocidos y controlados.

### 5.3 Núcleo funcional y borde imperativo

La validación, el cálculo y la transformación de los datos se colocan en un núcleo puro. La consola, la interfaz, la red y la persistencia permanecen en los bordes del sistema. El borde obtiene los datos, llama al núcleo y ejecuta las acciones necesarias.

### 5.4 Tipos que representan efectos

Haskell utiliza el tipo `IO` para señalar acciones relacionadas con la entrada y salida [1], [6]:

```haskell
saludar :: String -> String
saludar nombre = "Hola, " ++ nombre

main :: IO ()
main = do
nombre <- getLine
putStrLn (saludar nombre)
```

La función `saludar` representa una transformación pura. Las operaciones `getLine` y `putStrLn` permanecen en `main`, donde el tipo `IO` hace visible la interacción con el exterior.

## 6. Comparación

| Aspecto | Función pura | Función con efectos |
|---|---|---|
| Dependencias | Parámetros explícitos | Puede depender de estado, red o archivos |
| Resultado | Misma entrada, misma salida | Puede variar con la misma entrada |
| Estado externo | No lo modifica | Puede leerlo o modificarlo |
| Pruebas | Aisladas y directas | Requieren preparación o integración |
| Uso común | Cálculo, validación y transformación | Entrada, salida y persistencia |

## 7. Análisis crítico

Controlar los efectos secundarios también tiene costos. Dividir demasiado el código puede dificultar la lectura y algunas abstracciones funcionales requieren aprendizaje adicional. Además, un programa no se vuelve correcto únicamente por utilizar funciones puras: todavía puede contener errores de lógica, seguridad o requisitos.

El objetivo tampoco es prohibir `print`, las bases de datos o la comunicación por red. Una aplicación útil necesita interactuar con el exterior. La pregunta adecuada es: **¿el efecto es necesario, está identificado y puede mantenerse separado de la lógica principal?**

Haskell obliga a distinguir los efectos mediante `IO`, mientras que lenguajes como Scala y Python permiten aplicar esta separación de manera gradual [2]. Esto demuestra que los principios funcionales también pueden utilizarse en lenguajes que no son completamente funcionales.

## Conclusiones

Los efectos secundarios son cambios o interacciones observables adicionales al valor devuelto por una función. Permiten guardar datos, comunicarse por red y presentar resultados, pero también crean dependencias relacionadas con el estado y el orden de ejecución.

La programación funcional busca controlarlos para conseguir mayor predictibilidad, facilidad de prueba y menor interferencia entre operaciones. Su objetivo no es eliminar toda interacción, sino mantener un núcleo de funciones puras y concentrar los efectos en límites claros. De esta forma resulta más sencillo comprender qué calcula el sistema y en qué partes modifica el mundo exterior.

## Bibliografía

[1] P. Hudak, J. Peterson y J. Fasel, “Input/Output,” en *A Gentle Introduction to Haskell, Version 98*. Haskell.org, 2000. [En línea]. Disponible en: https://www.haskell.org/tutorial/io.html. [Consultado: 1-sep-2026].

[2] Scala Documentation, “Pure Functions,” *Scala Book*. [En línea]. Disponible en: https://docs.scala-lang.org/overviews/scala-book/pure-functions.html. [Consultado: 1-sep-2026].

[3] Microsoft, “Refactor into pure functions,” *Microsoft Learn*, 15-sep-2021. [En línea]. Disponible en: https://learn.microsoft.com/en-us/dotnet/standard/linq/refactor-pure-functions. [Consultado: 1-sep-2026].

[4] Microsoft, “Functional programming vs. imperative programming,” *Microsoft Learn*, 15-sep-2021. [En línea]. Disponible en: https://learn.microsoft.com/en-us/dotnet/standard/linq/functional-vs-imperative-programming. [Consultado: 1-sep-2026].

[5] Scala Documentation, “E129: Pure Expression In Statement Position,” *Scala 3 Reference*. [En línea]. Disponible en: https://docs.scala-lang.org/scala3/reference/error-codes/E129.html. [Consultado: 1-sep-2026].

[6] P. Hudak, J. Peterson y J. Fasel, “About Monads,” en *A Gentle Introduction to Haskell, Version 98*. Haskell.org, 2000. [En línea]. Disponible en: https://www.haskell.org/tutorial/monads.html. [Consultado: 1-sep-2026].

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Anexo: bitácora de asistencia de Inteligencia Artificial

## Prompts utilizados

- “Me podrías ayudar a hacer una investigación de nivel medio sobre el tema: Efectos secundarios: qué son y por qué la programación funcional busca controlarlos; todo esto en Markdown con sus respectivos títulos, incluyendo imágenes y citas bibliográficas, considerando este `AI_GUIDANCE.md`.”

## Herramientas utilizadas

- ChatGPT (Codex).
- Documentación oficial de Haskell.

Estas fuentes se utilizaron para comprobar las definiciones, los conceptos técnicos y los ejemplos presentados en la investigación.

## Resultados obtenidos

- Una investigación en Markdown organizada mediante introducción, desarrollo técnico, comparación, análisis crítico, conclusiones y bibliografía en formato IEEE.
- Una explicación de los efectos secundarios y su relación con las funciones puras y la transparencia referencial.
- Ejemplos de funciones puras e impuras escritos en Python.
- Un ejemplo en Haskell que separa la lógica pura de las operaciones de entrada y salida.
- Una tabla comparativa entre ambos tipos de funciones.
- Referencias provenientes de documentación oficial y fuentes técnicas.

## Cambios y validación

- Se revisó que la definición de función pura coincidiera con la documentación oficial consultada.
- Se corrigió la idea de que los efectos secundarios deben eliminarse completamente. La investigación explica que la programación funcional busca identificarlos, separarlos y controlarlos.
- Se redujo la extensión inicial de la investigación para presentar la información de manera más clara y resumida.
- Se agregó el encabezado YAML solicitado para identificar el proyecto, el curso, la institución, la fecha y el formato del documento.
- El ejemplo de Python se ejecutó con Python 3 y se comprobó que la aserción fuera correcta.
- Se verificó que el desarrollo técnico conservara más de las 500 palabras solicitadas por la rúbrica.

## Reflexión personal

La Inteligencia Artificial me ayudó a organizar la investigación y a comprender la diferencia entre eliminar los efectos secundarios y mantenerlos controlados. Aprendí que una aplicación necesita realizar acciones como leer información, mostrar resultados, utilizar archivos o comunicarse con una base de datos. Sin embargo, estas acciones pueden separarse de los cálculos principales para que el programa sea más fácil de comprender y probar.

También entendí que una función pura siempre produce el mismo resultado cuando recibe las mismas entradas y no modifica información externa. Esto permite detectar errores con mayor facilidad y reduce la dependencia del estado del programa.

La respuesta proporcionada por la IA fue revisada y resumida. Además, las definiciones principales fueron comparadas con documentación oficial de Haskell, Scala y Microsoft Learn. Este proceso me permitió reconocer que la información generada por una IA no debe utilizarse automáticamente, sino que debe comprenderse, verificarse y adaptarse antes de incluirla en un trabajo académico.

## Fecha

3 de septiembre de 2026.

## Plataforma de validación

- Python 3 para ejecutar y comprobar el ejemplo de funciones puras.
- Documentación oficial de Haskell para revisar la sintaxis de `IO`.