An expression is something that can be evaluated. The first section of the chapter, Rules for Name Resolution in JSL Building Blocks, discussed how JMP evaluates expressions. Now you must consider when JMP evaluates expressions.
The operators to control when expressions are evaluated are Expr and Eval, which you should think of as the procrastination and eager operators. Expr just copies its argument as an expression, rather than evaluating it. Eval does the opposite: it evaluates its argument, and then takes that result and evaluates it again.
Expr and Eval can be thought of as quoting and unquoting operators, telling JMP when you mean the expression itself, and when you mean the result of evaluating the expression.
If you assign the expression x+y to a, quoting it as an expression with Expr, then whenever a is evaluated, it evaluates the expression using the current values of x and y and returns the result. (Exceptions are the utilities Show, Write, and Print, which do not evaluate expressions for pure name arguments.)
If you want the expression that is stored in the name, rather than the result of evaluating the expression, use the NameExpr function. See Retrieve a stored expression, not its result.
If you assign an extra level of expressionquoting, then when a is evaluated, it unpacks one layer and the result is the expression x+y.
If you want the value of the expression, then use Eval to unpack all layers:
The JSL Quote() function returns the contents of an expression as a quoted string. Comments and white space in the string are preserved. Syntax coloring is also applied to the output.
In the output, the contents of the JSL Quote function are enclosed in quotes.
The main use of Expr is to be able to store scripts (such as macros) in global variables.
You can use Eval to evaluate an expression explicitly:
Note, however, that in column formulas, eval only works if it is outermost in the formula. So, for example,
generates an error, since eval is actually under the Add function. Instead, use
What if you wanted the symbolic value of a global (such as the expression Distribution(Column(height)) stored in dist above), rather than the evaluation of it (the actual launched platform)? The Name Expr function does this. Name Expr retrieves its argument as an expression without evaluating it, but if the argument is a name, it looks up the name’s expression and uses that, unevaluated.
Expr returns its argument exactly, whereas Name Expr looks up the expression stored in its argument. Name Expr “unpacks” just one layer to get the expression, but does not keep unpacking to get the result.
Evaluates x to the expression a+b+c, and then evaluates the expression, returning the result, 6 (unpacks all layers).


Evaluates x to the expression a+b+c, and then evaluates the expression, returning the result, 6 (unpacks all layers).


JSL also supports functions to access and traverse expressions, all of them either a name or a literal expression as an argument. In the following, expressionArg is either a single name or a compound expression to be taken literally.
The expressionArg can be a name holding an expression, an expression evaluated to an expression, or a literal expression quoted by Expr().
NArg (name) obtains the expression held in name (it is not evaluated) and returns the number of arguments
NArg (Expr(expression)) returns the number of arguments to literal expression.
For example, if aExpr = {a+b,c,d,e+f+g};
•

NArg(aExpr) results in 4.

•

NArg(Arg(aExpr,4)) results in 3.

•

NArg(Expr({1,2,3,4})) results in 4.

Head(expressionArg) returns the head of the expression without any arguments. If the expression is an infix, prefix, or postfix special character operator, then it is returned as the functional equivalent.
The expressionArg can be a name holding an expression, an expression evaluated to an expression, or a literal expression quoted by Expr().
For example, if aExpr = expr(a+b);
•

r = Head(aExpr) results in Add().

•

r = Head (Expr(sqrt(r))) results in Sqrt().

•

r = Head({1,2,3}) results in {} .

Arg(expressionArg,indexArg) extracts the specified argument of the symbolic expression, resulting in an expression.
The expressionArg can be a name holding an expression, an expression evaluated to an expression, or a literal expression quoted by Expr().
•

•

•

As another example, if aExpr = Expr(12+13*sqrt(1415));
•

Arg(aExpr,1) yields 12

•

Arg(aExpr,2) yields 13*sqrt(1415)

•

Arg(Expr(12+13*sqrt(1415)),2) yields 13*sqrt(1415)

•

Arg(Arg(aExpr,2),1) yields the first argument within the second argument of aExpr, or 13.

•

Arg(Arg(aExpr,2),2) yields Sqrt( 14  15 )

