Math::...mpiler(3pm)

๐Ÿ’– Math::Symbolic::Compiler โ€” the page header calls it Math::...mpiler(3pm), bestie ๐Ÿ’–

okay so this whole page is about Math::Symbolic::Compiler, and it lives in the User Contributed Perl Documentation corner of the manual. Buckle up, it's giving "compile your math tree into a sub and go fast" energy. โœจ


๐ŸŒธ NAME ๐ŸŒธ

Math::Symbolic::Compiler โ€” compile Math::Symbolic trees into Perl code. no cap, that's the whole job description. ๐Ÿ’…


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

here's the vibe in code form, exactly as the page has it:

use Math::Symbolic::Compiler;

# A tree to compile
my $tree = Math::Symbolic->parse_from_string('a^2 + b * c * 2');

# The Math::Symbolic::Variable 'a' will be evaluated to $_[1], etc.
my $vars = [qw(b a c)];

my ($closure, $code, $trees) =
  Math::Symbolic::Compiler->compile($tree, $vars);

print $closure->(2, 3, 5); # (b, a, c)
# prints 29 (= 3^2 + 2 * 5 * 2)

# or:
($closure, $trees) =
  Math::Symbolic::Compiler->compile_to_sub($tree, $vars);

($code, $trees) = Math::Symbolic::Compiler->compile_to_code($tree, $vars);

yes ma'am, 29. the math is mathing. ๐Ÿงฎโœจ


๐ŸŒˆ DESCRIPTION ๐ŸŒˆ

okay so this module lets you take Math::Symbolic trees and turn them into Perl code and/or anonymous subroutines, where the sub's arguments get positionally mapped to the variables of the compiled Math::Symbolic tree. iconic behaviour honestly. ๐Ÿ‘‘

and why would you want that, you ask? because evaluating a Math::Symbolic tree to its numeric value is extremely slow. and yeah, compiling is slow too โ€” but once you've done all your necessary symbolic calculations, you can grab that speed gain by invoking a closure instead of evaluating a tree. glow-up complete. ๐Ÿš€

๐Ÿ’€ UNCOMPILED LEFTOVER TREES ๐Ÿ’€

not everything is sunshine in the land of compiled Math::Symbolic trees, bestie. occasionally there are trees that cannot be compiled (a derivative, for example), and those ones have to be included into the code as trees. those trees get returned in a referenced array by the compile*() methods.

good news for the closure girlies: the closures will have access to the required trees as a special variable @_TREES inside the closure's scope, so you don't have to worry about them in that case. ๐Ÿซถ

but if you plan to use the generated code itself, you do need to supply an array named @_TREES that contains the trees as returned by the compile*() methods, in the scope of the eval() you evaluate the code with. lowkey important, don't skip it.

note: you give away all the performance benefits compiling the tree might have if the closure contains uncompiled trees. ๐Ÿ˜ญ

you can tell there are any by checking the length of the referenced array that contains the trees. if it's 0, then there are no trees left to worry about. zero. nothing. slay.

๐ŸŒฑ AVOIDING LEFTOVER TREES ๐ŸŒฑ

in most cases this is pretty simple. just apply all derivatives in the tree to make sure there are none left in the tree. easy. as of version 0.130, there is no operator except derivatives that cannot be compiled.

there may, however, be some operators you cannot get rid of this easily some time in the future. if you have problems getting a tree to compile, try using the means of simplification provided by Math::Symbolic::* to get a simpler tree for compilation. ๐Ÿ’

๐ŸŽ€ EXPORT ๐ŸŽ€

None by default! but you may choose to import the compile(), compile_to_sub(), and compile_to_code() subroutines into your namespace using the standard Exporter semantics โ€” including the ':all' tag. main character import choices. โœจ


๐Ÿ’… SUBROUTINES ๐Ÿ’…

($code, $trees) = compile_to_code($tree, $vars)

the compile_to_code() class method takes one mandatory argument, which is the Math::Symbolic tree to be compiled. the second argument is optional and is an array reference to an array of variable mappings. see "VARIABLE PASSING STYLES" for details on how this works. ๐Ÿ‘€

compile_to_code() returns a string and an array reference. the string contains the compiled Perl code that uses the values stored in @_ as described in the section on positional variable passing. it also accesses a special variable @_TREES if there were any sub-trees (inside the tree that has been compiled) that were impossible to compile. the array reference returned by this method contains any of the aforementioned trees that failed to compile. simple as. ๐Ÿ’

