Siguiente: , Anterior: , Subir: Definición de Funciones   [Índice general][Índice]

36.2 Funciones

36.2.1 Funciones ordinarias

Para definir una función en Maxima es necesario utilizar el operador ’:=’.

Por ejemplo,

f(x) := sin(x)

define una función f. También se pueden definir funciones anónimas utilizando lambda; por ejemplo,

lambda ([i, j], ...)

puede utilizarse en lugar de f donde

f(i,j) := block ([], ...);
map (lambda ([i], i+1), l)

devolvería una lista con todos sus elementos aumentados en una unidad.

También se puede definir una función con un número variable de argumentos, sin más que añadir un argumento final al que se le asigna una lista con todos los argumentos adicionales.:

(%i1) f ([u]) := u;
(%o1)                      f([u]) := u
(%i2) f (1, 2, 3, 4);
(%o2)                     [1, 2, 3, 4]
(%i3) f (a, b, [u]) := [a, b, u];
(%o3)               f(a, b, [u]) := [a, b, u]
(%i4) f (1, 2, 3, 4, 5, 6);
(%o4)                 [1, 2, [3, 4, 5, 6]]

El miembro derecho de una función debe ser una expresión. Así, si se quiere una secuencia de expresiones, se debe hacer

f(x) := (expr1, expr2, ...., exprn);

siendo el valor que alcance exprn el devuelto por la función.

Si se quiere hacer un return desde alguna de las expresiones de la función, se debe utilizar la estructura block junto con return. Por ejemplo,

block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)

es una expresión de pleno derecho, por lo que puede ocupar el lado derecho de la definición de una función. Aquí puede ocurrir que el retorno se produzca antes que se alcance la última expresión.

Los primeros corchetes del bloque ([]) pueden contener una lista de variables junto con posibles asignaciones, tal como [a: 3, b, c: []], lo que provocará que las tres variables a,b y c se consideren locales y sean independientes de otras globales con el mismo nombre; las variables locales sólo estarán activas mientras se ejecute el código que está dentro de la estructura block, o dentro de funciones que son llamadas desde dentro de block. A esto se le llama asignación dinámica, pues las variables sobreviven desde el inicio del bloque hasta que éste deje de estar operativo. Una vez se salga del bloque los valores originales de las variables, si es que los había, quedan restaurados. Es recomendable proteger las variables de esta forma. Se tendrá en cuenta que las asignaciones a las variables del bloque se hacen en paralelo, lo que significa que si como en el ejemplo anterior se hace c: a en el momento de entrar en el bloque, el valor de c será el que tenía a antes de entrar en el bloque, es decir, antes de la asignación a: 3. Así, haciendo lo siguiente

block ([a: a], expr1, ... a: a+3, ..., exprn)

se prevendría de que el valor externo de a fuese alterado, pero permitiría acceder a él desde dentro del bloque. La parte derecha de las asignaciones se evalúa dentro de su contexto antes de hacer efectiva la asignación. Utilizando únicamente block([x],.. haría que x se tuviese a sí misma como valor, justo como si se acabase de iniciar una nueva sesión de Maxima.

Los valores de los argumentos de una funcón se tratan exactamente de la misma forma que las variables de un bloque. Así, con

f(x) := (expr1, ..., exprn);

y

f(1);

se estaría en un contexto similar para la evaluación de las expresiones como si se hubiera hecho

block ([x: 1], expr1, ..., exprn)

Dentro de las funciones, cuando el lado derecho de la definición deba ser evaluado será útil hacer uso de define y posiblemente de buildq.

36.2.2 Funciones array

Una función array almacena el valor de la función la primera vez que es invocada con un argumento dado, devolviendo el valor almacenado sin recalcularlo cuando es llamada con ese mismo argumento. Estas funciones reciben también el nombre de funciones memorizadoras.

Los nombres de las funciones array son añadidos a la lista global arrays, no a la lista global functions. La función arrayinfo devuelve la lista de argumentos para los que hay valores almacenados y listarray devuelve precisamente estos valores almacenados. Las funciones dispfun y fundef devuelven la definición de la función array.

La función arraymake construye una llamada a una función array, de forma similar a como lo hace funmake para las funciones ordinarias. Por otro lado, arrayapply aplica una función array a sus argumentos, tal como lo hace apply con las funciones ordinarias. No existe para las funciones array nada similar a map, aunque map(lambda([x], a[x]), L) o makelist(a[x], x, L), siendo L una lista, podrían suplantar esta carencia.

La función remarray borra la definición de una función array, así como cualesquiera valores almacenados que tenga asociados, tal como remfunction lo hace con las funciones ordinarias.

La llamada kill(a[x]) borra el valor de la función array a almacenado para el argumento x; la próxima vez que se llame a a con el argumento x, se recalculará el valor correspondiente. Sin embargo, no hay forma de borrar todos los valores almacenados de una sola vez, excepto mediante kill(a) o remarray(a), con lo que se borra también la definición de la propia función.


Siguiente: , Anterior: , Subir: Definición de Funciones   [Índice general][Índice]