@c English version 2011-06-15
@menu
* Introducción a la definición de funciones::  
* Funciones::                    
* Macros::                       
* Funciones y variables para la definición de funciones::  
@end menu

@node Introducción a la definición de funciones, Funciones, Definición de Funciones, Definición de Funciones
@section Introducción a la definición de funciones

@node Funciones, Macros, Introducción a la definición de funciones, Definición de Funciones

@section Funciones
@subsection Funciones ordinarias

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

Por ejemplo,

@example
f(x) := sin(x)
@end example
@noindent

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

@example
lambda ([i, j], ...)
@end example

@noindent
puede utilizarse en lugar de @code{f} donde

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

@noindent
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.:

@example
(%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]]
@end example

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

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

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

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

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

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 (@code{[]}) pueden contener una lista de variables junto con posibles asignaciones, tal como @code{[a: 3, b, c: []]}, lo que provocará que las tres variables @code{a},@code{b} y @code{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 @code{block}, o dentro de funciones que son llamadas desde dentro de @code{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 @code{c: a} en el momento de entrar en el bloque, el valor de @code{c} será el que tenía @code{a} antes de entrar en el bloque, es decir, antes de la asignación @code{a: 3}. Así, haciendo lo siguiente


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

se prevendría de que el valor externo de @code{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 @code{block([x],..} haría que @code{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

@example
f(x) := (expr1, ..., exprn);
@end example

y

@example
f(1);
@end example

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

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

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

@subsection 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 @i{funciones memorizadoras}.

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

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

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

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

@node Macros, Funciones y variables para la definición de funciones, Funciones, Definición de Funciones
@section Macros


@deffn {Función} buildq (@var{L}, @var{expr})
Sustituye en paralelo las variables nombradas en la lista @var{L} en la expresión @var{expr}, sin evaluar ésta.
La expresión resultante se simplifica pero no se evalúa hasta que @code{buildq} termine de hacer las sustituciones.

Los elementos de @var{L} son símbolos o expresiones de asignación del tipo @code{@var{symbol}: @var{value}},
evaluadas en paralelo. Esto es, el valor de una variable en la parte derecha de una asignación es el valor que toma dicha variable en el contexto desde el que se invoca a @code{buildq}. En caso de que a una variable de @var{L} no se le haga una signación explícita, su valor en @code{buildq} es el mismo que tiene en el contexto desde el que se llama a @code{buildq}.

Las variables referenciadas en @var{L} se sustituyen en @var{expr} en paralelo. Esto es, la sustitución para cada variable se determina antes de que se hagan las sustituciones, de forma que la sustitución de una variable no tiene efecto alguno sobre las otras.

Si alguna variable @var{x} aparece como @code{splice (@var{x})} en @var{expr}, entonces a @var{x} se le debe asignar una lista, la cual será interpolada en @var{expr} en lugar de hacer una simple sustitución; ver ejemplo más abajo.

Cualesquiera otras variables de @var{expr} que no aparezcan en @var{L} se traspasan al resultado tal cual, incluso cuando tienen asignados valores en el contexto desde el que se llama a @code{buildq}.

Ejemplos:

@code{a} queda asociada explícitamente a @code{x}, mientras que @code{b} tiene la misma asociación (29) que en el contexto de llamada y @code{c} es traspasado al resultado sin ser sustituido. La expresión resultante no se evalúa hasta que no se le obligue a ello mediante la evaluación explícita @code{''%}.

@c ===beg===
@c (a: 17, b: 29, c: 1729)$
@c buildq ([a: x, b], a + b + c);
@c ''%;
@c ===end===
@example
(%i1) (a: 17, b: 29, c: 1729)$
(%i2) buildq ([a: x, b], a + b + c);
(%o2)                      x + c + 29
(%i3) ''%;
(%o3)                       x + 1758
@end example

En este ejemplo, @code{e} se asocia a una lista, la cual aparece como tal en los argumentos de @code{foo} e interpolada en los argumentos de @code{bar}.

@c ===beg===
@c buildq ([e: [a, b, c]], foo (x, e, y));
@c buildq ([e: [a, b, c]], bar (x, splice (e), y));
@c ===end===
@example
(%i1) buildq ([e: [a, b, c]], foo (x, e, y));
(%o1)                 foo(x, [a, b, c], y)
(%i2) buildq ([e: [a, b, c]], bar (x, splice (e), y));
(%o2)                  bar(x, a, b, c, y)
@end example

Como se ve a continuación, el resultado se simplifica tras las sustituciones. Si la simplificación se realizase antes que las sustituciones, ambos resultados serían iguales.

@c ===beg===
@c buildq ([e: [a, b, c]], splice (e) + splice (e));
@c buildq ([e: [a, b, c]], 2 * splice (e));
@c ===end===
@example
(%i1) buildq ([e: [a, b, c]], splice (e) + splice (e));
(%o1)                    2 c + 2 b + 2 a
(%i2) buildq ([e: [a, b, c]], 2 * splice (e));
(%o2)                        2 a b c
@end example

Las variables de @var{L} se asocian en paralelo; si se hiciese secuencialmente, el primer resultado sería @code{foo (b, b)}. Las sustituciones se llevan a cabo en paralelo. Compárese el segundo resultado con el resultado de @code{subst}, que hace las sustituciones de forma secuencial.

@c ===beg===
@c buildq ([a: b, b: a], foo (a, b));
@c buildq ([u: v, v: w, w: x, x: y, y: z, z: u],
@c         bar (u, v, w, x, y, z));
@c subst ([u=v, v=w, w=x, x=y, y=z, z=u],
@c        bar (u, v, w, x, y, z));
@c ===end===
@example
(%i1) buildq ([a: b, b: a], foo (a, b));
(%o1)                       foo(b, a)
(%i2) buildq ([u: v, v: w, w: x, x: y, y: z, z: u],
              bar (u, v, w, x, y, z));
(%o2)                 bar(v, w, x, y, z, u)
(%i3) subst ([u=v, v=w, w=x, x=y, y=z, z=u],
             bar (u, v, w, x, y, z));
(%o3)                 bar(u, u, u, u, u, u)
@end example

Se construye a continuación un sistema de ecuaciones con algunas variables o expresiones en el lado izquierdo y sus valores en el derecho; @code{macroexpand} muestra la expresión devuelta por @code{show_values}.

@c ===beg===
@c show_values ([L]) ::= buildq ([L], map ("=", 'L, L));
@c (a: 17, b: 29, c: 1729)$
@c show_values (a, b, c - a - b);
@c macroexpand (show_values (a, b, c - a - b));
@c ===end===
@example
(%i1) show_values ([L]) ::= buildq ([L], map ("=", 'L, L));
(%o1)   show_values([L]) ::= buildq([L], map("=", 'L, L))
(%i2) (a: 17, b: 29, c: 1729)$
(%i3) show_values (a, b, c - a - b);
(%o3)          [a = 17, b = 29, c - b - a = 1683]
(%i4) macroexpand (show_values (a, b, c - a - b));
(%o4)    map(=, '([a, b, c - b - a]), [a, b, c - b - a])
@end example

Dada una función con varios argumentos, se crea otra función
en la cual algunos argumentos son fijos.

@c ===beg===
@c curry (f, [a]) :=
@c         buildq ([f, a], lambda ([[x]], apply (f, append (a, x))))$
@c by3 : curry ("*", 3);
@c by3 (a + b);
@c ===end===

@example
(%i1) curry (f, [a]) :=
        buildq ([f, a], lambda ([[x]], apply (f, append (a, x))))$
(%i2) by3 : curry ("*", 3);
(%o2)        lambda([[x]], apply(*, append([3], x)))
(%i3) by3 (a + b);
(%o3)                       3 (b + a)
@end example
@end deffn



@deffn {Función} macroexpand (@var{expr})
Devuelve la macroexpansión de @var{expr}, sin evaluarla,
cuando @code{expr} es una llamada a una función macro; en caso contrario,
@code{macroexpand} devuelve @var{expr}.

Si la expansión de @var{expr} devuelve otra llamada a una función macro, esta llamada también se expande.

La función @code{macroexpand} no evalúa su argumento.
Sin embargo, si la expansión de una llamada a función macro tiene efectos laterales, éstos se ejecutan.

Véanse también @code{::=}, @code{macros} y @code{macroexpand1}.

Ejemplos:

@c ===beg===
@c g (x) ::= x / 99;
@c h (x) ::= buildq ([x], g (x - a));
@c a: 1234;
@c macroexpand (h (y));
@c h (y);
@c ===end===
@example
(%i1) g (x) ::= x / 99;
                                    x
(%o1)                      g(x) ::= --
                                    99
(%i2) h (x) ::= buildq ([x], g (x - a));
(%o2)            h(x) ::= buildq([x], g(x - a))
(%i3) a: 1234;
(%o3)                         1234
(%i4) macroexpand (h (y));
                              y - a
(%o4)                         -----
                               99
(%i5) h (y);
                            y - 1234
(%o5)                       --------
                               99
@end example

@end deffn

@deffn {Función} macroexpand1 (@var{expr})
Devuelve la macroexpansión de @var{expr}, sin evaluarla,
cuando @code{expr} es una llamada a una función macro; en caso contrario,
@code{macroexpand1} devuelve @var{expr}.

La función @code{macroexpand1} no evalúa su argumento.
Sin embargo, si la expansión de una llamada a función macro tiene efectos laterales, éstos se ejecutan.

Si la expansión de @var{expr} devuelve otra llamada a una función macro, esta llamada no se expande.

Véanse también @code{::=}, @code{macros} y @code{macroexpand}.

Ejemplos:

@c ===beg===
@c g (x) ::= x / 99;
@c h (x) ::= buildq ([x], g (x - a));
@c a: 1234;
@c macroexpand1 (h (y));
@c h (y);
@c ===end===
@example
(%i1) g (x) ::= x / 99;
                                    x
(%o1)                      g(x) ::= --
                                    99
(%i2) h (x) ::= buildq ([x], g (x - a));
(%o2)            h(x) ::= buildq([x], g(x - a))
(%i3) a: 1234;
(%o3)                         1234
(%i4) macroexpand1 (h (y));
(%o4)                       g(y - a)
(%i5) h (y);
                            y - 1234
(%o5)                       --------
                               99
@end example

@end deffn

@defvr {Variable global} macros
Valor por defecto: @code{[]}

La variable @code{macros} es la lista de las funciones macro definidas por el usuario.
El operador de definición de funciones macro @code{::=} coloca la nueva función macro en esta lista,
mientras que  @code{kill}, @code{remove} y @code{remfunction} eliminan las funciones macro de la lista.

Véase también @code{infolists}.

@end defvr

@deffn {Función} splice (@var{a})

Interpola la lista nombrada por el átomo  @var{a} dentro de una expresión, pero sólo si @code{splice} aparece dentro de @code{buildq}; en otro caso, @code{splice} se considera una función no definida. Si @var{a} aparece dentro de @code{buildq} sin @code{splice}, entonces queda sustituida por una lista dentro del resultado. El argumento de @code{splice} debe ser un átomo, no pudiendo ser una lista literal ni una expresión que devuelva una lista.

Normalmente @code{splice} suministra los argumentos para una función u operador. Para una función @code{f}, la expresión @code{f (splice (@var{a}))} dentro de @code{buildq} se convierte en @code{f (@var{a}[1], @var{a}[2], @var{a}[3], ...)}. Dado un operador @code{o}, la expresión @code{"o" (splice (@var{a})} dentro de @code{buildq} se convierte en 
@code{"o" (@var{a}[1], @var{a}[2], @var{a}[3], ...)}, donde @code{o} puede ser cualquier tipo de operador, normalmente uno que admita varios argumentos. Nótese que el operador debe ir encerrado entre comillas dobles @code{"}.

Ejemplos:

@c ===beg===
@c buildq ([x: [1, %pi, z - y]], foo (splice (x)) / length (x));
@c buildq ([x: [1, %pi]], "/" (splice (x)));
@c matchfix ("<>", "<>");
@c buildq ([x: [1, %pi, z - y]], "<>" (splice (x)));
@c ===end===
@example
(%i1) buildq ([x: [1, %pi, z - y]], foo (splice (x)) / length (x));
                       foo(1, %pi, z - y)
(%o1)                -----------------------
                     length([1, %pi, z - y])
(%i2) buildq ([x: [1, %pi]], "/" (splice (x)));
                                1
(%o2)                          ---
                               %pi
(%i3) matchfix ("<>", "<>");
(%o3)                          <>
(%i4) buildq ([x: [1, %pi, z - y]], "<>" (splice (x)));
(%o4)                   <>1, %pi, z - y<>
@end example

@end deffn

@node Funciones y variables para la definición de funciones, , Macros, Definición de Funciones
@section Funciones y variables para la definición de funciones

@deffn {Función} apply (@var{F}, [@var{x_1}, ..., @var{x_n}])
Construye y evalúa la expresión @code{@var{F}(@var{arg_1}, ..., @var{arg_n})}.

La función @code{apply} no hace distinciones entre funciones array y 
funciones ordinarias; cuando @var{F} es el nombre de una función array,
@code{apply} evalúa @code{@var{F}(...)}, esto es, hace una llamada con
paréntesis en lugar de corchetes. La función @code{arrayapply}
evalúa una llamada a función con corchetes para estos casos.

Ejemplos:

La función @code{apply} evalúa sus argumentos.
En este ejemplo, @code{min} se aplica al valor de @code{L}.

@c ===beg===
@c L : [1, 5, -10.2, 4, 3];
@c apply (min, L);
@c ===end===
@example
(%i1) L : [1, 5, -10.2, 4, 3];
(%o1)                 [1, 5, - 10.2, 4, 3]
(%i2) apply (min, L);
(%o2)                        - 10.2
@end example

La función @code{apply} evalúa sus argumentos,
incluso cuando la función @var{F} no lo hace.

@c ===beg===
@c F (x) := x / 1729;
@c fname : F;
@c dispfun (F);
@c dispfun (fname);
@c apply (dispfun, [fname]);
@c ===end===
@example
(%i1) F (x) := x / 1729;
                                   x
(%o1)                     F(x) := ----
                                  1729
(%i2) fname : F;
(%o2)                           F
(%i3) dispfun (F);
                                   x
(%t3)                     F(x) := ----
                                  1729

(%o3)                         [%t3]
(%i4) dispfun (fname);
fname is not the name of a user function.
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i5) apply (dispfun, [fname]);
                                   x
(%t5)                     F(x) := ----
                                  1729

(%o5)                         [%t5]
@end example

La función @code{apply} evalúa el nombre de función @var{F}.
La comilla simple @code{'} evita la evaluación.
El nombre @code{demoivre} corresponde a una variable global y
también a una función.

@c ===beg===
@c demoivre;
@c demoivre (exp (%i * x));
@c apply (demoivre, [exp (%i * x)]);
@c apply ('demoivre, [exp (%i * x)]);
@c ===end===
@example
(%i1) demoivre;
(%o1)                         false
(%i2) demoivre (exp (%i * x));
(%o2)                  %i sin(x) + cos(x)
(%i3) apply (demoivre, [exp (%i * x)]);
demoivre evaluates to false
Improper name or value in functional position.
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i4) apply ('demoivre, [exp (%i * x)]);
(%o4)                  %i sin(x) + cos(x)
@end example

@end deffn


@deffn {Función} block ([@var{v_1}, ..., @var{v_m}], @var{expr_1}, ..., @var{expr_n})
@deffnx {Función} block (@var{expr_1}, ..., @var{expr_n})

La función @code{block} evalúa @var{expr_1}, ..., @var{expr_n} secuencialmente y devuelve el valor de la última expresión evaluada. La secuencia puede alterarse con las funciones @code{go}, @code{throw} y @code{return}. La última expresión es @var{expr_n} a menos que @code{return} o una expresión que contenga un @code{throw} sea evaluada. Las variables @var{v_1}, ..., @var{v_m} son locales en el bloque; éstas se distiguen de las globales que tengan el mismo nombre. Si no se declaran variables locales entonces se puede omitir la lista. Dentro del bloque, cualquier otra variable distinta de @var{v_1}, ..., @var{v_m} se considera global.

La función @code{block} guarda los valores actuales de las variables @var{v_1}, ..., @var{v_m}, si los tienen, a la entrada del bloque y luego las evalúa a sí mismas, es decir les saca el valor temporalmente. A las variables locales se les puede asignar cualquier valor dentro del bloque, pero al salir de éste, los valores inicialmente almacenados quedan restaurados, al tiempo que los asignados dentro del bloque se pierden.

La declaración @code{local(@var{v_1}, ..., @var{v_m})} dentro de un bloque
almacena las propiedades asociadas a los símbolos @var{v_1}, ..., @var{v_m},
borra cualesquiera otras propiedades antes de evaluar las expresiones y
restaura las propiedades guardadas antes de abandonar el bloque.
Algunas declaraciones, como @code{:=}, @code{array}, @code{dependencies}, @code{atvalue},
@code{matchdeclare}, @code{atomgrad}, @code{constant}, @code{nonscalar}, @code{assume}
y otras se implementan como propiedades de símbolos.
El efecto producido por @code{local} consiste en hacer que tales declaraciones tengan
efecto sólo dentro del bloque, en otro caso las declaraciones dentro del bloque 
tendrían un efecto global que afectarían al exterior de @code{block}.

Un @code{block} puede aparecer dentro de otro @code{block}. Las variables locales se inicializan cada vez que se entra dentro de un nuevo bloque. Las variables locales de un bloque se consideran globales dentro de otro anidado dentro del primero. Si una variable es no local dentro de un bloque, su valor es el que le corresponde en el bloque superior. Este criterio se conoce con el nombre de "alcance dinámico".

El valor del bloque es el de la última sentencia o el argumento de la función @code{return}, que puede utilizarse para salir del bloque. La función @code{go} puede usarse para transferir el control a la sentencia del bloque que esté etiquetada con el argumento de @code{go}. Para etiquetar una sentencia basta que vaya precedida de un argumento atómico como cualquier otra sentencia dentro del bloque. Por ejemplo, @code{block ([x], x:1, tururu, x: x+1, ..., go(tururu), ...)}.  El argumento de @code{go} debe ser el nombre de una etiqueta colocada dentro del bloque. No se puede utilzar @code{go} para trasladarse a una etiqueta de un bloque que no sea el que contenga a @code{go}.

Normalmente los bloques aparecerán al lado derecho de las definiciones de funciones, pero también pueden utilizarse en otros contextos.

@end deffn

@deffn {Función} break (@var{expr_1}, ..., @var{expr_n})

Calcula e imprime @var{expr_1}, ..., @var{expr_n} para luego provocar la detención de Maxima, de modo que el usuario pueda examinar y cambiar el entorno de ejecución. Pulsando posteriormente @code{exit;} el cálculo se reanuda.

@end deffn

@deffn {Función} catch (@var{expr_1}, ..., @var{expr_n})

Evalúa @var{expr_1}, ..., @var{expr_n} una a una;  si alguna de ellas conlleva la evaluación de una expresión de la forma @code{throw (arg)}, entonces el valor de @code{catch} es el de @code{throw (arg)} y ya no se evalúan más expresiones. Esta respuesta pasa todos los niveles de anidamiento hasta el @code{catch} más próximo. Si no hay ningún @code{catch}  que contenga un @code{throw} se emite un mensaje de error.

Si la evaluación de los argumentos no conlleva la evaluación de ningún @code{throw}, entonces el valor de @code{catch} es el devuelto por @var{expr_n}.

@example
(%i1) lambda ([x], if x < 0 then throw(x) else f(x))$
(%i2) g(l) := catch (map (''%, l))$
(%i3) g ([1, 2, 3, 7]);
(%o3)               [f(1), f(2), f(3), f(7)]
(%i4) g ([1, 2, -3, 7]);
(%o4)                          - 3
@end example

La función @code{g} devuelve las imágenes por @code{f} de todos los elementos de la lista @code{l} si ésta contiene únicamente números no negativos; si no es este el caso, entonces @code{g} captura el primer negativo que encuentra y lo devuelve por medio del @code{throw}.

@end deffn

@deffn {Function} compfile (@var{filename}, @var{f_1}, @dots{}, @var{f_n})
@deffnx {Function} compfile (@var{filename}, functions)
@deffnx {Function} compfile (@var{filename}, all)

Traduce funciones de Maxima a código Lisp, guardándolo 
luego en el fichero @var{filename}.

Con la llamada @code{compfile(@var{filename}, @var{f_1}, @dots{}, @var{f_n})}
se traducen las funciones especificadas, mientras que 
@code{compfile(@var{filename}, functions)} y
@code{compfile(@var{filename}, all)} traducen las funciones definidas por
el usuario.

El código Lisp traducido no se evalúa, ni el fichero 
de salida es procesado por el compilador de Lisp.
La función @code{translate} crea y evalúa las traducciones Lisp, mientras que
@code{compile_file} traduce primero de Maxima a Lisp y luego
ejecuta el compilador Lisp. 

Véanse también @code{translate}, @code{translate_file} y @code{compile_file}.

@end deffn

@deffn {Función} compile (@var{f_1}, ..., @var{f_n})
@deffnx {Función} compile (functions)
@deffnx {Función} compile (all)

Traduce las funciones de Maxima @var{f_1}, ..., @var{f_n} a Lisp, evaluando el código resultante, y llama a la función Lisp @code{COMPILE} para cada función traducida. La función @code{compile} devuelve una lista con los nombres de las funciones compiladas.

Las llamadas @code{compile (all)} o @code{compile (functions)} compilan todas las funciones definidas por el usuario.

La función @code{compile} no evalúa sus argumentos, pero con el operador comilla-comilla (@code{'@w{}'}) sí lo hace.

@end deffn

@deffn {Función} define (@var{f}(@var{x_1}, ..., @var{x_n}), @var{expr})
@deffnx {Función} define (@var{f}[@var{x_1}, ..., @var{x_n}], @var{expr})
@deffnx {Función} define (funmake (@var{f}, [@var{x_1}, ..., @var{x_n}]), @var{expr})
@deffnx {Función} define (arraymake (@var{f}, [@var{x_1}, ..., @var{x_n}]), @var{expr})
@deffnx {Función} define (ev (@var{expr_1}), @var{expr_2})

Define una función de nombre @var{f} con argumentos @var{x_1}, ..., @var{x_n} y cuerpo @var{expr}.
@code{define} evalúa siempre su segundo argumento, a menos que se
indique lo contrario con el operador de comilla simple. La función así
definida puede ser una función ordinaria de Maxima (con sus argumentos
encerrados entre paréntesis) o una función array (con sus argumentos encerrados
entre corchetes).

Cuando el último o único argumento @var{x_n} es una lista de un solo 
elemento, la función definida por @code{define} acepta un número variable
de argumentos. Los valores de los argumentos se van asignando uno a uno a 
@var{x_1}, ..., @var{x_(n - 1)}, y los que queden, si los hay, se asignan 
a @var{x_n} en forma de lista.

Cuando el primer argumento de @code{define} es una expresión de la
forma @code{@var{f}(@var{x_1}, ..., @var{x_n})} o
@code{@var{f}[@var{x_1}, ..., @var{x_n}]}, se evalúan los argumentos de la función,
pero no @var{f}, incluso cuando se trate de una función o variable ya existente 
con ese nombre.

Cuando el primer argumento es una expresión con operador @code{funmake}, 
@code{arraymake} o @code{ev}, se evalúa este primer argumento, lo que
permite calcular la función.

Todas las definiciones de funciones aparecen en el mismo espacio
de nombres; definiendo una función @code{f} dentro de otra
función @code{g} no limita automáticamente el alcance de @code{f} a @code{g}.
Sin embargo, @code{local(f)} hace que la definición de la función @code{f}
sea efectiva sólo dentro del bloque o expresión compuesta en el que
aparece @code{local}.

Si un argumento formal @var{x_k} es un símbolo afectado
por el operador comilla simple (expresión nominal), la función definida por
@code{define} no evalúa el correspondiente valor de argumento.
En cualquier otro caso, los argumentos que se pasan son evaluados.

Véanse también @code{:=} y @code{::=}.

Ejemplos:

@code{define} evalúa siempre su segundo argumento, a menos que se
indique lo contrario con el operador de comilla simple.

@c ===beg===
@c expr : cos(y) - sin(x);
@c define (F1 (x, y), expr);
@c F1 (a, b);
@c F2 (x, y) := expr;
@c F2 (a, b);
@c ===end===
@example
(%i1) expr : cos(y) - sin(x);
(%o1)                    cos(y) - sin(x)
(%i2) define (F1 (x, y), expr);
(%o2)              F1(x, y) := cos(y) - sin(x)
(%i3) F1 (a, b);
(%o3)                    cos(b) - sin(a)
(%i4) F2 (x, y) := expr;
(%o4)                   F2(x, y) := expr
(%i5) F2 (a, b);
(%o5)                    cos(y) - sin(x)
@end example

La función así
definida puede ser una función ordinaria de Maxima o una función array.

@c ===beg===
@c define (G1 (x, y), x.y - y.x);
@c define (G2 [x, y], x.y - y.x);
@c ===end===
@example
(%i1) define (G1 (x, y), x.y - y.x);
(%o1)               G1(x, y) := x . y - y . x
(%i2) define (G2 [x, y], x.y - y.x);
(%o2)                G2     := x . y - y . x
                       x, y
@end example

Cuando el último o único argumento @var{x_n} es una lista de un solo 
elemento, la función definida por @code{define} acepta un número variable
de argumentos.

@c ===beg===
@c define (H ([L]), '(apply ("+", L)));
@c H (a, b, c);
@c ===end===
@example
(%i1) define (H ([L]), '(apply ("+", L)));
(%o1)                H([L]) := apply("+", L)
(%i2) H (a, b, c);
(%o2)                       c + b + a
@end example

Cuando el primer argumento es una expresión con operador @code{funmake}, 
@code{arraymake} o @code{ev}, se evalúa este primer argumento.

@c ===beg===
@c [F : I, u : x];
@c funmake (F, [u]);
@c define (funmake (F, [u]), cos(u) + 1);
@c define (arraymake (F, [u]), cos(u) + 1);
@c define (foo (x, y), bar (y, x));
@c define (ev (foo (x, y)), sin(x) - cos(y));
@c ===end===
@example
(%i1) [F : I, u : x];
(%o1)                        [I, x]
(%i2) funmake (F, [u]);
(%o2)                         I(x)
(%i3) define (funmake (F, [u]), cos(u) + 1);
(%o3)                  I(x) := cos(x) + 1
(%i4) define (arraymake (F, [u]), cos(u) + 1);
(%o4)                   I  := cos(x) + 1
                         x
(%i5) define (foo (x, y), bar (y, x));
(%o5)                foo(x, y) := bar(y, x)
(%i6) define (ev (foo (x, y)), sin(x) - cos(y));
(%o6)             bar(y, x) := sin(x) - cos(y)
@end example

@end deffn



@deffn {Función} define_variable (@var{name}, @var{default_value}, @var{mode})

Introduce una variable global en el entorno de Maxima. La función 
@code{define_variable} puede ser útil en los paquetes escritos por
los usuarios que vayan a ser compilados o traducidos con frecuencia.

La función @code{define_variable} ejecuta los siguientes pasos:

@enumerate
@item
@code{mode_declare (@var{name}, @var{mode})} declara el modo de @var{name} al traductor.
Véase @code{mode_declare} para ver la lista de modos aceptables.

@item
Si aún no tiene asignación, se le da a la variable @var{default_value} el valor @var{name}.

@item
@code{declare (@var{name}, special)} la declara como especial.

@item
Asocia @var{name} a una función de comprobación para asegurar que
a @var{name} sólo se le asignan valores del modo declarado.
@end enumerate


@c FOLLOWING STATEMENT APPEARS TO BE OUT OF DATE.
@c EXAMINING DEFMSPEC $DEFINE_VARIABLE AND DEF%TR $DEFINE_VARIABLE IN src/trmode.lisp,
@c IT APPEARS THAT THE 4TH ARGUMENT IS NEVER REFERRED TO.
@c EXECUTING translate_file ON A MAXIMA BATCH FILE WHICH CONTAINS
@c define_variable (foo, 2222, integer, "THIS IS FOO");
@c DOES NOT PUT "THIS IS FOO" INTO THE LISP FILE NOR THE UNLISP FILE.
@c The optional 4th argument is a documentation string.  When
@c @code{translate_file} is used on a package which includes documentation
@c strings, a second file is output in addition to the Lisp file which
@c will contain the documentation strings, formatted suitably for use in
@c manuals, usage files, or (for instance) @code{describe}.

La propiedad @code{value_check} se puede asociar a cualquier variable que haya
sido definida mediante @code{define_variable} en cualquiera de los modos diferentes
a @code{any}. La propiedad @code{value_check} puede ser una expresión lambda o
una función de una variable, que será invocada al intentar asignar un valor a la
variable; el argumento pasado a la función @code{value_check} es el valor que
se le quiere asignar a la variable.

La función @code{define_variable} evalúa @code{default_value} pero no
@code{name} ni @code{mode}; el valor que devuelve es el valor actual de 
@code{name}, el cual es @code{default_value} si a @code{name} no se le ha
aplicado ninguna asignación, o el valor de dicha asignación en caso
contrario.

Ejemplos:

@code{foo} es una variable booleana con valor inicial @code{true}.
@c ===beg===
@c define_variable (foo, true, boolean);
@c foo;
@c foo: false;
@c foo: %pi;
@c foo;
@c ===end===
@example
(%i1) define_variable (foo, true, boolean);
(%o1)                         true
(%i2) foo;
(%o2)                         true
(%i3) foo: false;
(%o3)                         false
(%i4) foo: %pi;
Error: foo was declared mode boolean, has value: %pi
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i5) foo;
(%o5)                         false
@end example

@code{bar} es una variable entera, cuyo valor habrá de ser primo.
@c ===beg===
@c define_variable (bar, 2, integer);
@c qput (bar, prime_test, value_check);
@c prime_test (y) :=
@c    if not primep(y) then error (y, "is not prime.");
@c bar: 1439;
@c bar: 1440;
@c bar;
@c ===end===
@example
(%i1) define_variable (bar, 2, integer);
(%o1)                           2
(%i2) qput (bar, prime_test, value_check);
(%o2)                      prime_test
(%i3) prime_test (y) := if not primep(y) then
                           error (y, "is not prime.");
(%o3) prime_test(y) := 
         if not primep(y) then error(y, "is not prime.")
(%i4) bar: 1439;
(%o4)                         1439
(%i5) bar: 1440;
1440 is not prime.
#0: prime_test(y=1440)
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i6) bar;
(%o6)                         1439
@end example

@code{baz_quux} es una variable a la que no se le podrá asignar valor alguno.
El modo @code{any_check} es como @code{any}, 
pero @code{any_check} activa el mecanismo @code{value_check}, cosa que @code{any}
no hace.
@c ===beg===
@c define_variable (baz_quux, 'baz_quux, any_check);
@c F: lambda ([y], if y # 'baz_quux 
@c                   then error ("Cannot assign to `baz_quux'."));
@c qput (baz_quux, ''F, value_check);
@c baz_quux: 'baz_quux;
@c baz_quux: sqrt(2);
@c baz_quux;
@c ===end===
@example
(%i1) define_variable (baz_quux, 'baz_quux, any_check);
(%o1)                       baz_quux
(%i2) F: lambda ([y], if y # 'baz_quux then
                 error ("Cannot assign to `baz_quux'."));
(%o2) lambda([y], if y # 'baz_quux
                   then error(Cannot assign to `baz_quux'.))
(%i3) qput (baz_quux, ''F, value_check);
(%o3) lambda([y], if y # 'baz_quux
                   then error(Cannot assign to `baz_quux'.))
(%i4) baz_quux: 'baz_quux;
(%o4)                       baz_quux
(%i5) baz_quux: sqrt(2);
Cannot assign to `baz_quux'.
#0: lambda([y],if y # 'baz_quux then
             error("Cannot assign to `baz_quux'."))(y=sqrt(2))
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i6) baz_quux;
(%o6)                       baz_quux
@end example

@end deffn


@deffn {Función} dispfun (@var{f_1}, ..., @var{f_n})
@deffnx {Función} dispfun (all)

Muestra la deficnión de las funciones de usuario @var{f_1}, ..., @var{f_n}. Cada argumento puede ser el nombre de una macro (definida mediante @code{::=}), una función ordinaria (definida mediante @code{:=} o @code{define}), una función arreglo  (definida mediante @code{:=} o @code{define}, pero encerrando los argumentos dentro de corchetes @code{[ ]}), una función de subíndice (definida mediante @code{:=} o @code{define}, pero encerrando algunos argumentos entre corchetes y otros entre paréntesis  @code{( )}), una función de subíndice seleccionada por un subíndice variable, o una función de subíndice definida con un subíndice constante.

La llamada @code{dispfun (all)} muestra todas las funciones de usuario tal como las dan las listas @code{functions}, @code{arrays} y @code{macros}, omitiendo las funciones con subíndices definidas con subíndices constantes.

La función @code{dispfun} crea una etiqueta (@code{%t1}, @code{%t2}, etc.) para cada función mostrada, y asigna la definición de la función a la etiqueta. En contraste, @code{fundef} devuelve las definiciones de las funciones.

La función @code{dispfun} no evalúa sus argumentos; el operador de comilla-comilla @code{'@w{}'} permite la evaluación.

La función @code{dispfun} devuelve la lista de etiquetas de expresiones intermedias correspondientes a las funciones mostradas.

Ejemplos:

@c ===beg===
@c m(x, y) ::= x^(-y);
@c f(x, y) :=  x^(-y);
@c g[x, y] :=  x^(-y);
@c h[x](y) :=  x^(-y);
@c i[8](y) :=  8^(-y);
@c dispfun (m, f, g, h, h[5], h[10], i[8]);
@c ''%;
@c ===end===
@example
(%i1) m(x, y) ::= x^(-y);
                                     - y
(%o1)                   m(x, y) ::= x
(%i2) f(x, y) :=  x^(-y);
                                     - y
(%o2)                    f(x, y) := x
(%i3) g[x, y] :=  x^(-y);
                                    - y
(%o3)                     g     := x
                           x, y
(%i4) h[x](y) :=  x^(-y);
                                    - y
(%o4)                     h (y) := x
                           x
(%i5) i[8](y) :=  8^(-y);
                                    - y
(%o5)                     i (y) := 8
                           8
(%i6) dispfun (m, f, g, h, h[5], h[10], i[8]);
                                     - y
(%t6)                   m(x, y) ::= x

                                     - y
(%t7)                    f(x, y) := x

                                    - y
(%t8)                     g     := x
                           x, y

                                    - y
(%t9)                     h (y) := x
                           x

                                    1
(%t10)                     h (y) := --
                            5        y
                                    5

                                     1
(%t11)                    h  (y) := ---
                           10         y
                                    10

                                    - y
(%t12)                    i (y) := 8
                           8

(%o12)       [%t6, %t7, %t8, %t9, %t10, %t11, %t12]
(%i12) ''%;
                     - y              - y            - y
(%o12) [m(x, y) ::= x   , f(x, y) := x   , g     := x   , 
                                            x, y
                  - y           1              1             - y
        h (y) := x   , h (y) := --, h  (y) := ---, i (y) := 8   ]
         x              5        y   10         y   8
                                5             10
@end example

@end deffn



@deffn {Función} fullmap (@var{f}, @var{expr_1}, ...)
Similar a @code{map}, pero conservará el mapeado
descendente de todas las subexpresiones hasta que los operadores
principales ya no sean los mismos.

La función @code{fullmap} es utilizada por el simplificador de Maxima
en algunas transformaciones matriciales, por lo que Maxima generará en algunas ocasiones mensajes de error relacionados con @code{fullmap} aunque el usuario no haya invocado explícitamente esta función.

@c ===beg===
@c a + b * c;
@c fullmap (g, %);
@c map (g, %th(2));
@c ===end===
@example
(%i1) a + b * c;
(%o1)                        b c + a
(%i2) fullmap (g, %);
(%o2)                   g(b) g(c) + g(a)
(%i3) map (g, %th(2));
(%o3)                     g(b c) + g(a)
@end example

@end deffn

@deffn {Función} fullmapl (@var{f}, @var{list_1}, ...)
Similar a @code{fullmap}, pero @code{fullmapl} sólo hace mapeo
sobre listas y matrices.

@c ===beg===
@c fullmapl ("+", [3, [4, 5]], [[a, 1], [0, -1.5]]);
@c ===end===
@example
(%i1) fullmapl ("+", [3, [4, 5]], [[a, 1], [0, -1.5]]);
(%o1)                [[a + 3, 4], [4, 3.5]]
@end example

@end deffn


@defvr {Variable del sistema} functions
Valor por defecto: @code{[]}

La variable @code{functions} es una lista que contiene los nombres de las funciones ordinarias de Maxima. Una función ordinaria es aquella que ha sido construida mediante cualquiera de los métodos @code{define} o @code{:=} y que es invocada utilizando paréntesis. Una función puede definirse durante una sesión de Maxima o en un fichero que posteriormente será cargado en memoria por @code{load} o @code{batch}.

Las funciones array, que son invocadas con corchetes (@code{F[x]}),
y las funciones subindicadas, que son las invocadas con corchetes y
paréntesis (@code{F[x](y)}) se registran en la variable global @code{arrays},
no en @code{functions}.

Las funciones Lisp no se registran en ninguna lista.

Ejemplos:

@c ===beg===
@c F_1 (x) := x - 100;
@c F_2 (x, y) := x / y;
@c define (F_3 (x), sqrt (x));
@c G_1 [x] := x - 100;
@c G_2 [x, y] := x / y;
@c define (G_3 [x], sqrt (x));
@c H_1 [x] (y) := x^y;
@c functions;
@c arrays;
@c ===end===
@example
(%i1) F_1 (x) := x - 100;
(%o1)                   F_1(x) := x - 100
(%i2) F_2 (x, y) := x / y;
                                      x
(%o2)                    F_2(x, y) := -
                                      y
(%i3) define (F_3 (x), sqrt (x));
(%o3)                   F_3(x) := sqrt(x)
(%i4) G_1 [x] := x - 100;
(%o4)                    G_1  := x - 100
                            x
(%i5) G_2 [x, y] := x / y;
                                     x
(%o5)                     G_2     := -
                             x, y    y
(%i6) define (G_3 [x], sqrt (x));
(%o6)                    G_3  := sqrt(x)
                            x
(%i7) H_1 [x] (y) := x^y;
                                      y
(%o7)                     H_1 (y) := x
                             x
(%i8) functions;
(%o8)              [F_1(x), F_2(x, y), F_3(x)]
(%i9) arrays;
(%o9)                 [G_1, G_2, G_3, H_1]
@end example

@end defvr

@deffn {Función} fundef (@var{f})

Devuelve la definición de la función @var{f}.

Cada argumento puede ser el nombre de una macro (definida mediante @code{::=}), una función ordinaria (definida mediante @code{:=} o @code{define}), una función arreglo  (definida mediante @code{:=} o @code{define}, pero encerrando los argumentos dentro de corchetes @code{[ ]}), una función de subíndice (definida mediante @code{:=} o @code{define}, pero encerrando algunos argumentos entre corchetes y otros entre paréntesis  @code{( )}), una función de subíndice seleccionada por un subíndice variable, o una función de subíndice definida con un subíndice constante.

La función @code{fundef} no evalúa sus argumentos; el operador comilla-comilla @code{'@w{}'} permite la evaluación.

La llamada de función @code{fundef (@var{f})} devuelve la definición de @var{f}. Por el contrario, @code{dispfun (@var{f})} crea una etiqueta intermedia y le asigna la definición a la etiqueta.

@end deffn

@deffn {Función} funmake (@var{F}, [@var{arg_1}, ..., @var{arg_n}])

Devuelve una expresión @code{@var{F}(@var{arg_1}, ..., @var{arg_n})}.
El valor así retornado es simplificado pero no evaluado,
de forma que la función @var{F} no es invocada, incluso cuando exista.

La función @code{funmake} no hace distinciones entre funciones array
y funciones ordinarias; cuando @var{F} es el nombre de una función array,
@code{funmake} devuelve @code{@var{F}(...)},
esto es, una llamada a función con paréntesis en lugar de corchetes.
La función @code{arraymake} devuelve una llamada a función con
corchetes para estos casos.

La función @code{funmake} evalúa sus argumentos.

Ejemplos:

La función @code{funmake} aplicada a una función ordinaria de Maxima.

@c ===beg===
@c F (x, y) := y^2 - x^2;
@c funmake (F, [a + 1, b + 1]);
@c ''%;
@c ===end===
@example
(%i1) F (x, y) := y^2 - x^2;
                                   2    2
(%o1)                  F(x, y) := y  - x
(%i2) funmake (F, [a + 1, b + 1]);
(%o2)                    F(a + 1, b + 1)
(%i3) ''%;
                              2          2
(%o3)                  (b + 1)  - (a + 1)
@end example

La función @code{funmake} aplicada a una macro.

@c ===beg===
@c G (x) ::= (x - 1)/2;
@c funmake (G, [u]);
@c ''%;
@c ===end===
@example
(%i1) G (x) ::= (x - 1)/2;
                                  x - 1
(%o1)                    G(x) ::= -----
                                    2
(%i2) funmake (G, [u]);
(%o2)                         G(u)
(%i3) ''%;
                              u - 1
(%o3)                         -----
                                2
@end example

La función @code{funmake} aplicada a una función subindicada.

@c ===beg===
@c H [a] (x) := (x - 1)^a;
@c funmake (H [n], [%e]);
@c ''%;
@c funmake ('(H [n]), [%e]);
@c ''%;
@c ===end===
@example
(%i1) H [a] (x) := (x - 1)^a;
                                        a
(%o1)                   H (x) := (x - 1)
                         a
(%i2) funmake (H [n], [%e]);
                                       n
(%o2)               lambda([x], (x - 1) )(%e)
(%i3) ''%;
                                    n
(%o3)                       (%e - 1)
(%i4) funmake ('(H [n]), [%e]);
(%o4)                        H (%e)
                              n
(%i5) ''%;
                                    n
(%o5)                       (%e - 1)
@end example

La función @code{funmake} aplicada a un símbolo
que no está asociado a función alguna.

@c ===beg===
@c funmake (A, [u]);
@c ''%;
@c ===end===
@example
(%i1) funmake (A, [u]);
(%o1)                         A(u)
(%i2) ''%;
(%o2)                         A(u)
@end example

La función @code{funmake} evalúa sus argumentos,
pero no el valor retornado.

@c ===beg===
@c det(a,b,c) := b^2 -4*a*c;
@c (x : 8, y : 10, z : 12);
@c f : det;
@c funmake (f, [x, y, z]);
@c ''%;
@c ===end===
@example
(%i1) det(a,b,c) := b^2 -4*a*c;
                                    2
(%o1)              det(a, b, c) := b  - 4 a c
(%i2) (x : 8, y : 10, z : 12);
(%o2)                          12
(%i3) f : det;
(%o3)                          det
(%i4) funmake (f, [x, y, z]);
(%o4)                    det(8, 10, 12)
(%i5) ''%;
(%o5)                         - 284
@end example

Maxima simplifica el valor retornado de @code{funmake}.

@c ===beg===
@c funmake (sin, [%pi / 2]);
@c ===end===
@example
(%i1) funmake (sin, [%pi / 2]);
(%o1)                           1
@end example

@end deffn

@deffn {Función} lambda ([@var{x_1}, ..., @var{x_m}], @var{expr_1}, ..., @var{expr_n})
@deffnx {Function} lambda ([[@var{L}]], @var{expr_1}, ..., @var{expr_n})
@deffnx {Function} lambda ([@var{x_1}, ..., @var{x_m}, [@var{L}]], @var{expr_1}, ..., @var{expr_n})
Define y devuelve una expresión lambda (es decir, una función anónima).
La función puede tener argumentos @var{x_1}, ..., @var{x_m} y/o argumentos
opcionales @var{L}, que aparecerán dentro del cuerpo de la función como una lista.
El valor que devuelve la función es @var{expr_n}.
Una expresión lambda puede asignarse a una variable y ser evaluada como si fuese una función ordinaria. Además, puede aparecer en algunos contextos en los que sea necesario un nombre de función.

Cuando se evalúa la función, se crean las variables @var{x_1}, ..., @var{x_m} sin asignación de valores. Una función @code{lambda} puede aparecer dentro de un @code{block} o de otra @code{lambda}. Las variables locales se inicializan cada vez que se entra dentro de un nuevo bloque o de otra función @code{lambda}. Las variables locales se consideran globales dentro de un bloque o función @code{lambda} anidado dentro del primero. Si una variable es no local dentro de un bloque o función @code{lambda}, su valor es el que le corresponde en el bloque o función @code{lambda} superior. Este criterio se conoce con el nombre de "alcance dinámico".

Una vez establecidas las variables locales @var{expr_1} a @var{expr_n} son secuencialmente evaluadas. La variable especial  @code{%%} representa el valor de la expresión inmediata anterior. Las sentencias @code{throw} y @code{catch} pueden aparecer también en la lista de expresiones.

La función @code{return} no puede aparecer en una expresión @code{lambda} a menos que se encuentre acotada dentro de un bloque (@code{block}), en cuyo caso @code{return} establece el valor de retorno del bloque, pero no de la expresión @code{lambda}, a menos que el bloque resulte ser precisamente @var{expr_n}. De igual manera, @code{go} no puede aparecer en una expresión @code{lambda} si no es dentro de un @code{block}.

Las funciones @code{lambda} no evalúan sus argumentos;  el operador comilla-comilla @code{'@w{}'} permite su evaluación.

Ejemplo:

@itemize @bullet
@item
Una función lambda puede asignarse a una variable y ser evaluada como si fuese una función ordinaria.
@end itemize
@c ===beg===
@c f: lambda ([x], x^2);
@c f(a);
@c ===end===
@example
(%i1) f: lambda ([x], x^2);
                                      2
(%o1)                    lambda([x], x )
(%i2) f(a);
                                2
(%o2)                          a
@end example
@itemize @bullet
@item
Una expresión lambda puede aparecer en algunos contextos en los que sea necesario un nombre de función.
@end itemize
@c ===beg===
@c lambda ([x], x^2) (a);
@c apply (lambda ([x], x^2), [a]);
@c map (lambda ([x], x^2), [a, b, c, d, e]);
@c ===end===
@example
(%i3) lambda ([x], x^2) (a);
                                2
(%o3)                          a
(%i4) apply (lambda ([x], x^2), [a]);
                                2
(%o4)                          a
(%i5) map (lambda ([x], x^2), [a, b, c, d, e]);
                        2   2   2   2   2
(%o5)                 [a , b , c , d , e ]
@end example
@itemize @bullet
@item
Los argumentos son variables locales. Otras variables se consideran globales. Las variables globales son evaluadas en el momento que lo es la expresión, a menos que la evaluación de las mismas sea forzada, como cuando se hace uso de @code{'@w{}'}.
@end itemize
@c ===beg===
@c a: %pi$
@c b: %e$
@c g: lambda ([a], a*b);
@c b: %gamma$
@c g(1/2);
@c g2: lambda ([a], a*''b);
@c b: %e$
@c g2(1/2);
@c ===end===
@example
(%i6) a: %pi$
(%i7) b: %e$
(%i8) g: lambda ([a], a*b);
(%o8)                   lambda([a], a b)
(%i9) b: %gamma$
(%i10) g(1/2);
                             %gamma
(%o10)                       ------
                               2
(%i11) g2: lambda ([a], a*''b);
(%o11)                lambda([a], a %gamma)
(%i12) b: %e$
(%i13) g2(1/2);
                             %gamma
(%o13)                       ------
                               2
@end example
@itemize @bullet
@item
Las expresiones lambda pueden anidarse. Las variables locales de expresiones lambda exteriores se consideran globales en expresiones internas, a menos que se enmascaren con variables locales de igual nombre.
@end itemize
@c ===beg===
@c h: lambda ([a, b], h2: lambda ([a], a*b), h2(1/2));
@c h(%pi, %gamma);
@c ===end===
@example
(%i14) h: lambda ([a, b], h2: lambda ([a], a*b), h2(1/2));
                                                   1
(%o14)    lambda([a, b], h2 : lambda([a], a b), h2(-))
                                                   2
(%i15) h(%pi, %gamma);
                             %gamma
(%o15)                       ------
                               2
@end example
@itemize @bullet
@item
Puesto que @code{lambda} no evalúa sus argumentos, la expresión lambda @code{i} de más abajo no define una función del tipo "multiplicar por @code{a}". Tal tipo de función se puede definir a través de @code{buildq}, como en la expresión lambda @code{i2} de más abajo.
@end itemize
@c ===beg===
@c i: lambda ([a], lambda ([x], a*x));
@c i(1/2);
@c i2: lambda([a], buildq([a: a], lambda([x], a*x)));
@c i2(1/2);
@c i2(1/2)(%pi);
@c ===end===
@example
(%i16) i: lambda ([a], lambda ([x], a*x));
(%o16)            lambda([a], lambda([x], a x))
(%i17) i(1/2);
(%o17)                  lambda([x], a x)
(%i18) i2: lambda([a], buildq([a: a], lambda([x], a*x)));
(%o18)    lambda([a], buildq([a : a], lambda([x], a x)))
(%i19) i2(1/2);
                                     x
(%o19)                   lambda([x], -)
                                     2
(%i20) i2(1/2)(%pi);
                               %pi
(%o20)                         ---
                                2
@end example
@itemize @bullet
@item
Una expresión lambda puede tener un número variable de argumentos,
los cuales se indican mediante @code{[@var{L}]}, bien sea solo o como un
último argumento. Estos argumentos aparecerán dentro del cuerpo de
la función en forma de lista.
@end itemize
@c ===beg===
@c f : lambda ([aa, bb, [cc]], aa * cc + bb);
@c f (foo, %i, 17, 29, 256);
@c g : lambda ([[aa]], apply ("+", aa));
@c g (17, 29, x, y, z, %e);
@c ===end===
@example
(%i1) f : lambda ([aa, bb, [cc]], aa * cc + bb);
(%o1)          lambda([aa, bb, [cc]], aa cc + bb)
(%i2) f (foo, %i, 17, 29, 256);
(%o2)       [17 foo + %i, 29 foo + %i, 256 foo + %i]
(%i3) g : lambda ([[aa]], apply ("+", aa));
(%o3)             lambda([[aa]], apply(+, aa))
(%i4) g (17, 29, x, y, z, %e);
(%o4)                  z + y + x + %e + 46
@end example
@end deffn

@deffn {Función} local (@var{v_1}, ..., @var{v_n})

La declaración @code{local(@var{v_1}, ..., @var{v_m})} dentro de un bloque
almacena las propiedades asociadas a los símbolos @var{v_1}, ..., @var{v_m},
borra cualesquiera otras propiedades antes de evaluar las expresiones y
restaura las propiedades guardadas antes de abandonar el bloque.

Algunas declaraciones, como @code{:=}, @code{array}, @code{dependencies}, @code{atvalue},
@code{matchdeclare}, @code{atomgrad}, @code{constant}, @code{nonscalar}, @code{assume}
y otras se implementan como propiedades de símbolos.
El efecto producido por @code{local} consiste en hacer que tales declaraciones tengan
efecto sólo dentro del bloque, en otro caso las declaraciones dentro del bloque 
tendrían un efecto global que afectarían al exterior de @code{block}.

La función @code{local} sólo puede usarse dentro de un @code{block}, en el
cuerpo de definición de funciones o de expresiones @code{lambda} o en la
función @code{ev}, siéndole permitido aparecer una sóla vez en cada una de ellas.

La función @code{local} no evalúa sus argumentos y devuelve @code{done}.

Ejemplo:

Definición local de una función.

@c ===beg===
@c foo (x) := 1 - x;
@c foo (100);
@c block (local (foo), foo (x) := 2 * x, foo (100));
@c foo (100);
@c ===end===
@example
(%i1) foo (x) := 1 - x;
(%o1)                    foo(x) := 1 - x
(%i2) foo (100);
(%o2)                         - 99
(%i3) block (local (foo), foo (x) := 2 * x, foo (100));
(%o3)                          200
(%i4) foo (100);
(%o4)                         - 99
@end example
@end deffn



@defvr {Variable opcional} macroexpansion
Valor por defecto: @code{false}

La variable @code{macroexpansion} controla si la expansión (esto es, el valor de retorno) de una función macro se sustituye por la llamada a la función macro. Una sustitución puede acelerar futuras evaluaciones de la expresión, bajo el coste que implica tener que almacenar la expansión.

@table @code
@item false
La expansión de una función macro no se sustituye por la llamada a la función macro.
@item expand
La primera vez que se evalúa una llamada a función macro se almacena la expansión. De esta manera la expansión no se recalcula en llamadas posteriores; cualesquiera efectos laterales (como @code{print} o asignaciones a variables globales)
tan solo tienen lugar la primera vez que la función macro es evaluada. La expansión en una expresión no afecta a otras expresiones que llamen a la misma función macro.
@item displace
La primera vez que se evalúa una llamada a una función macro, la expansión se sustituye por la llamada, modificando así la expresión desde la que se hizo la llamada a la función macro. La expansión no se recalcula en llamadas posteriores; cualesquiera efectos laterales tan solo tienen lugar la primera vez que la función macro es evaluada. La expansión en una expresión no afecta a otras expresiones que llamen a la misma función macro.
@end table

Ejemplos:

Si @code{macroexpansion} vale @code{false},
una función macro es llamada cada vez que la expresión de llamada es evaluada.

@c ===beg===
@c f (x) := h (x) / g (x);
@c g (x) ::= block (print ("x + 99 is equal to", x),
@c                  return (x + 99));
@c h (x) ::= block (print ("x - 99 is equal to", x),
@c                  return (x - 99));
@c macroexpansion: false;
@c f (a * b);
@c dispfun (f);
@c f (a * b);
@c ===end===
@example
(%i1) f (x) := h (x) / g (x);
                                  h(x)
(%o1)                     f(x) := ----
                                  g(x)
(%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                       return (x + 99));
(%o2) g(x) ::= block(print("x + 99 is equal to", x), 
                     return(x + 99))
(%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                       return (x - 99));
(%o3) h(x) ::= block(print("x - 99 is equal to", x), 
                     return(x - 99))
(%i4) macroexpansion: false;
(%o4)                         false
(%i5) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x 
                            a b - 99
(%o5)                       --------
                            a b + 99
(%i6) dispfun (f);
                                  h(x)
(%t6)                     f(x) := ----
                                  g(x)

(%o6)                         done
(%i7) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x 
                            a b - 99
(%o7)                       --------
                            a b + 99
@end example

Si @code{macroexpansion} vale @code{expand}, una función macro tan solo es llamada una vez.

@c ===beg===
@c f (x) := h (x) / g (x);
@c g (x) ::= block (print ("x + 99 is equal to", x),
@c                  return (x + 99));
@c h (x) ::= block (print ("x - 99 is equal to", x),
@c                  return (x - 99));
@c macroexpansion: expand;
@c f (a * b);
@c dispfun (f);
@c f (a * b);
@c ===end===
@example
(%i1) f (x) := h (x) / g (x);
                                  h(x)
(%o1)                     f(x) := ----
                                  g(x)
(%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                       return (x + 99));
(%o2) g(x) ::= block(print("x + 99 is equal to", x), 
                     return(x + 99))
(%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                       return (x - 99));
(%o3) h(x) ::= block(print("x - 99 is equal to", x), 
                     return(x - 99))
(%i4) macroexpansion: expand;
(%o4)                        expand
(%i5) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x 
                            a b - 99
(%o5)                       --------
                            a b + 99
(%i6) dispfun (f);
                                  h(x)
(%t6)                     f(x) := ----
                                  g(x)

(%o6)                         done
(%i7) f (a * b);
                            a b - 99
(%o7)                       --------
                            a b + 99
@end example

Si @code{macroexpansion} vale @code{expand}, una función macro es llamada una vez y la expresión de llamada se modifica.

@c ===beg===
@c f (x) := h (x) / g (x);
@c g (x) ::= block (print ("x + 99 is equal to", x), return (x + 99));
@c h (x) ::= block (print ("x - 99 is equal to", x), return (x - 99));
@c macroexpansion: displace;
@c f (a * b);
@c dispfun (f);
@c f (a * b);
@c ===end===
@example
(%i1) f (x) := h (x) / g (x);
                                  h(x)
(%o1)                     f(x) := ----
                                  g(x)
(%i2) g (x) ::= block (print ("x + 99 is equal to", x), return (x + 99));
(%o2) g(x) ::= block(print("x + 99 is equal to", x), 
                                                  return(x + 99))
(%i3) h (x) ::= block (print ("x - 99 is equal to", x), return (x - 99));
(%o3) h(x) ::= block(print("x - 99 is equal to", x), 
                                                  return(x - 99))
(%i4) macroexpansion: displace;
(%o4)                       displace
(%i5) f (a * b);
x - 99 is equal to x 
x + 99 is equal to x 
                            a b - 99
(%o5)                       --------
                            a b + 99
(%i6) dispfun (f);
                                 x - 99
(%t6)                    f(x) := ------
                                 x + 99

(%o6)                         done
(%i7) f (a * b);
                            a b - 99
(%o7)                       --------
                            a b + 99
@end example

@end defvr

@defvr {Variable opcional} mode_checkp
Valor por defecto: @code{true}

Cuando @code{mode_checkp} vale @code{true}, @code{mode_declare} chequea los modos de las variables con valores asignados.
@c NEED SOME EXAMPLES HERE.

@end defvr

@defvr {Variable opcional} mode_check_errorp
Valor por defecto: @code{false}

@c WHAT DOES THIS MEAN ??
Cuando @code{mode_check_errorp} vale @code{true}, @code{mode_declare} llama a error.
@c NEED SOME EXAMPLES HERE.

@end defvr

@defvr {Variable opcional} mode_check_warnp
Valor por defecto: @code{true}

@c WHAT DOES THIS MEAN ??
Cuando @code{mode_check_warnp} vale @code{true}, se detallan los errores de modo.
@c NEED SOME EXAMPLES HERE.

@end defvr

@deffn {Función} mode_declare (@var{y_1}, @var{modo_1}, ..., @var{y_n}, @var{modo_n})

La función @code{mode_declare} se utiliza para declarar los modos de variables y funciones para la ulterior traducción a Lisp o compilación de funciones. Se coloca habitualmente al comienzo de la definición de una función, de un script en Maxima o se ejecuta en tiempo real.

Los argumentos de @code{mode_declare} son pares formados por una variable y un modo, el cual debe ser @code{boolean}, @code{fixnum}, @code{number}, @code{rational} o @code{float}. Cada variable puede ser sustituida por una lista de variables, en cuyo caso todas ellas tendrán el mismo modo.

@c aquí me salto un párrafo que no está claro en el original (Mario).

Código numérico que utilice arreglos puede ejecutarse más rápido declarando el tamaño que va a ocupar el arreglo, como en:

@example
mode_declare (array (a [10, 10]), float)
@end example

para un arreglo de números en coma flotante de dimensiones 10 x 10.

Se puede declarar el modo del resultado de una función poniendo @code{function (f_1, f_2, ...)} como argumento;
aquí @code{f_1}, @code{f_2}, ... son los nombres de las funciones. Por ejemplo, la expresión

@example
mode_declare ([function (f_1, f_2, ...)], fixnum)
@end example

declara que el valor a devolver por  @code{f_1}, @code{f_2}, ... son enteros de modo "single-word".

El nombre @code{modedeclare} es sinónimo de @code{mode_declare}.

@end deffn

@deffn {Función} mode_identity (@var{arg_1}, @var{arg_2})
Es una forma especial usada con @code{mode_declare} y @code{macros} para declarar, por ejemplo, una lista de listas de números. 

@c Elimino aquí un párrafo. Comentario en la versión inglesa: WHAT IS THIS ABOUT ?? (Mario)

@end deffn



@deffn {Función} remfunction (@var{f_1}, ..., @var{f_n})
@deffnx {Función} remfunction (all)
Desliga las definiciones de función de sus símbolos @var{f_1}, ..., @var{f_n}.
Los argumentos pueden ser nombres de funciones ordinarias 
(creadas con @code{:=} o @code{define}) o de funciones macro (creadas con @code{::=}).

La instrucción @code{remfunction (all)} desliga todas las definiciones de funciones.

La función @code{remfunction} no evalúa sus argumentos.

La función @code{remfunction} devuelve una lista con los
símbolos para los que la definición de función
fue desligada. Devuelve @code{false} en el lugar de cualquier 
símbolo para el que no hay función definida.

La función @code{remfunction} no se puede aplicar a arrays de funciones ni a
funciones subindicadas. Sí es aplicable en tales casos la 
función @code{remarray}.
@end deffn


@defvr {Variable opcional} savedef
Valor por defecto: @code{true}

Si @code{savedef} vale @code{true}, se mantiene la versión Maxima de una función definida por el usuario cuando ésta se traduce, lo que permite mostrar su código con @code{dispfun} y que la función pueda ser editada.

Si @code{savedef} vale @code{false}, los nombres de las funciones traducidas se eliminan de la lista @code{functions}.

@end defvr



@defvr {Variable opcional} transcompile
Valor por defecto: @code{true}

Si @code{transcompile} vale @code{true}, @code{translate} y @code{translate_file} generan declaraciones para hacer el código traducido más apto para la compilación.

La función @code{compfile} hace la asignación @code{transcompile: true}.

@end defvr

@deffn {Función} translate (@var{f_1}, ..., @var{f_n})
@deffnx {Función} translate (functions)
@deffnx {Función} translate (all)

Traduce las funciones definidas por el usuario @var{f_1}, ..., @var{f_n} del lenguaje de Maxima a Lisp y evalúa las traducciones Lisp. Normalmente las funciones traducidas se ejecutan más rapidamente que las originales.

Las llamadas @code{translate (all)} o @code{translate (functions)} traducen todas las funciones de usuario.

Las funciones a ser traducidas deberían incluir una llamada a @code{mode_declare} al comienzo siempre que sea posible, a fin de producir código más eficiente. Por ejemplo:

@example
f (x_1, x_2, ...) := block ([v_1, v_2, ...],
    mode_declare (v_1, modo_1, v_2, modo_2, ...), ...)
@end example

@noindent

donde @var{x_1}, @var{x_2}, ... son los parámetros que se pasan a la función y @var{v_1}, @var{v_2}, ... son las variables locales.

Los nombres de las funciones traducidas son eliminados de la lista @code{functions} si @code{savedef} vale @code{false} (ver más abajo) y son añadidos a las listas @code{props}.

Las funciones no deberían ser traducidas hasta no estar completamente depuradas.

Se supone que las expresiones están simplificadas; en caso de no estarlo, se generará código correcto pero ineficiente. Así, el usuario no debería asignar a @code{simp} el valor @code{false}, el cual inhibe la simplificación de la expresión a ser traducida.

Cuando la variable @code{translate} vale @code{true}, se traducen automáticamente las funciones de usuario a Lisp.

Nótese que las funciones traducidas puede que no se ejecuten exactamente igual a como lo hacían antes de la traducción, debido a posibles incompatibilidades entre las versiones de Maxima y Lisp. En general, la función @code{rat} con más de un argumento y la función @code{ratvars} no deberían utilizarse si algunas de las variables son declaradas como expresiones racionales canónicas (CRE) mediante @code{mode_declare}. Además, la asignación  @code{prederror: false} no traducirá.

Si @code{savedef} vale @code{true}, entonces la versión de Maxima de una función de usuario permanecerá cuando la función sea traducida por @code{translate}. Con esto se hace posible que se muestre la definición llamando a @code{dispfun} y que la función sea editada.

Si @code{transrun} vale @code{false} entonces las versiones interpretadas de todas las funciones serán ejecutadas en lugar de las versiones traducidas.

El resultado devuelto por @code{translate} es una lista con los nombres de las funciones traducidas.

@end deffn

@deffn {Función} translate_file (@var{nombre_fichero_maxima})
@deffnx {Función} translate_file (@var{nombre_fichero_maxima}, @var{nombre_fichero_lisp})

Traduce un fichero en código Maxima a un fichero en código Lisp. La función @code{translate_file} devuelve una lista con los nombres de tres ficheros: el nombre del ficheero en Maxima, el nombre del fichero en Lisp y el nombre del fichero que contiene información adicional sobre la traducción. La función @code{translate_file} evalúa sus argumentos.

La llamada @code{translate_file ("foo.mac"); load("foo.LISP")} es lo mismo que @code{batch ("foo.mac")}, excepto por la presencia de ciertas restricciones, como el uso de @code{'@w{}'} y @code{%}, por ejemplo.
@c FIGURE OUT WHAT THE RESTRICTIONS ARE AND STATE THEM

La llamada @code{translate_file (@var{nombre_fichero_maxima})} traduce un fichero en Maxima, @var{nombre_fichero_maxima}, a otro en Lisp de nombre similar. Por ejemplo, @code{foo.mac} se traduce en @code{foo.LISP}. El nombre del fichero en Maxima puede incluir el nombre de un directorio, en cuyo caso el fichero de salida Lisp se guardará en el mismo directorio desde el que se leyó la fuente Maxima.

La llamada @code{translate_file (@var{nombre_fichero_maxima}, @var{nombre_fichero_lisp})} traduce el fichero Maxima  @var{nombre_fichero_maxima} en el fichero Lisp @var{nombre_fichero_lisp}. La función @code{translate_file} ignora la extensión del fichero, en caso de que exista, de @code{nombre_fichero_lisp}; la extensión del fichero de salida Lisp  será invariablemente @code{LISP}. El nombre del fichero Lisp puede incluir la ruta del directorio, en cuyo caso se almacenará en el directorio especificado.

La función @code{translate_file} también escribe un fichero de mensajes de avisos del traductor con diversos niveles de gravedad. La extensión de este fichero es @code{UNLISP}. Este fichero puede contener información valiosa, aunque de difícil interpretación, para detectar fallos en el código traducido. El fichero @code{UNLISP} se guarda siempre en el mismo directorio desde el que se leyó la fuente de Maxima.

La función @code{translate_file} emite código Lisp que incluye algunas declaraciones y definiciones que entran en efecto tan pronto como el código Lisp es compilado. Véase @code{compile_file} para más información sobre este particular.

@c CHECK ALL THESE AND SEE WHICH ONES ARE OBSOLETE
Véanse también @code{tr_array_as_ref},
@c tr_bind_mode_hook EXISTS BUT IT APPEARS TO BE A GROTESQUE UNDOCUMENTED HACK
@c WE DON'T WANT TO MENTION IT
@c @code{tr_bind_mode_hook}, 
@code{tr_bound_function_applyp},
@c tr_exponent EXISTS AND WORKS AS ADVERTISED IN src/troper.lisp
@c NOT OTHERWISE DOCUMENTED; ITS EFFECT SEEMS TOO WEAK TO MENTION
@code{tr_exponent},
@code{tr_file_tty_messagesp}, 
@code{tr_float_can_branch_complex},
@code{tr_function_call_default}, 
@code{tr_numer},
@code{tr_optimize_max_loop}, 
@code{tr_semicompile},
@code{tr_state_vars}, 
@code{tr_warnings_get},
@code{tr_warn_bad_function_calls},
@code{tr_warn_fexpr}, 
@code{tr_warn_meval},
@code{tr_warn_mode},
@code{tr_warn_undeclared},
y @code{tr_warn_undefined_variable}.

@end deffn

@defvr {Variable opcional} transrun
Valor por defecto: @code{true}

Si @code{transrun} vale @code{false} entonces se ejecutarán las versiones interpretadas de todas las funciones, en lugar de las versiones traducidas.

@end defvr

@defvr {Variable opcional} tr_array_as_ref
Valor por defecto: @code{true}

Si @code{translate_fast_arrays} vale @code{false}, referencias de arreglos en el código Lisp creadas por  @code{translate_file} se ven afectadas por @code{tr_array_as_ref}.

El valor de la variable @code{tr_array_as_ref} no tiene ningún efecto cuando @code{translate_fast_arrays} vale @code{true}.

@end defvr

@defvr {Variable opcional} tr_bound_function_applyp
Valor por defecto: @code{true}

Si @code{tr_bound_function_applyp} vale @code{true}, Maxima envía un aviso si encuentra una variable con valor asignado que está siendo utilizada como una función. @code{tr_bound_function_applyp} no influye en el código generado bajo estas circunstancias.

Por ejemplo, una expresión como @code{g (f, x) := f (x+1)} provocará un mensaje de esta naturaleza.

@end defvr

@defvr {Variable opcional} tr_file_tty_messagesp
Valor por defecto: @code{false}

Si @code{tr_file_tty_messagesp} vale @code{true}, los mensajes generados por @code{translate_file} durante la traducción de un fichero se muestran en la consola y se insertan en el fichero UNLISP.  Si vale @code{false}, los mensajes sobre la traducción del fichero sólo se incorporan al fichero UNLISP.

@end defvr

@defvr {Variable opcional} tr_float_can_branch_complex
Valor por defecto: @code{true}

Le dice al traductor de Maxima a Lisp que las funciones @code{acos}, @code{asin}, @code{asec} y @code{acsc} pueden devolver valores complejos.

@end defvr

@defvr {Variable opcional} tr_function_call_default
Valor por defecto: @code{general}

El valor @code{false} significa llama a @code{meval}, @code{expr} significa que Lisp asignó los argumentos de la función,  @code{general}, el valor por defecto, devuelve código apropiado para @code{mexprs} y @code{mlexprs} pero no para @code{macros}. La opción @code{general} asegura que las asignaciones de las variables son correctas en el código compilado. En modo @code{general}, cuando se traduce F(X), si F es una variable con valor, entonces se entiende que se quiere calcular @code{apply (f, [x])}, y como tal se traduce, con el apropiado aviso. No es necesario desactivar esto. Con los valores por defecto la falta de mensajes de aviso implica compatibilidad completa entre el código traducido y compilado con el interpretado por Maxima.

@end defvr

@defvr {Variable opcional} tr_numer
Valor por defecto: @code{false}

Si @code{tr_numer} vale @code{true} se utilizan las propiedades numéricas en aquellos átomos que las posean, como en  @code{%pi}.

@end defvr

@defvr {Variable opcional} tr_optimize_max_loop
Valor por defecto: 100

El valor de @code{tr_optimize_max_loop} es el número máximo de veces que el traductor repetirá la macro-expansión y la optimización en el tratamiento de una expresión.

@end defvr

@defvr {Variable opcional} tr_semicompile
Valor por defecto: @code{false}

Si @code{tr_semicompile} vale @code{true}, las salidas de @code{translate_file} y @code{compfile} serán macro-expandidas pero no compiladas a código máquina por el compilador de Lisp.

@end defvr

@defvr {Variable del sistema} tr_state_vars
Valor por defecto:

@example
[transcompile, tr_semicompile, tr_warn_undeclared, tr_warn_meval,
tr_warn_fexpr, tr_warn_mode, tr_warn_undefined_variable,
tr_function_call_default, tr_array_as_ref,tr_numer]
@end example

Es la lista de variables que afectan la forma en que se obtiene la salida del código traducido. Esta información es útil para desarrolladores que pretendan corregir posibles fallos del traductor. Comparando el código traducido con el que se debería obtener bajo unas ciertas condiciones, es posible hacer el seguimiento de los fallos.

@end defvr

@deffn {Función} tr_warnings_get ()

Devuelve una lista con los avisos dados por el traductor.

@end deffn

@defvr {Variable opcional} tr_warn_bad_function_calls
Valor por defecto: @code{true}

Devuelve un aviso cuando se hacen llamadas a funciones que quizás no sean correctas debido a declaraciones inapropiadas realizadas durante la traducción.

@end defvr

@defvr {Variable opcional} tr_warn_fexpr
Valor por defecto: @code{compfile}

Devuelve un aviso si se encuentra con alguna FEXPR. Las FEXPR no deberían aparecer en el código traducido.

@end defvr

@defvr {Variable opcional} tr_warn_meval
Valor por defecto: @code{compfile}

Devuelve un aviso si la función @code{meval} es llamada.  Si @code{meval} es invocada, es señal de la presencia de problemas en la traducción.

@end defvr

@defvr {Variable opcional} tr_warn_mode
Valor por defecto: @code{all}

Devuelve un aviso cuando a las variables se les asignan valores incompatibles con su modo.

@end defvr

@defvr {Variable opcional} tr_warn_undeclared
Valor por defecto: @code{compile}

Determina cuando enviar mensajes sobre variables no declaradas.

@end defvr

@defvr {Variable opcional} tr_warn_undefined_variable
Valor por defecto: @code{all}

Devuelve un aviso cuando se detectan variables globales no definidas.

@end defvr

@deffn {Función} compile_file (@var{nombre_fich})
@deffnx {Función} compile_file (@var{nombre_fich}, @var{nombre_fich_compilado})
@deffnx {Función} compile_file (@var{nombre_fich}, @var{nombre_fich_compilado}, @var{nombre_fich_lisp})

Traduce el fichero Maxima @var{nombre_fich} a Lisp, ejecuta el compilador de Lisp y, en caso de ser exitosa la compilación, carga el código compilado en Maxima.

La función @code{compile_file} devuelve una lista con los nombres de tres ficheros: el fichero original en Maxima, la traducción Lisp, notas sobre la traducción y el código compilado. Si la compilación falla, el cuarto elemento es  @code{false}.

Algunas declaraciones y definiciones entran en efecto tan pronto como el código Lisp es compilado (sin cargar el código compilado). Éstas incluyen funciones definidas con el operador @code{:=}, macros definidas con el operador @code{::=}, @code{alias}, @code{declare}, @code{define_variable},  @code{mode_declare} y @code{infix}, @code{matchfix},
@code{nofix}, @code{postfix}, @code{prefix} y @code{compfile}.

Asignaciones y llamadas a funciones no se evalúan hasta que el código compilado es cargado. En particular, dentro del fichero Maxima, asignaciones a los controles ("flags") de traducción (@code{tr_numer}, etc.) no tienen efecto durante la traducción.

El @var{nombre_fich} no puede contener sentencias del tipo @code{:lisp}.

La función @code{compile_file} evalúa sus argumentos.

@end deffn


@deffn {Función} declare_translated (@var{f_1}, @var{f_2}, ...)

Cuando se traduce un fichero de código Maxima a Lisp, es importante para el traductor saber qué funciones de las que están en el fichero van a ser llamadas como traducidas o compiladas, y cuáles son simplemente funciones Maxima o que no están definidas. Se genera el código @code{(MFUNCTION-CALL fn arg1 arg2 ...)} cuando el traductor no sabe si @code{fn} va a ser una función lisp.

@end deffn