if there are any such trees that did not compile, you may put them into the @_TREES variable in scope of the eval() that evaluates the compiled code โ€” in the same order that they were returned by this method. if you do that, the code will run and determine the value of the tree at run-time. needless to say, that is slow. ๐ŸŒ

($sub, $trees) = compile_to_sub($tree, $vars)

the compile_to_sub() class method takes one mandatory argument, which is the Math::Symbolic tree to be compiled. second argument is optional and an array reference to an array of variable mappings. see "VARIABLE PASSING STYLES" for details on how this works. same deal, different return type. โœจ

compile_to_sub() returns a list of two elements:

  • the first being the compiled anonymous subroutine ๐Ÿ‘‘
  • for the second element, please refer to the docs on the compile_to_code() subroutine ๐Ÿ’–

($sub, $code, $trees) = compile($tree, $vars)

the compile() class method takes one mandatory argument, which is the Math::Symbolic tree to be compiled. second argument is optional and an array reference to an array of variable mappings. see "POSITIONAL VARIABLE PASSING" for details on how this works. (yes bestie, the doc really does point at two differently-named sections. iykyk. ๐Ÿ˜ญ)

compile() returns a list of three elements:

  1. the compiled anonymous subroutine
  2. the compiled code
  3. for details on the second and third elements, please refer to the docs on the compile_to_code() subroutine

three-for-one deal, we love to see it. ๐Ÿ›๏ธ

๐Ÿงš VARIABLE PASSING STYLES ๐Ÿงš

currently, the Math::Symbolic compiler only supports compiling to subs with positional variable passing. at some point, the user should be able to choose between positional- and named variable passing styles. the difference is best explained by an example:

# positional:
$sub->(4, 5, 1);

# named: (NOT IMPLEMENTED!)
$sub->(a => 5, b => 4, x => 1);

with positional variable passing, the subroutine statically maps its arguments to its internal variables. the way the subroutine does that has been fixed at compile-time. it is determined by the second argument to the various compile_* functions found in this package. that second argument is expected to be a reference to an array of variable names. the order of the variable names determines which parameter of the compiled sub will be assigned to the variable. example time, bestie:

my ($sub) =
  Math::Symbolic::Compiler->compile_to_sub($tree, [qw/c a b/]);

# First argument will be mapped to c, second to a, and third to b
# All others will be ignored.
$sub->(4, 5, 6, 7);

# Variable mapping: a = 5, b = 6, c = 4

one important note remains (don't scroll past this!!): if any (or all) variables in the tree are unaccounted for, they will be lexicographically sorted and appended to the variable mapping in that order. that means if you don't map variables yourself, they will be sorted lexicographically. alphabet bestie behaviour, fr fr. ๐Ÿ”ค

thanks to Henrik Edlund's input, it's possible to pass a hash reference as the second argument to the compile* functions instead of an array reference. the order of the mapped variables is then determined by their associated value, which should be an integer starting with 0. example:

Math::Symbolic::Compiler->compile_to_sub($tree, {b => 2, a => 1, c => 0});

would result in the order c, a, b. math checks out, hash slays. ๐Ÿ“


๐Ÿซถ AUTHOR ๐Ÿซถ

please send feedback, bug reports, and support requests to the Math::Symbolic support mailing list: math-symbolic-support at lists dot sourceforge dot net. please consider letting us know how you use Math::Symbolic. thank you. ๐Ÿ’Œ

if you're interested in helping with the development or extending the module's functionality, please contact the developers' mailing list: math-symbolic-develop at lists dot sourceforge dot net.

list of contributors:

Steffen M๏ฟฝller, symbolic-module at steffen-mueller dot net
Stray Toaster, mwk at users dot sourceforge dot net
Oliver Ebenh๏ฟฝh

icons, all of them. ๐ŸŒŸ


โญ SEE ALSO โญ

new versions of this module can be found on http://steffen-mueller.net or CPAN. the module development takes place on Sourceforge at http://sourceforge.net/projects/math-symbolic/

  • Math::Symbolic

and that's the page, bestie!! ๐Ÿ’œ this was perl v5.40.0, dated 2024-09-16, rendered as Math::...mpiler(3pm) โ€” go compile something gorgeous. periodt. ๐Ÿ’…๐ŸŽ€๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from