As the possibilities of macros got more and more powerful, it became also evident that one major limitation was due to the difficulty of feeding back to the macro any results from the data base. While the macro commands provide all necessary primitives to implement even very complex procedures, the execution of the macro could only be influenced in a very limited way by the contents of the data base or the results generated by the macro. Thus, a general feedback mechanism was needed to make the results of the computations available to the macro language.

In Release 4.0, this mechanism has been implemented by means of the
new concept of **scalars**,
an extension to the already existing scalar matrices. The
*scalar matrix*,
which we are used to, is always used as a matrix. The new term
*scalar*,
on the other hand, refers to the same number, but in the context of
a simple number, which is no longer associated with a matrix.

In short, scalars can be used in the following ways:

-- as scalar matrices, same as before

-- to store summary results of the network calculator

-- in all algebraic expressions used in functions and calculators

-- in macros, through a new substitution mechanism

Let us now look at some details on how this is implemented:

Scalars and scalar matrices are actually two ways of looking at exactly the same information (in a similar way as we refer to centroids or zones depending on the context). Since the maximum number of matrices is now independent for each matrix type (see above), we can assume that the number of scalars in new applications will be substantially higher (using probably always the maximum of 99), which leaves enough room for the extented use due to the new concept.

In order to allow storing of network related data in scalars, the network
calculator, module 2.41, has been enhanced to allow the user to save
the values reported in the calculation summary into scalars. The summary
now also includes the identifiers of the node or link at which the maximum
or minimum value of the expression occurred. This feature is implemented
as an additional choice in the "`Select: Type of output`" question.
The user may save as many of the summary values in scalar as needed, without
having to repeat the calculation.

A new **intrinsic function ms()**
is now available in all algebraic expressions,
i.e. in all function classes, as well as in the network and matrix calculators.
The argument of the intrinsic is rounded to an integer and interpreted as the
index of a scalar (i.e. matrix number). The value returned by the intrinsic
function is the value of the scalar. This way, scalars can be used to
implement "programmable constants" in functions, avoiding the need to
redefine a function when only the values of these constants change.
Note that the argument of the intrinsic function

`ms()`

is not necessarily
a constant, such as "`ms(15)`

", but can be an arbitrary expression such as
"`ms((volau/(lanes*200)`

1).max.1.min.5)+". It is thus possible to use
the function `ms()`

to implement look-up tables by defining a contiguous
sequence of scalars with the appropriate values. Such a look-up table
can be used to compute composed functions (such as stair-case or
piecewise linear) or discrete transformations (such as the computation of
color indices).
Macros now allow for
**scalar substitution**,
implemented in a similar way as register and parameter substitution.
The keyword
`%ms1%`

to
`%ms99%`

,
if they occur in a macro, are substituted
with the corresponding scalar value. Besides this direct addressing,
scalars may also be addressed indirectly by using the contents of the
`x`

, `y`

and `z`

registers as the scalar index. This is done by means of
the keywords `%msx%`

, `%msy%`

and `%msz%`

.
By default, the value is substituted using an automatic precision with
a maximum of 10 digits. The optional modifiers .0 to .8 can be used to
force a certain number of decimals in the fractional part of the number.
For example
`%ms15.4%`

will be substituted by the value of scalar ms15 using a 4 digit fraction,
and `%msy.0%`

will be substituted by the scalar pointed to by the current contents of
the register `y`

, rounded to an integer.

Looking at the many possible combination of all the uses of scalars outlined above, it becomes evident that this new concept opens up a whole new field of "intelligent" macros, which can combine network and matrix related data and take decisions based on the actual result obtained in the computations.