# Parameter qualifiers

Parameter qualifiers are keywords used in the Parameters attribute of a function to specify what kind of value the function expects for each parameter. They include:

• Class Qualifiers, such as Index and Variable, which specify what class of Object is expected.
• Evaluation mode qualifiers, such as Mid and Prob, control whether to evaluate a parameter as deterministic or probabilistic.
• Data type qualifiers, such as Number, Text, Reference, and Handle, which specify the expected data type.
• Dimension qualifiers, such as Atom, List, Array, and [i], which specify the expected array dimensions and support array abstraction.
• Optional and Repeated (or ...) specify whether a parameter is optional (with default value) or may be repeated.

## Introducing parameter qualifiers

Parameter qualifiers help make sure that each parameter gets the kind of value or object that the function expects. They help detect or avoid errors when using System functions and User-defined functions. If the actual parameter is different from what the qualifier specifies, Analytica may be able to convert it to what was expected, or otherwise flags an error.

For example, this function returns the value of index i for which array tList indexed by i contains text matching t:

Function TextMatch(t, tList, i, caseSensitive )
Parameters: (t: Text Atom; tList: Text [i]; i: Index; caseSensitive: Boolean Atom Optional = True)
Description: If t matches a cell in tlist, a vector of text values indexed by i, it returns the value of i, otherwise Null.
By default the match is sensitive to letter case. If you specify optional parameter caseSensitive as False, it ignores the letter cases.
Definition:
If Not caseSensitive Then (
 t := TextUpperCase(t);
 tList := TextUpperCase(tList)
);
SubIndex( tList, t, i)

In the Parameters attribute, each parameter is followed by ":" and one or more qualifiers. The qualifier Text specifies that t and tList must contain Text values (not numbers). The dimension qualifiers [i] and Index specify that tList should have an index i, and parameter i should be the identifier of that Index. It will give an error message if i is not an Index variable. The qualifiers Boolean Optional = True specify that parameter caseSensitive should be a Boolean (True or False) and is optional. If omitted, it defaults to True -- i.e. the text match is sensitive to whether letters are upper- or lowercase.

If you write your own User-defined functions, it is important to understand at least the basics of parameter qualifiers. If not, you may find it useful when you are using built-in functions.

## What you must know

If you learn about no other qualifiers, the one qualifier you need to know about is Index. You should think about it this way: some parameters are values, and some parameters are indexes. The value parameters can exist with no qualifiers, but an index parameter must have the Index qualifier. If you create a function that operates over an index, you’ll want an index qualifier.

## Evaluation mode qualifiers

Evaluation modes control how, or whether, Analytica evaluates each parameter when a function is used (called). The evaluation mode qualifiers are:

### Mid

Mid evaluates the parameter determinstically, or in mid mode, using the mid (usually median) of any explicit probability distribution.

### Prob

Prob evaluates the parameter probabilistically, i.e., in prob mode, if it can. If you declare the dimension of the parameter, include the dimension Run in the declaration if you want the variable to hold the full sample, or omit Run from the list if you want the variable to hold individual samples. For example:

(A: Prob [In1, Run])

### Sample

Sample evaluates the parameter probabilistically, i.e., in prob mode, if it can. If you declare the dimension of the parameter, include the dimension Run in the declaration if you want the variable to hold the full sample, or omit Run from the list if you want the variable to hold individual samples. For example:

(A: Sample[In1, Run])

### Context

Context evaluates the parameter deterministically or probabilistically according to the current context. For example:

Function Fn1(x)
Parameters: (x: Context)
Mean(Fn1(x))

Mean() is a statistical function that always evaluates its parameter probabilistically. Hence, the evaluation context for x is probabilistic, and so Fn1 evaluates x probabilistically.

Context is the default evaluation mode used when no evaluation mode qualifier is mentioned. So, strictly, Context is redundant, and you can omit it. But, it is sometimes useful to specify it explicitly to make clear that the function should be able to handle the parameter whether it is deterministic or probabilistic.

### ContextSample

ContextSample causes the qualified parameter to be evaluated in prob mode if any of the other parameters to the function are Run. If not, it evaluates in context mode — i.e., prob or mid following the context in which the function is called.

This qualifier is used for the main parameter of most built-in statistical functions. For example, Mean has these parameters:

