An expression is any combination of variables, constants, and functions linked by operators that can be evaluated. The section Rules for Name Resolution in JSL Building Blocks discusses how JMP evaluates expressions. Now you must consider when JMP evaluates expressions. JMP evaluates statements in sequence. Using expressions enables you to assign an expression and then modify or execute that expression when needed.
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.
x = 1; y = 20;
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.)
x = 1; y = 20;
a = Expr( x + y );
a;
21
x = 1; y = 20;
Show( Name Expr( a ) );
NameExpr(a) = x + y
If you assign an extra level of expression-quoting, then when a is evaluated, it unpacks one layer and the result is the expression x+y.
x = 1; y = 20;
a = Expr( Expr( x + y ) );
Show( a );
a = Expr(x + y)
x = 1; y = 20;
Show( Eval( a ) );
Eval(a) = 21
x = 1; y = 20;
a = Expr( Expr( Expr( Expr( x + y ) ) ) );
b = a;
Expr( Expr( x + y ) )
c = Eval( a );
Expr( x + y )
d = Eval( Eval( a ) );
x+y
e = Eval( Eval( Eval( a ) ) );
21
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.
x = JSL Quote( /* Begin quote. */
For (i = 1, i <= 5, i++,
	// Print the value of i.
Print( i );
);
	// End expression.
);
Show( x );
In the output, the contents of the JSL Quote() function are enclosed in quotes.
x = " /* Begin quote. */
For (i = 1, i <= 5, i++,
	// Print the value of i.
Print(i);
);
	// End expression.
";
A common use of the Expr() function is to store a script in a global variable. This could be considered as a macro. Consider the following script:
dist = Expr( Distribution( Column( height ) ) );
dist;
For( i = 0, i < 3, i = i + 1, dist );
Use Eval() to evaluate an expression explicitly:
Eval( dist );
Note, however, that in column formulas, Eval() only works if it is outermost in the formula. So, for example,
Formula( Log( Eval( Column Name( i ) ) ) );
Formula( Eval( Substitute( Expr( Log( xxx ) ), Expr( xxx ), Column Name( i ) ) ) );
Formula( Eval( Column Name( i ) ) + 10 );
generates an error, since Eval() is actually under the Add function. Instead, use:
Formula(Eval(Substitute(Expr(xxx+10), Expr(xxx), column name(i))))
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.
popVar = Expr( Summation( i = 1, N Row(), (y[i] - Col Mean( y )) ^ 2 / N Row() ) );
Summation( i = 1, N Row(), (y[i] - Col Mean( y )) ^ 2 / N Row() )
 
unbiasedPopVar = Substitute( Name Expr( popVar ), Expr( Wild()/N Row() ), Expr( (y[i] - Col Mean( y )) ^ 2 / ( N Row() - 1 ) ) );
Summation( i = 1, N Row(), (y[i] - Col Mean( y )) ^ 2 / (N Row() - 1) )
Compare x, Expr(x), NameExpr(x), and Eval(x) after submitting this script:
a = 1; b = 2; c = 3;
x = Expr( a + b + c );
x;
6
Evaluates x to the expression a+b+c, and then evaluates the expression, returning the result, 6 (unpacks all layers).
Eval( x );
6
Evaluates x to the expression a+b+c, and then evaluates the expression, returning the result, 6 (unpacks all layers).
NameExpr( x );
a+b+c
Returns the expression that was stored in x, which is a+b+c (unpacks the outside layer).
Expr( x );
x
Returns the expression x (packs one layer).
NArg(expressionArg) finds the number of arguments in expressionArg.
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 (expression) evaluates expression 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.
Arg(expressionArg,i) extracts the ith argument of expressionArg
The expressionArg can be a name holding an expression, an expression evaluated to an expression, or a literal expression quoted by Expr().
Arg(name,i) obtains the expression held in name (it is not evaluated) and finds the ith argument
Arg(expression,i) evaluates expression and finds the ith argument
Arg(Expr(expression),i) finds the ith argument of expression
As another example, if aExpr = Expr(12+13*sqrt(14-15));
Arg(aExpr,1) yields 12
Arg(aExpr,2) yields 13*sqrt(14-15)
Arg(Expr(12+13*sqrt(14-15)),2) yields 13*sqrt(14-15)
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 )
1.
The inner Arg statement is evaluated.
Arg(aExpr,2)
13 * Sqrt( 14 - 15 )
Arg(Arg(aExpr,2),2)
// this is equivalent to Arg(Expr (13 * Sqrt( 14 - 15 ) ), 2)
Sqrt( 14 - 15 )
Arg(Arg(Arg(aExpr,2),2),3)
// this is equivalent to Arg (Expr (Sqrt( 14 - 15 ) ), 3)
Empty()
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:
Arg(Arg(Arg(Arg(aExpr,2),2),1),2);
15
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 substitutions, by evaluating expressions inside a character string.
With Eval Insert, you specify characters that delimit the start and end of an expression, and everything in between is evaluated and expanded.
resultString = EvalInsert( string with embedded expressions,startDelimiter,endDelimiter )
EvalInsertInto( string l-value with embedded expressions,startDelimiter,endDelimiter )
The delimiter is optional. The default start delimiter is "^". The default end delimiter is the start delimiter.
xstring = "def";
r = Eval Insert( "abc^xstring^ghi" );  // results in "abcdefghi";
 
