Unevaluated functions

If an expression sequence or just a single expression is wrapped in [...], this creates a list data structure. If it is wrapped in {...}, any duplicate entries are removed and this creates a set data structure, and the order of the expressions may be rearranged. Finally, if the expression sequence or single expression is wrapped in parentheses prefexied by a name, the result is a function. If the name is assigned a procedure, then that procedure is called, and the function is evaluated. Otherwise, the result is an unevaluatd function:

[> f( 1, 2, 3, 4, 5, 6 );

$f(1, 2, 3, 4, 5, 6)$

[> bases := (1, t, t^2, t^3, t^4): # An expression sequence
[> g( t^(-1), bases, t^5 );

$g\left(\frac{1}{t}, 1, t, t^2, t^3, t^4, t^5 \right)$

Like lists and sets, unevaluated functions can be assigned to a variable:

[> unevalfn := f(1, t, t^2, t^3, t^4):

In a sense, a function is no different than a named list. Like a list, an unevaluated function is unique, and if you change an entry in that unevaluated function, a new unevaluated function is created. Thus, manipulating unevaluated functions can, too, be very expensive, both computationally and with respect to memory usage.

To find the number of entries, use the nops(...) function:

[> nops( unevalfn );

$5$

While unevaluated functions are like named lists, you cannot access the entries using indexes. Instead, in the next topic, we will look at a general mechanism for accessing and manipulating sets, lists and functions.

Membership in an unevaluated function

To determine if an expression is in an unevaluated function, like lists and sets, you can use the member function:

[> UF := f(5, 6, 6, 10, 10, 3, 1, 1, 1, 6, 4, 7, 8, 4, 10, 3, 10, 4, 5, 3):
[> member( 8, UF ); # Is '8' in the unevaluated function?

$true$

[> member( 9, UF ); # Is '9' in the unevaluated function?

$false$

If you want to know at which index the first time a value appears the unassigned function, then you can can pass in another symbol, and if the item is found, the symbol is assigned the location:

[> member( 8, UF, 'idx' );

$true$

[> idx;

$13$

Mapping a function onto an unevaluated function

Suppose you want to apply a function onto the entries of a list. The map(...) function allows this:

[> Digits := 3:
[> uf := f( seq( -2.0..2.0, 0.1 ) ):
[> map( sin^2 + 1, uf );

$[1.23, 1.15, 1.09, 1.04, 1.01, 1., 1.01, 1.04, 1.09, 1.15, 1.23]$

[> map( (x) -> [x, sin(x)], uf );

This replaces each entry $x$ of the list with a list containing the value $x$ and $\sin(x)$:

$f( [-0.5, -0.479], [-0.4, -0.389], [-0.3, -0.296], [-0.2, -0.199], [-0.1, -0.0998],$ $[0., 0.], [0.1, 0.0998], [0.2, 0.199], [0.3, 0.296], [0.4, 0.389], [0.5, 0.479] )$

In the next topic, we will look at how we can manipulate sets, lists and unevaluated functions in a common manner. You will have already noted that we can use map(...) on lists, sets and unevaluated functions.