Mean(x: ContextSample[i]; i: Index = Run)

Thus, Mean(x, Run) evaluates x in prob mode. So does Mean(x), because the index i defaults to Run. But, Mean(x, j) evaluates x in mid mode, because j is not Run.

When the parameter declaration contains more than one dimension, prob mode is used if any of the indexes is Run.

### Index

Index indicates that the parameter must be an index variable, or a dot-operator expression, such as a.i. You can then use the parameter as a local index within the function definition. This is useful if you want to use the index in a function that requires an index, for example Sum(x, i) within the function.

### Variable

Variable or Var indicates that the parameter must be a variable, i.e., and unquoted identifier of a variable object. You can then treat the parameter name as equivalent to the variable within the function definition. Here the parameter name is a local alias of the variable, and the variable does not get evaluated by the function call, which is different from a Context where the parameter is evaluated and the resulting value is passed in. Variable is useful if you want to use the variable in one of the few expressions or built-in functions that require a variable as a parameter, for example, WhatIf, Dydx, and Elasticity.

### Object

The parameter must be the identifier of an object. This is virtually the same as the Function_parameter_qualifiers#Variable qualifier except that it can be any object, whereas Variable requires the object to be a variable object. Inside the function, the parameter name acts as a local alias of the object itself.

### Module

The parameter must be either the identifier of a module or an expression that computes a handle to a module. Inside the function, the parameter acts as a local alias of the module object, similar to an Object qualifier.

### Class

The parameter must either be the identifier of a class object (for example, the object named Decision which represents the class of decision nodes), or it can be an expression that computes a handle to a class object.

### Attribute

The parameter must either be the identifier of an Attribute (for example, Description), or an expression that returns a handle to an Attribute object.

### Expression