r = "abc^xstring^ghi"; // in-place evaluation
Eval Insert Into( r ); // r now has "abcdefghi";
 
// with specified delimiter
r = Eval Insert( "abc%xstring%ghi","%" );  // result is "abcdefghi";
 
// with different start and end delimiters
r = Eval Insert( "abc[xstring]ghi","[","]" );  // result is "abcdefghi";
When a numeric value contains locale-specific 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 Insert( "^1.2^", <<Use Locale( 1 ) );
1,2
Eval List evaluates expressions inside a list and returns a list with the results:
x = { 1 + 2, 3 + 4 };
y = Eval List( x );   // result in y is {3,7}
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:
x = Expr( Distribution( Column( Expr("X"||Char( i ) ) ) ) );
i = 3;
y = Eval Expr( x );   // returns Distribution( Column( "X3" ) )
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.
// two-step method
x = Expr( Distribution( Column( Expr( "X" || Char( i ) ) ) ) );
i = 3;
y = Eval Expr( x );
y;
 
// one-step method
x = Expr( Distribution( Column( Expr( "X" || Char( i ) ) ) ) );
i = 3;
Eval( Eval Expr( x ) );
See Table 8.3 to learn what would happen if you tried to use Eval directly on x without first doing Eval Expr.
x = Parse( "a=1" ) ;  // x now has the expression a=1
Eval( Parse( "a=1" ) ); // a now has the value 1
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.
y = Char( Expr( a = 1 ) ); // results in y having the character value "a=1"
z = Char( 42 ); // results in "42"
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).
Char( 42, 5, 2 ); // results in the character value "42.00"
To preserve locale-specific formatting in the numeric value, include the <<Use Locale(1) option as shown in the following example:
Char( 42, 5, 2, <<Use Locale(1) ); // results in the character value "42,00" in the French locale
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.
Parse( y );
Num( z );
Char
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.
 
string = char(number, width, decimal)
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
Eval(x)
Evaluates x, and then evaluates the result of x (unquoting).
Eval Expr
Eval Expr(x)
Eval List
Eval List(list)
Expr
Expr(x)
NameExpr
NameExpr(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
Num("string")
Parse
Parse("string")
Table 8.3 compares various ways that you can use the evaluation-control functions with x. Assume that a data table contains a column named X3, and x and i have been assigned:
x = Expr( Distribution(Column( Expr("X"||Char( i ) ) ) ) );
i = 3;
x; // or
Eval(x);
Not Found in access or evaluation of 'distribution' , Bad Argument( {"X" || Char( i )} )
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.
Expr(x);
x
Returns the expression x (packs an additional layer).
Name Expr(x);
Distribution(Column(Expr("X" || Char(i))))
Returns the expression stored in x exactly as is: Distribution(Column(Expr("X" || Char(i)))).
y=Eval Expr(x);
Distribution(Column("X3"))
y; //or
Eval(Eval Expr(x));
Distribution[]
Eval(eval expr(x)) and simply calling y are equivalent.
Evaluates Distribution(Column("X3")) to launch the platform.
z = Char(nameexpr(x));
"Distribution(Column(Expr (\!"X\!" || Char(i))))"
Note that Char(x) would first attempt to evaluate x, producing an error and ultimately returning a quoted missing value: "."
Parse(z);
Distribution(Column(Expr("X" || Char(i))))
a = Parse(Char( NameExpr(x)));
Eval(EvalExpr(a));
Distribution[]
Eval(
	EvalExpr(
		Parse(
			Char(
				NameExpr(x)))));
 Distribution(Column(Expr("X" || Char(i))))

Help created on 1/2/2019