•

Arg(Arg(Arg(aExpr,2),2),1) yields 14  15

•

Arg(Arg(Arg(aExpr,2),2),3) yields Empty()

1.

The inner Arg statement is evaluated.

// this is equivalent to Arg(Expr (13 * Sqrt( 14  15 ) ), 2)
// this is equivalent to Arg (Expr (Sqrt( 14  15 ) ), 3)
There is only one element to the Sqrt expression, so a request for the third argument yields Empty(). To access the two arguments inside the Sqrt expression, try this:
HeadName(expressionArg) returns the name of the head of the expression as a string. If the expression is an infix, prefix, postfix, or other special character operator, then it is returned as the functional equivalent.
The expressionArg can be a name holding an expression, an expression evaluated to an expression, or a literal expression quoted by Expr().
For example, if aExpr = expr(a+b);
•

r = HeadName (aExpr) results in "Add".

•

r = HeadName (Expr(sqrt(r))) results in "Sqrt".

•

r = HeadName ({1,2,3}) results in "List".

In previous versions of JMP, other versions of Arg, Narg, Head, and HeadName were implemented, called ArgExpr, NArgExpr, HeadExpr, and HeadNameExpr, respectively. These did the same thing, but did not evaluate their argument. These forms are now deprecated and will not be documented in future versions.
Eval Insert is for the situation where you want to make a lot of substitutions, by evaluating expressions inside a character string. [In Perl, this is called interpolation.]
With Eval Insert, you specify characters that delimit the start and end of an expression, and everything in between is evaluated and expanded.
The delimiter is optional. The default start delimiter is "^". The default end delimiter is the start delimiter.
When a numeric value contains localespecific formatting, include the <<Use Locale(1) option. The following example substitutes a comma for the decimal point based on the computer’s locale setting.
Eval List evaluates expressions inside a list and returns a list with the results:
Eval List is useful for loading the list of user choices returned by Column Dialog or New Window with the Modal argument.
Eval Expr() evaluates only the inner expressions and returns an expression that contains the results of the evaluation. By comparison, Eval evaluates the inner expressions, takes the results, and then evaluates it again.
Suppose that a data table contains a column named X3. Here is an example of using Eval Expr() to evaluate the inner expression first:
To evaluate further, you need to either call the result in a subsequent step, or else put Eval() around the Eval Expr(). The following examples create a Distribution report.
See Compare all the operators for controlling evaluation to learn what would happen if you tried to use Eval directly on x without first doing Eval Expr.
Parsing is the syntactic scanning of character strings into language expressions. Suppose that you have read in a valid JSL expression into a character string, and now want to evaluate it. The Parse function returns the expression. To evaluate it, use the Eval function.
To go in the reverse, use the Char function, which converts an expression into a character string. Usually the argument to a Char function is an Expr function (or a NameExpr of a global variable), since Char evaluates its argument before deparsing it.
The Char function allows arguments for field width and decimal places if the argument is a number. The default is 18 for width and 99 for decimal (Best format).
To preserve localespecific formatting in the numeric value, include the <<Use Locale(1) option as shown in the following example:
The reverse of Char is not quite as simple. To convert a character string into an expression, you use Parse, but to convert a character string into a number value, you use Num.
Char(Expr(expression))
Char(name)

Converts an expression into a character string. The expression must be quoted with Expr; otherwise its evaluation is converted to a string.


Converts a number into its character representation. Width and decimal are optional arguments to specify formatting; the default is 18 for width and 99 for decimal.


Eval(x)


Eval List(list)


Expr(x)


Returns the unevaluated expression of x rather than the evaluation of x. NameExpr is like Expr except that if x is a name, NameExpr returns the unevaluated expression stored in the name rather than the unevaluated name x.


Num("string")


Parse("string")

Compare all the operators for controlling evaluation compares various ways that you can use the evaluationcontrol operators with x. Assume that a data table contains a column named X3, and x and i have been assigned:
Eval(x) and simply calling x are equivalent.
Evaluates the expression distribution( column( expr( "X"  Char( i ) ) ) ). This results in errors. The column name is recognized as "X"Char(i) because it is packed by the Expr() function.


