24. Reentrancy

All of the numeric and range functions are reentrant. This means that while a function is executing it may be invoked one or more additional times and the invocations will not interfere with each other.

For example, in sin(2*sin(x)) the first call to the sin() function starts computing 2*... and to complete the expression sin() is invoked again, as sin(x), and that result is used in the multiplication by 2 in the first call.

An example of reentrancy using a range function is max(1+max(a1:a9),2+max(c1:c9)).

Although the range functions llsq and search are also reentrant, they can not be used more than once in the same expression because they return multiple values; they can only be used in multiple assignment statements. However, more than one invocation may be active at the same time, as demonstrated in the following example which minimizes g() to find the value of a3 to use while minimizing f() with respect to a1 and a2:

%  cat search.ss

// minimize f(a1,a2,a3) with respect to a1,a2
// where a3 minimizes g(a1,a2,a3) given a1,a2
//
f = (a1-1)**2 + (a2-2)**2 + a3**2;
g = (a3-a1)**2 + (a3-a2)**2;
{a1:a2} = search(f,3,4); {a3:a3} = search(g,2);
eval; print all;

% SS search.ss

  f = (((A1-1)**2)+((A2-2)**2))+(A3**2) = 1.49991
  g = ((A3-A1)**2)+((A3-A2)**2) = 0.501364
  $1 = {A1:A2} = search(f,3,4) = 1.49991
  $2 = {A3:A3} = search(g,2) = 0.501364
	A
1	($1)
2	($1)
3	($2)
	A
1	0.50
2	1.50
3	1.00
This example can easily be analyzed by hand to confirm the above results. Setting the derivative of g() with respect to a3 equal to zero yields a3=(a1+a2)/2. Using that result in f() and setting the derivatives of f() with respect to a1 and a2 to zero yields a1=0.5 and a2=1.5, so then a3=1.0.