Parameter

Parameters are like variables, but they are evaluated at the invocation of a shape or path and bound to the parameter variables when the shape or path is executed.

Parameter Types
As you can see from the example, a parameter declaration is a type followed by a name. There are five parameter types: number, vector, adjustment, shape, and natural. The first four are equivalent to the numeric, vector, shape adjustment, and shape replacement variable types. The natural type is a numeric type that is constrained to be a non-negative integer. The type specifier is optional for number parameters. If you don't specify a parameter type then the parameter is assumed to be a number.

Number parameters
Number parameters are floating point numbers. They can be used in any expression within a rule or path.

Vector parameters
Vectors are tuples of floating point numbers. Some functions and shape adjustments can take vectors as arguments. You must specify the size of the vector like so: vector2 is a 2-tuple, vector3 is a 3-tuple, etc. Currently the largest vector size allowed is vector9.

Natural Parameters
Natural parameters are numeric parameters that are constrained to be natural numbers (non-negative integers). They can be used in any expression within a rule or path.

Adjustment parameters
There are two ways to use adjustment parameters: they can be inserted into a shape adjustment list using the new transform adjustment (which has the abbreviated form tr). Or the parameter can be directly inserted an expression that has adjustment type.

Shape parameters
Shape parameters are used in place of the shape name in a shape replacement. The above example shows how adjustment and shape parameters are passed to a shape and used within a shape.

Restriction to Preserve Context Free Purity
Allowing unrestricted use of parameters would change CFDG files from context free grammars to indexed grammars, which are considered context-sensitive. So there are two types of numeric parameters, each with its own restrictions.

Number Parameter Restrictions
number parameters can either be one of two forms: purely local or purely non-local. A purely local expression does not depend on any incoming parameters: it does not reference an incoming parameter, does not reference a variable that depends on an incoming parameter, and does not reference a loop index which has loop bounds that depend on an incoming parameter. A purely non-local expression is simply a direct reference to an incoming parameter.

Natural Parameter Restrictions
natural parameters are restricted to be natural numbers (positive integers or zero). Any expression can be evaluated and bound to a natural parameter as long as it meets the natural number restrictions. The natural number restrictions are:
 * All constants must be natural numbers
 * All variables (local, global, and parameter variables) must be natural
 * The only permitted operators are: addition (+), proper subtraction (--), multiplication (*), exponent(^), comparison (<, >, <=, >=, ==, <>), and boolean (&&, ||, ^^, !).
 * Operands must be natural
 * Division (/), negation(-), and regular subtraction (-) are not allowed
 * Only permitted functions are: abs, div, divides, factorial, if, max, min, mod, randint, select, and sg
 * Arguments must be natural

Range of Natural Numbers
A natural number must be &ge;0 and &le;CF::MaxNatural. The default value for CF::MaxNatural is 1000, but it can be set to any value between 1 and 9,007,199,254,740,992 (the largest integer that can be stored in an IEEE 64-bit float).

Defeating Parameter Restrictions
By default, number and natural parameter restrictions are enabled, but they can be turned off. Simply provide a CF::Impure configuration declaration to turn checking on or off.

Reusing Parameters
In the curve example above the curve rule invokes itself recursively using the same parameters. There is a shorthand for doing this common operation, put an equal sign, =, in place of the parameters in the shape invocation. This works for recursive shape invocation and also for invoking a different shape that has the same parameter types. Using the parameter reuse syntax is optional. This curve shape draws exactly the same as the other one: But using the parameter reuse syntax makes your code simpler, more expressive, and faster.