Tutorials📘 Introductory Tutorial7. Functions and Evaluation (0.5 hr)

Functions and Evaluation

The <function> and <evaluate> Tags

In DoenetML, a function is defined using the <function> tag; place the formula defining the function between the opening and closing tags. If you want to evaluate the function at a given input value later, make sure to give your function a name. For example:

     <function name="f">x^2+1</function>

To evaluate your function, use the self-closing <evaluate> tag as follows:

     <evaluate function="$functionName" input="inputValue" />

The following code shows this in action, with both numeric and symbolic input.

<setup>  
  <function name="f">x^2+1</function>
</setup>
 
<p><m>f(4) = <evaluate function="$f" input="4"/></m> </p>
<p><m>f(a+b) = <evaluate function="$f" input="a+b"/> </m> </p>

Test code here.

In the above example, the function ff was defined in the <setup> block. If you include a <function> within the main text of your document, outside of a setup block, Doenet will render the formula for the function, but not the function name. In that situation, you probably want to include code such as <m>g(x) = ... </m> to avoid having a random, “floating” formula in your document:

<p><function name="f">x^2+1</function></p>
 
<p><m>g(x) = <function name="g">sin( pi x)</function></m></p>

Test code here.

The $$ Macro

In mathematics we spend a lot of time evaluating functions. It would be time consuming and awkward to write <evaluate function="$functionName" input="inputValue" /> every time you want to plug a value into a function. Fortunately, DoenetML provides a time-saving macro:

     $$f(inputValue)

The syntax shown above is equivalent to the longer <evaluate> tag. Frequently you want to evaluate a function at some number which was provided in a <mathInput/> box or defined as a <math>, so expressions like $$f($a) are extremely common in DoenetML; essentially that expression means “evaluate f(x)f(x) at x=ax = a.”

<p><m>f(x) = 
  <function name="func">2x+3</function>
</m>, and <m>f(0) = $$func(0)</m>.</p>
 
<p>Enter a value for <m>x</m>: <mathInput name="a" prefill="2" /></p>
<p>(Try both numeric and symbolic inputs, including fractions and decimals.)</p>
 
<p><m>f($a) = $$func($a)</m></p>

Test code here.

$ vs. $$

It can be confusing for new DoenetML users to remember when to use $ or $$. The key is to remember what they stand for.

$ creates a reference to any named object in DoenetML. The expression $x amounts to “insert object x here.”

$$ is short for <evaluate> and is only used with functions, and only when you want to evaluate the function at a given input value.

The most common mistake with $ and $$ is to define a function named ff and then try to evaluate it with an expression like $f(2). That won’t work because $f creates a reference to ff; it doesn’t evaluate ff at a given value. The expression $f(2) basically means “reference the function ff here, and then write (2) next to it.” In mathematical notation, it’s akin to [f(x)]2[f(x)]2, and not f(2)f(2).

These behaviors are illustrated in the following example.

<p>The next two lines are functionally equivalent.  (Pun intended!)</p>
<p><function name="f">x^2</function></p>
<p>$f</p>
 
<p>This won't compute <m>f(2)</m>:</p>
<p>$f(2)</p>
<p>This will compute <m>f(2)</m>:</p>
<p>$$f(2)</p>

Test code here.

User-Defined Functions

In DoenetML documents, we sometimes want to evaluate a function which is provided by the student. (See this Arclength demonstration, for example.) One way to accomplish this is by having the user enter a formula in a <mathInput/>, and then use the value of that input to define a function. See the example below for an example.

<setup>
  <function name="f">$userFormula</function>
</setup>
 
<p>Define your function: <m>f(x) = </m>
  <mathInput name="userFormula" prefill="x^3-x" />
</p>
 
<p>Enter a value for <m>x</m>: 
   <mathInput name="x" prefill="2" />
</p>
 
<p><m>f($x) = $$f($x)</m></p>

Test code here.

Numeric Functions

This section is a bit technical and could be skipped if you’re just starting to learn DoenetML. It’s included for later reference, because the feature described here could be very important to you as you learn to write more complicated DoenetML documents.

By default, DoenetML functions are evaluated symbolically. If you define

     <function name="f">x^2+1</function>

then you can evaluate f with numeric or symbolic inputs: $$f(2) returns 5, and $$f(a+b) returns (a+b)2+1(a+b)^2 + 1.

Sometimes, you might know ahead of time that you will only evaluate a function with numeric inputs. In that case, you can create a “numeric function” (as opposed to “symbolic function”) by including the attribute symbolic="false" in the function definition. Check out the following example to see how this affects function evaluation.

<p>Symbolic: <m>f(x) = <function name="f">1/x</function></m></p>
<p><m> f(2) = $$f(2)</m></p>
<p><m> f(\pi) = $$f(pi)</m></p>
<p><m> f(3.1) = $$f(3.1)</m></p>
<p><m> f(a+b) = $$f(a+b)</m></p>
 
<p>Numeric: <m>g(x) = <function name="g" symbolic="false">1/x</function></m></p>
<p><m> g(2) = $$g(2)</m></p>
<p><m> g(\pi) = $$g(pi)</m></p>
<p><m> g(3.1) = $$g(3.1)</m></p>
<p><m> g(a+b) = $$g(a+b)</m></p>

Test code here.

At the very bottom of the results window (you may have to scroll!), g(a+b)=NaNg(a + b) = NaN, which is Doenet-speak for “Not a Number.” The function gg can only handle numeric input; when we try to evaluate gg with symbolic input, the evaluation fails.

For now, as you learn DoenetML, you can ignore this feature and just use symbolic calculations. In the future, the main benefit to using symbolic="false" is that numeric function evaluation is much faster. It can make a notable difference if you have an activity which requires dozens or hundreds of evaluations.

Next Steps

Now that you’ve covered the basics of functions and function evaluation in DoenetML, it’s time to learn some more advanced features and operations that are available for functions. The next section will talk about specifying domains and computing derivatives.