The expression passed to the parameter is not evaluated, and the parsed expression is passed into the function. The function will usually evaluate the function itself under the appropriate circumstances (e.g., see Evaluate). Because the expression is precisely the parsed expression that appears in the function call, the expression could include local variables which will no longer be within lexical scope inside the function and will not refer to anything valid in the UDF's stack frame (or may refer to the wrong local value). Hence, this variation should not be used with UDFs if expressions containing local identifiers might be passed -- use Unevaluated instead. For built-in functions, it is more efficient than Unevaluated and can be used because built-in functions don't create a new stack frame (mentioned here for the benefit of Lumina's internal developers).

### Unevaluated

The expression passed to the parameter is not evaluated, and the parsed expression is passed into the function. The function will usually evaluate the function itself under the appropriate circumstances (e.g., see Evaluate). This differs from the Expression qualifier in that local variables are replaced by their values in the expression. So, for example, given the UDF

Function F( e : Unevaluated )

and the caller

Local a := 5;
F( a^2 )

When the definition of F is evaluated, «e» will be the parsed expression (5^2) instead of (local_a ^ 2).

## Dimension qualifiers

A dimension or array qualifier can specify that a parameter is an array with specified index(es) or at Atom.or Scalar with no indexes,.

### Atom

Atom specifies that the parameter must be an atom — a single number, text, or other value, not an array when the function is evaluated. But the actual parameter may be an array when you call the function. If it is, Analytica disassembles the array into atoms, applies the function separately to each atom, and then reassembles the results into an array with the same indexes as the original parameter. In this way, it makes sure that the function works fine on an array-valued parameter, and fully supports array abstraction -- even though the internal definition of the function can only handle an atomic parameter value.

You need to use Atom only when the function uses one of Analytica’s few constructs that require an atomic parameter or operand — i.e., that does not fully support array abstraction. See Ensuring Array Abstraction.

You might be tempted to use Atom to qualify parameters of every function, just in case it’s needed. But, we strongly advise against that approach: The computational time to disassemble an array parameter into Atoms, call the function multiple times, and reassemble the results can be substantial. So, avoid using it except when really necessary.

### Scalar

Scalar indicates that the parameter should be a single number, not an array. It means the same as Number Atom.

### Array[i1, i2...]

Array specifies that the parameter should be an array with the designated index(es) when it the function is evaluated. The actual parameter may have indexes in addition to those listed. If so, as with Atom or Scalar, it disassembles the array into subarrays, each with only the listed indexes; applies the function to each subarray; and reassembles the results to have the original set of index(es) -- possibly excluding one or more of the listed indexes if the function reduces over the indexx. For example, if Fu1 has the parameter declaration:

Function Fu1(a: Array[Time])

and if a, when evaluated, contains index(es) other than Time, it iterates over the other index(es) calling Fu1, for each one, and thus ensuring that each time it calls Fu1, parameter a has no index other than Time. See Array()

An array declaration can specified zero or more indexes between the square brackets. With zero indexes, it is equivalent to the qualifier Atom, specifying that the parameter must be a single value or atom each time the function is called.

The square brackets are sufficient and the qualifier word Array is optional, so you could write simply:

Function F(a: Number [I])

Function F(a: Number Array [I])

Each index identifier listed inside the brackets can be either a global index variable or another parameter explicitly qualified as an Index. For example the Parameters attribute:

(A: [Time, j]; j: Index)

specifies that parameter a must be an array indexed by Time (a built-in index variable) and by the index variable passed to parameter j.

In the absence of an array qualifier, it accepts an array-valued parameter for the function, and passes it into the function Definition for evaluation with all its indexes. This kind of vertical array abstraction is usually more efficient for those functions that can handle array-valued parameters.

### All

All forces the parameter to have, or be expanded to have, all the Indexes listed. For example:

x: All [i, j]

Here the All qualifier forces the value of x to be an array indexed by the specified index variables, i and j. If x is a single number, not an array, All converts it into an array with indexes, i and j, repeating the value of x in each element. Without All , Analytica would simply pass the atomic value x into the function definition.

### Reduced

Reduced is a parameter qualifier that acts in concert with Dimension qualifiers to exclude any dimensions that are being iterated. Consider, for example,

F(x: [i]; z: Reduced)

Suppose you pass to parameter to «x» a value with indexes [i, j] and pass to parameter «z» a value with indexes [j, k]. When calling function F the qualifier [i] for parameter «x» causes the function to iterate over -- i.e. be called separately for each value of -- index j. Without the Reduced qualifier, «z» would be indexed by j and k on each iteration, even though «x» would not have the j index. By adding Reduced as a qualifier for «z» , it slices «z» on each iteration by j, but leaves «z» indexed by k.

The Reduced qualifier is often useful when the parameter is logically atomic, but where efficiency can be gained by processing many values of «z» at the same time. For example, suppose your function F "fits" a curve to data «x» and returns the value of the fitted curve at «z». With reduced, it can compute the data fit only once, and then apply it to all the values of «z».

## Data Type qualifiers

Type checking qualifiers cause a check of whether the value of a parameter (or each element of an array-valued parameter) has the expected type — such as, number, text, or reference. If any values don't have the expected type, Analytica gives an evaluation error when it tries to use (call) the function. The type checking qualifiers are:

Name Description
Number A number, including  +INF, -INF, or NaN
Positive A number greater than zero, including INF
Nonnegative Zero, or a number greater than zero including INF
Text A text value
Reference A reference to a value, created with the \ operator
Handle A handle to an Analytica object, obtained from the Handle or HandleFromIdentifier functions. It also accepts an array of handles.
Color (requires Analytica 5.0) An ARGB-integer or a textual color name. The value passed is always an ARGB integer.
OrNull Used in conjunction with one of the above type qualifiers, allows Null values in addition to the given type. For example:

x: Number OrNull
Some array functions ignore Null values, but require this qualifier for the null values to be accepted without flagging an error. When a parameter is declared atomic and this qualifier is not specified, the function evaluation is skipped entirely and the result is null. If you want Null to be passed into your function and the parameter is atomic, then you need to include the OrNull qualifier.

Coerce If you accompany a Type checking qualifier by the Coerce qualifier, it tries to convert, or coerce, the value of the parameter to the specified type. For example:

a: Coerce Text [I]
tries to convert the value of a to an array of text values. It gives an error message if any coercion is unsuccessful.

Coerce supports these conversions:

From To Result
Null Text "Null"
Number Text Number as text, using the number format of the variable or function calling the function.
Text Number or Positive If possible, interprets it as a date or number, using the number format.
Null Reference \Null
Number Reference \X
Text Reference \Text

Other combinations, including Null to Number, give an error message that the coercion is not possible.

## Ordering qualifiers: Ascending and Descending

The ordering qualifiers, Ascending or Descending, check that the parameter value is an array of numbers or text values in the specified order. For text values, Ascending means alphabetical order, and Descending means the reverse.

Ordering is not strict; that is, it allows successive elements to be the same. For example, [1, 2, 3, 3, 4] and ['Anne', 'Bob', 'Bob', 'Carmen'] are both considered ascending.

If the value of the parameter does not have the specified ordering, or it is an atom (not array) value, it gives an evaluation error.

If the parameter has more than one dimension (other than Run), you should specify the index of the dimension over which to check the order, for example:

A: Ascending [I]

## Optional parameters

You can specify a parameter as optional using the qualifier Optional, for example:

Function F(a: Number; b: Optional Number)

In this case, you can call the function without mentioning b, as:

F(100)

Or you can specify b:

F(100, 200)

You can specify a default value for an optional parameter after an = sign, for example:

Function F(a: Number; b: Number Optional = 0)

It uses the default value if the actual parameter is omitted. Given an equal sign and default value, the Optional qualifier is itself optional (!):

Function F(a: Number; b: Number = 0)

Optional parameters can appear anywhere within the declaration — they are not limited to the final parameters. For example, if you declare the parameters for G as:

Function G(A: Optional; B; C: Optional; D; E: Optional)

You can call G in any of these ways:

G(1, 2, 3, 4, 5)
G(1, 2, , 4)
G( , 2, , 4)
G( , 2, 3, 4, 5)

Generally, you must include the commas to indicate an omitted optional parameter, before any specified parameter, but not after the last specified parameter.

Or you can use named-based calling syntax, which is usually clearer and simpler:

G(B: 2, D: 4)

### IsNotSpecified](v)

If you omit a parameter that is not given a default value, you can test this inside the function definition using function IsNotSpecified(v). For example, the first line of the body of the function might read:

If IsNotSpecified(a) then a := 0;

But it is usually simpler to specify the default value in the parameter list as:

Function H(x;, a : = 0)

## Repeated parameters (...)

Three dots, ... qualifies a parameter as repeatable, meaning that the function accepts one or more actual parameters for the formal parameter. For example:

Function ValMax(x: ... Number) := Max(x)
ValMax(3, 6, -2, 4) → 6

ValMax() returns the maximum value of the actual parameters given for its repeated parameter, «x». Unlike the built-in Max() function, it doesn’t need square brackets around its parameters.

During evaluation of ValMax(), the value of the repeated parameter, «x», is a list of the values of the actual parameters, with implicit (Null) index:

[3, 6, -2, 4]

ValMax() also take array parameters, for example:

Variable Z := [0.2, 0.5, 1, 2, 4]
ValMax(Sqrt(Z), Z^2, 0)

By itself, the qualifier “...” means that the qualified parameter expects one or more parameters. If you combine “...” with Optional, it accepts zero or more parameters.

Calling a function that has only its last parameter repeated is easy. You just add as many parameters as you want in the call. The extra ones are treated as repeated:

Function F2(a; b: ...)
F2(1, 2, 3, 4)

Within the function, F2, the value of a is 1, and the value of b is a list [2, 3, 4].

If the repeated parameter is not the last parameter, or if a function has more than one repeated parameter, for example:

Function Fxy(X: ... scalar; Y: ... Optional Scalar)

You have several options for syntax to call the function. Use name-based calling:

Fxy(x: 10, 20, 40, y: 2, 3, 4)

Or use position for the first repeated parameter group and name only the second parameter y:

Fxy(10, 20, 40, y: 2, 3, 4)

Or enclose each set of repeated parameters in square brackets:

Fxy([10, 20, 40], [2, 3, 4])

Use Repeated parameter forwarding when you need to compute the list of parameters passed to a repeated parameter. You place three dots in front of an expression that computes a list, each item in the list being one repeat for the parameter. The second parameter of Max is a repeated index, so this can be used to find the largest element in a multidimensional array of unknown dimensionality.

Max(x, ...IndexesOf(x))

## Deprecated synonyms for parameter qualifiers

Most parameter qualifiers have several synonyms. For example, Atomic, AtomType, and AtomicType are synonyms for Atom. We recommend that you use only the words listed above. If you encounter other synonyms in older models, see Deprecated Synonyms for Parameter Qualifiers.