From Using JSL to Develop Efficient, Robust Applications (EU 2018 415), I learned that there are some functions which evaluate their argument and others which don't:
I wondered about Head. Here everything looks logic ...
f= Expr(x=2);
Substitute(NameExpr(f),Expr(x), Expr(y));
Head(f);
Head is not like Substitute, I can directly use the function name as an argument - and Head returns the head of the expression: Assign()
After checking some other functions which "don't evaluate their argument":
Expr(x=2); // x=2
Name Expr(x=2); // x=2
let's check the result for
Head(x=2)
which is "2" - i.e. the result after evaluating the argument?!?! why is it not assign()?
Names Default To Here(1);
{a, b, c} = {1, 2, 3};
Head(Expr(Sum(a, b, c)));
HeadExpr(Sum(a, b, c)); // Deprecated
Head(Sum(a, b, c));
https://www.jmp.com/support/help/en/17.2/#page/jmp/advanced-expressions-macros-and-lists.shtml#
ah, ok, the scripting index is very clear.
In general, it could make scripting a lot easier if the JSL editor used some highlighting to distinguish between arguments that are evaluated and arguments that aren't evaluated before the function is executed:
Advanced syntax highlighting in JSL Editor
Names Default To Here(1);
{a, b, c} = {1, 2, 3};
Head(Expr(Sum(a, b, c)));
HeadExpr(Sum(a, b, c)); // Deprecated
Head(Sum(a, b, c));
https://www.jmp.com/support/help/en/17.2/#page/jmp/advanced-expressions-macros-and-lists.shtml#
ah, ok, the scripting index is very clear.
In general, it could make scripting a lot easier if the JSL editor used some highlighting to distinguish between arguments that are evaluated and arguments that aren't evaluated before the function is executed:
Advanced syntax highlighting in JSL Editor
same for Narg - the argument gets evaluated (1x, like with Name Expr()
(adapted from the scripting guide)
aExpr = {a+b,c,d,e+f+g};
Show(NArg(aExpr)); //4
Show(NArg(Arg(aExpr,4))); // 3
Show(NArg(Add(1,2,3,4))); // 0
Show(NArg(Expr(Add(1,2,3,4)))); //4
Show(Head(aExpr)); //List()
Show(Head(Arg(aExpr,4))); // Add()
Show(Head(Add(1,2,3,4))); // 10
Show(Head(Expr(Add(1,2,3,4)))); //Add
this Name Expr-like behavior is especially useful for the cases with
- As Column(...)
- column reference via variable (col)
as an argument.
dt = Open("$SAMPLE_DATA/Big Class.jmp");
col = Name Expr(As Column("age"));
Head(As Column("age"));
Head(col);
dt << Recode Column(AsColumn("age"),{1},Target Column(AsColumn("age")));
dt << Recode Column(col,{1},Target Column(col));
dt << Graph Builder(Variables( X( As Column ("age") ) ),Elements( Points( X ) ));
dt << Graph Builder(Variables( X( col) ),Elements( Points( X ) ));
on the other hand: functions which don't work if a column is entered via As Column():
dt = Open("$SAMPLE_DATA/Big Class.jmp");
col = Name Expr(As Column("age"));
Distribution(Column(As Column("age")));
The easy solution: wrap As Column with Name Expr:
Distribution(Column(Name Expr(As Column("age"))));
... or use Column() instead of As column where applicable:
Distribution(Column(Column("age")));
To distinguish between both cases, you can put a print(1); at the beginning of the argument:
dt << Graph Builder(Variables( X( Print(1);As Column ("age") ) ),Elements( Points( X ) )); // fails
Distribution(Column(Print(1);Column("age"))); // works
@hogi wrote:the argument gets evaluated (1x, like with Name Expr() )
sorry:
like with Name Expr()
Head():
means: "the expressionArg can be
1) a name holding an expression - and Head will use the expression,
2) an expression - and Head will evaluate it and will use the result as input
3) or a literal expression quoted by Expr() - and Head will take the literal expression".
Name Expr():
"the expressionArg can be
1) a name holding an expression - and Name Expr will use the expression,
2) an expression - and Name Expr will take the expression".
Name Expr(1+2); // 1 + 2
Head(1+2); // 3
Argument doesn't get evaluated:
[id=1]
Functions which evaluate their arguments:
[ID=2]
almost all functions ...
most "is ..." functions:
good to know:
evaluate arguments > 1st one:
Functions which behave like Name Expr():
[ID=3]
"the expressionArg can be
1) a name holding an expression - and Name Expr will use the expression,
2) an expression - and Name Expr will take the expression".
*) so cool!
x= Expr(Print(1));
Extract Expr(x, x) // Print(1)
Other functions like Head()
[ID=7]
"the expressionArg can be
1) a name holding an expression - and Head will use the expression,
2) an expression - and Head will evaluate it and will use the result as input
3) or a literal expression quoted by Expr() - and Head will take the literal expression".