Hay lenguajes como el C en que estas dos estructuras de programación no se diferencian entre sí, mientras que en el superBASIC diferenciamos entre ambas según retornen o no un valor, siendo equivalentes el resto de sus características.
Ambas son estructuras recursivas, algo que en el BASIC estándar no existe como tal, aunque se puede hacer uso del GOSUB para conseguir cierta recursividad, es complejo por carecer de variables locales y las limitaciones del tamaño de la Pila de retorno lo hacen inviable en la mayoría de sistemas. Vemos un ejemplo muy sencillo de ambas:
BASIC | SuperBASIC | |
100 CLS 110 GOSUB 180 120 LET A=5:GOSUB 230:PRINT A 130 STOP 150 REM --------------------- 160 REM SALUDAR 170 REM --------------------- 180 PRINT "Hola a todos" 190 RETURN 200 REM --------------------- 210 REM INCREMENTAR 220 REM --------------------- 230 LET A=A+1 240 RETURN |
100 CLS 110 saluda 120 PRINT incremento(5) 130 REMark ------------------------ 140 REMark PROCEDIMIENTO: Saludar 150 REMark ------------------------ 160 DEFine PROCedure saluda 170 PRINT "Hola a todos" 180 END DEFine 190 REMark ------------------------ 200 REMark FUNCION:Incrementar 210 REMark ------------------------ 220 DEFine FuNction incremento(a) 230 RETurn a+1 240 END DEFine |
En BASIC estándar hay que usar GOSUB para ir a otras partes del programa, para lo que hay que conocer el número de línea en que se encuentra nuestra rutina, y no olvidar el RETURN final pues si no el programa se liará bastante, y como todas las instrucciones son ejecutables, es necesario parar el programa para que no vuelva a ejecutar la primera rutina. En SuperBASIC podemos definir rutinas con nombre, y llamarlas desde cualquier punto del programa por ese nombre, esos trozos no se ejecutarán nunca por si solos, lo que hace que sean mas sencillos de usar.
Además opcionalmente podemos usar todos los parámetros de entrada que deseemos, cuando se llama se deben usar valores o variables para estos parámetros, que son copiados por valor a la rutina, estos parámetros ya no son variables globales sino que se comportan como variables locales en la rutina, por lo que se simplifica mucho el manejo de las variables, en nuestro ejemplo pasamos una variable a la función incremento, esta recibe el valor en una variable que siempre es local, lo que simplifica mucho el diseño de buenas rutinas, que no afecten al resto del programa.
Vemos que el procedimiento no tiene valor alguno de retorno, mientras que la función lo tiene siempre, es importante tenerlo en cuenta, ya que no podemos llamar por ejemplo a PRINT saluda pues no hay valor de retorno, ni llamar directamente a incrementa si no usamos el valor retornado en ningún lugar. En esto se diferencia de C en que se puede no usar el valor de retorno.
El paso de parámetro a nuestras rutinas siempre se realiza por valor, si deseamos modificar el valor de una variable debemos recurrir a usar variables globales para ello. Una función puede retornar solo un valor, pero el tipo de este valor no se define por lo que podemos asignar una variable de cadena a una entera, y esperar que el SuperBASIC nos resuelva la conversión del tipo de la variable. A mi particularmente me gustan los lenguajes fuertemente tipados que me evitan errores, pero en nuestro querido QL no hay otra opción.
Vamos con la recursividad, usando el ejemplo típico del factorial. Ritchie, uno de los creadores del C, dijo que era muy mal ejemplo pues la solución iterativa del factorial es mas rápida y eficiente que la recursiva, y prefería poner como ejemplo la impresión de un número en pantalla, ya entraremos en eso.
BASIC iterativo | SuperBASIC recursivo | |
100 CLS 110 INPUT "Valor: ";V 120 GOSUB 180 130 PRINT "El factorial es: ";F 140 END 150 REM --------------------- 160 REM FACTORIAL 170 REM --------------------- 180 LET F=1 190 FOR I= V TO 1 STEP -1 200 F=F*I 210 NEXT I 220 RETURN |
100 CLS 110 INPUT "Valor: ";v 120 PRINT "El factorial es: ";factorial(v) 190 REMark ------------------------ 200 REMark FUNCION: Factorial 210 REMark ------------------------ 220 DEFine FuNction factorial(a) 230 IF (a = 0) THEN 231 RETurn 1 232 ELSE 233 RETurn a * factorial(a-1) 234 END IF 240 END DEFine |
Este ejemplo pone en claro que en caso del BASIC estándar, debemos conocer la dirección del programa en que se encuentra la rutina y los valores de variables que usará, mientras que en SuperBASIC nos vale con saber el nombre de la rutina. Si tenéis curiosidad y ejecutáis en un QL el programa para el valor 200, el resultado tardará un poco pero será 3.060575E614 presentando el resultado en notación científica, si ponéis en marcha un GWBASIC por ejemplo con el DOSBOX, el proceso iterativo dará un error de OverFlow para valores mayores a 33.
Otra característica muy útil es la posibilidad de usar variables locales, lo que evita muchos errores de programación, simplemente definiéndolas como primera instrucción de la función o el procedimiento:
100 b=10 : calculos: PRINT b 200 DEFine PROCedure calculos 210 LOCAL b 220 b = 20 230 END DEFine
Si ejecuta este programa tal cual, el valor que imprime es 10, pero si elimina la línea 210, el valor que mostrará será 20. Siempre todos los parámetros que reciba serán tratados como variables locales.
No hay comentarios:
Publicar un comentario