Evaluates the inner expression but leaves the outer expression unevaluated, so that y is Distribution(Column("X3")).


Evaluates Distribution(Column("X3")) to launch the platform.


Quotes the entire expression as a text string, adding \!" escape characters as needed.
Note that Char(x) would first attempt to evaluate x, producing an error and ultimately returning a quoted missing value: "."


Note that you must break this into at least two steps as shown. Combining it into one giant step produces different results because the Eval Expr layer causes the Parse layer to be copied literally, not executed.

Storing the expression (the script itself, not its evaluation at the moment) with Expr delays its evaluation until the global is actually called. Any variables, data points, or expressions included in that expression are evaluated on the fly when the expression is evaluated. See Stored expressions, for detailed rules for storing expressions and later evaluating them.
The following operators manipulate lists. They can also be used to manipulate expressions, as shown in the next section, Manipulating expressions. A summary of commands with explanations is in Functions for manipulating lists or expressions.
Inplace operators are those that operate on lists or expressions directly. They have From or Into in their names (for example, Remove From and Insert Into). They do not return a result; you have to show the list to see the result. The first argument for an inplace operator must be an Lvalue. An Lvalue is an entity such as a global variable whose value can be set.
For the notinplace operators, you must either state the list directly or else quote a name that evaluates to a list. Such operators do not have From or Into in their names. They return manipulated lists or expressions without changing the original list or expression given in the first argument.
Substitute and Substitute Into merit further discussion. Both find all matches to a pattern in a list (or expression) and replace them with another expression. Each pattern must be a name. The arguments are evaluated before they are applied, so most of the time you must quote them with an Expr function.
Substitute Into does the same work, in place:
The operators for manipulating lists can also operate on most expressions. Be sure to quote the expression with Expr. For example:
As with lists, remember that the first argument for inplace operators must be an Lvalue. An Lvalue is an entity such as a global variable whose value can be set. Inplace operators are those that operate on lists or expressions directly. They have From or Into in their names (for example, Remove From and Insert Into). They do not return a result; you have to show the expression to see the result.
For the notinplace operators, you must either state the expression directly or else quote a name that evaluates to an expression using NameExpr. Such operators do not have From or Into in their names. They return manipulated lists or expressions without changing the original list or expression given in the first argument.
Substituting is extremely powerful; please review the earlier discussion Substituting. Here are a few notes regarding substituting for expressions.
Substitute(pattern,name,replacement) substitutes for names in expressions
NameExpr looks through the name but copies instead of evaluates:
Substitute evaluates all its arguments, so they must be quoted correctly:
SubstituteInto needs an Lvalue, so the first argument is not quoted:
Substitute is useful for changing parts of expressions, such as in the following example that tests the Is functions:
You can use SubstituteInto to have JMP solve quadratic equations. The following example solves 4x2  9 = 0:
The operators for manipulating lists and expressions are discussed in the previous section, Manipulating lists, and summarized in Functions for manipulating lists or expressions.
Copies the list or expression, deleting the item(s) at the indicated position. If position is omitted, items are deleted from the end. Position can be a list of positions. An extra argument, n, deletes n items instead of just 1.


Inserts a new item into the list or expression at the given position. If position is not given, it is inserted at the end.


Shift an item or n items from the front to the back of the list or expression. Shift items from back to front if n is negative.


Sort the elements of a list or the terms of an expression. Numbers sort low, followed by the name value of names, strings, or operators. For example 1+2 is lower than 12 because the name value Add sorts lower than the name value Subtract. {1,2} sorts lower than {1,3}, which sorts lower than {1,3,0}. {1000} sorts lower than {“a”}, but {a} and {“a”} sort as equal.


Creates a matrix of subscript positions where the values in matrix A match the values in matrix B. A must be a matrix sorted in ascending order.


Finds all matches to the pattern in the list or expression, and replaces them with the replacement expression. Each pattern must be a name. The second and third arguments are evaluated before they are applied, so most of the time you must quote them with an Expr function. To delay evaluating an argument, use Name Expr instead of Expr. You can list multiple patternreplacement pairs for multiple substitutions in one statement.

