Definición de programación
Existen múltiples lenguajes de programación, pero todos comparten características comunes, en su definición, en sus componentes y en la forma en que podemos esperar que funcionen.
Aunque sin entrar en explicaciones teóricas complejas, sobre las que el lector puede encontrar buenos textos en la web o consultar la bibliografía especializada, me interesa para el desarrollo de nuestros conocimientos de programación, iniciar esta sección sobre los modelos de programación, hablando, aunque sea brevemente, de dos modelos básicos de programación: la lineal (o imperativa) y la estructurada (también modular). Estas denominaciones pueden no ser estrictas desde la perspectiva de la teoría y la historia de los modelos de programación, pero es útil a mi objetivo, ya que permitirá diferenciar dos estrategias básicas (las dos de mayor uso en este blog).
En efecto, la programación imperativa, que yo voy a asimilar al concepto de linealidad (de ahí lo de programación lineal), es el modelo de programación más antiguo, según el cual un programa es una secuencia de instrucciones sucesivas. Integra también el uso de ciclos o bucles y condicionales, pero se caracteriza por el uso (a veces profusamente) de la instrucción GoTo.
Mediante GoTo (también GOTO) se redirige el programa a una posición determinada de la secuencia de instrucciones, en función de determinadas condiciones. Este modo de proceder es fuente de que lo que en principio se enuncia como simple, termine por convertirse en complejo, y sobre todo dificulta el seguimiento del programa.
Es el modelo de programación que subyace a los lenguajes Basic iniciales y hoy en día no se practica como tal modelo, debido a las dificultades de gestión y mantenimiento que genera el uso de GoTo y por requerir largas secuencias de instrucciones.
Como alternativa, surgió el modelo de programación estructurada (década de 1960), una de cuyas evoluciones a posteriori fue el modelo de programación modular.
Al contrario de la programación imperativa, en la programación estructurada no se hace uso de la sentencia GoTo, optando por el uso de subrutinas ejecutadas (eso sí) secuencialmente, y privilegiando el uso de las estructuras de control (condicionales, ciclos e iteraciones o ciclos con condición inicial)
Una evolución (según algunos autores) de la programación estructurada es la programación modular que se caracteriza por subdividir un programa en módulos o subprogramas a los que se recurre en función del desarrollo del algoritmo, lo que la diferencia de la programación estructurada, que mantiene el principio de linealidad en es uso de las subrutinas. Una ventaja añadida del modelo modular es la posibilidad de reutilizar código (módulos) en función de necesidades, lo que reduce la extensión del programa final.
Después de esta breve introducción, me interesa justificar su utilidad de cara a que entendamos el proceso de diferenciación que paulatinamente vamos a ver desarrollada cuando nos iniciemos, por ejemplo, en el conocimiento de los procedimientos de trabajo que vamos a desarrollar sobre OOo Basic.
También será de interés a la hora de analizar cómo trabajar de forma más funcional con el código que genera Grabar macro y nuestra conversión del mismo en subrutinas o en funciones diferenciadas.
Lo que no voy a hacer, en este caso, es ejemplificar en PSeInt estos dos (a grandes rasgos) modelos de programación: lineal vs. estructurada-modular (que es la diferenciación que realmente nos interesa) porque nos aporta poco desde esta perspectiva y porque lo tendremos que trabajar con cierta profundidad en los contextos que antes señalé.
Para empezar, desde la perspectiva con la que estamos trabajando, podemos decir que la programación orientada a objetos (POO) es un desarrollo de la programación funcional en la que "empaquetamos" juntos (en una clase) una serie de variables que contienen datos relevantes sobre ese algo con el que queremos trabajar (atributos) y una serie de funciones, que ahora llamamos métodos y que representa el comportamiento típico e igualmente relevante de ese algo. Ese algo es la concreción de la clase y se llama objeto, que no es otra cosa que una instancia de la clase.
La POO se acerca al modo en que funcionan las cosas en la realidad, lo que facilita el desarrollo de programas sostenibles y fáciles de mantener, compuesto por piezas simples y reutilizables que interaccionan entre si.
Además, al igual que sucede con la programación funcional, son pertinentes los conceptos de abstracción y encapsulamiento, ambos complementarios entre sí. Esta pertinencia refuerza la idea de que la POO está emparentada con la programación funcional:
Aunque esto pueda parecer muy abstracto, en realidad es una forma muy común de proceder cuando nos encontramos con problemas complejos. El famoso "vamos por partes..." no es más que la vulgarización de esta filosofía de trabajo.
Desde el punto de vista de la programación (que es lo que nos ocupa), el siguiente esquema representa el procedimiento de trabajo que supone aplicar el modelo o paradigma funcional.
def factorial(n):
if n==0:return 1else:return n * factorial(n-1) # En este punto se produce la reutilización de la función
dentro de la misma función (recursividad)
def main():n=eval(input("Introduce un entero positivo para calcular su factorial: "))print("El factorial de ", n , " es ", factorial(n))main()
Cuando un programa, una aplicación o como sea pertinente o preferible llamarlo, es de cierta complejidad, ésta se refleja en su extensión en número de líneas, pero y también, en su complejidad. Dentro de estos dos parámetros podemos incluir la repetición de una serie de líneas de código con funcionalidad específica que se pueden identificar como unidades de acción.
El modelo modular no rompe la lógica del modelo lineal, simplemente hace más eficiente nuestro algoritmo, más sostenible y más robusto. Además, esos segmentos pueden ser reutilizados en otros programas o aplicaciones, lo que incrementa nuestra eficiencia a la hora de desarrollar proyectos.
En líneas generales, el comportamiento de estos módulos que llamaremos funciones, en sentido general, por cumplir una función específica, presentan estos comportamientos: