OPTIMIZATION
Function Definition
(C1) G(L):=CATCH(MAP(LAMBDA([X], IF X<0 THEN THROW(X) ELSE F(X)),L))$ (C2) G([1,2,3,7]); (D2) [F(1), F(2), F(3), F(7)] (C3) G([1,2,-3,7]); (D3) - 3
The function G returns a list of F of each element of L if L consists only of non-negative numbers; otherwise, G "catches" the first negative element of L and "throws" it up.
TRANSLATE_FILE("filename").
For convenience you might define
Compile_and_load(FILENAME):= LOAD(COMPILE_LISP_FILE(TRANSLATE_FILE(FILENAME)[2]))[2]);
These file-oriented commands are to be preferred over the use of COMPILE, COMPFILE, and the TRANSLATE SAVE combination.
introduces a global variable into the MACSYMA environment. This is for user-written packages, which are often translated or compiled. Thus
DEFINE_VARIABLE(FOO,TRUE,BOOLEAN);
does the following:
(1) MODE_DECLARE(FOO,BOOLEAN); sets it up for the translator.
(2) If the variable is unbound, it sets it: FOO:TRUE.
(3) DECLARE(FOO,SPECIAL); declares it special.
(4) Sets up an assign property for it to make sure that it never gets set to a value of the wrong mode. E.g. FOO:44 would be an error once FOO is defined BOOLEAN.
See DESCRIBE(MODE_DECLARE); for a list of the possible "modes". The optional 4th argument is a documentation string. When TRANSLATE_FILE is used on a package which includes documentation strings, a second file is output in addition to the LISP file which will contain the documentation strings, formatted suitably for use in manuals, usage files, or (for instance) DESCRIBE. With any variable which has been DEFINE_VARIABLE'd with mode other than ANY, you can give a VALUE_CHECK property, which is a function of one argument called on the value the user is trying to set the variable to.
PUT('G5,LAMBDA([U],IF U#'G5 THEN ERROR("Don't set G5")), 'VALUE_CHECK);
Use DEFINE_VARIABLE(G5,'G5,ANY_CHECK, "this ain't supposed to be set by anyone but me.") ANY_CHECK is a mode which means the same as ANY, but which keeps DEFINE_VARIABLE from optimizing away the assign property.
ARRAY(yi, dim1, dim2, ...)
should be used when first declaring the bounds of the array. If all the elements of the array are of mode FIXNUM (FLOAT), use FIXNUM (FLOAT) instead of COMPLETE. Also if every element of the array is of the same mode, say m, then
MODE_DECLARE(COMPLETEARRAY(yi),m))
should be used for efficient translation. Also numeric code using arrays can be made to run faster by declaring the expected size of the array, as in:
MODE_DECLARE(COMPLETEARRAY(A[10,10]),FLOAT)
for a floating point number array which is 10 x 10. Additionally one may declare the mode of the result of a function by using FUNCTION(F1,F2,...) as an argument; here F1,F2,... are the names of functions. For example the expression,
MODE_DECLARE([FUNCTION(F1,F2,...),X],FIXNUM,Q, COMPLETEARRAY(Q),FLOAT)
declares that X and the values returned by F1,F2,... are single-word integers and that Q is an array of floating point numbers. MODE_DECLARE is used either immediately inside of a function definition or at top-level for global variables. Do PRINTFILE(MCOMPI,DOC,MAXDOC); for some examples of the use of MODE_DECLARE in translation and compilation.
FIRSTNUMB(X)::=BUILDQ([X],MODE_IDENTITY(NUMBER,X))$
and use FIRSTNUMB every time you take the first of a list of numbers.
F(X1,X2,...):=BLOCK([v1,v2,...], MODE_DECLARE(v1,mode1,v2,mode2,...),...)
where the X1,X2,... are the parameters to the function and the v1,v2,... are the local variables. The names of translated functions are removed from the FUNCTIONS list if SAVEDEF is FALSE (see below) and are added to the PROPS lists. Functions should not be translated unless they are fully debugged. Also, expressions are assumed simplified; if they are not, correct but non- optimal code gets generated. Thus, the user should not set the SIMP switch to FALSE which inhibits simplification of the expressions to be translated. The switch TRANSLATE, default: [FALSE], If TRUE, causes automatic translation of a user's function to LISP. Note that translated functions may not run identically to the way they did before translation as certain incompatabilities may exist between the LISP and MACSYMA versions. Principally, the RAT function with more than one argument and the RATVARS function should not be used if any variables are MODE_DECLAREd CRE. Also the PREDERROR:FALSE setting will not translate. SAVEDEF[TRUE] - if TRUE will cause the MACSYMA version of a user function to remain when the function is TRANSLATEd. This permits the definition to be displayed by DISPFUN and allows the function to be edited. TRANSRUN[TRUE] - if FALSE will cause the interpreted version of all functions to be run (provided they are still around) rather than the translated version. One can translate functions stored in a file by giving TRANSLATE an argument which is a file specification. This is a list of the form [fn1,fn2,DSK,dir] where fn1 fn2 is the name of the file of MACSYMA functions, and dir is the name of a file directory. The result returned by TRANSLATE is a list of the names of the functions TRANSLATEd. In the case of a file translation the corresponding element of the list is a list of the first and second new file names containing the LISP code resulting from the translation. This will be fn1 LISP on the disk directory dir. The file of LISP code may be read into MACSYMA by using the LOADFILE function.
[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]
The list of the switches that affect the form of the translated output. This information is useful to system people when trying to debug the translator. By comparing the translated product to what should have been produced for a given state, it is possible to track down bugs.