While working on a big script, I noticed some interesting behavior regarding expressions.
Consider the following piece of jsl code:
// Create a namespace for cleanliness
ns = New Namespace("ns");
// Make an example data table dt
ns:dt = New Table("window",
New Column("a", set values([1,2,3])),
New Column("b", set values([1,4,9]))
);
// 1. Make an expression gr_exp1 containing the graph builder instructions
ns:gr_exp1 = expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
);
// Running the expression will build the graph (as expected)
ns:gr_exp1;
// 2. Make a function f1 that saves the graph builder instructions into an expression gr_exp2
ns:f1 = function({},{Default Local},
ns:gr_exp2 = expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
);
);
// When one runs the function, the graph will be displayed, though only saving the
// expression into a variable is desired.
ns:f1;
Since for this script I just wanted to save the graph as an expression (and evaluate later), I did not want it to pop-up. After some trial and error, I noticed that nesting the expression in another expression solved the problem:
ns:f2 = function({},{Default Local},
ns:gr_exp2 = expr(expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
));
);
// Now no graph is displayed when running the function, and the expression is saved!
ns:f2;
That solved my issue. But, given the structure of my script, I actually needed to call the function f2 from another function, say f3:
// 4. Now make a function f3 that calls f2 (with the idea of simply saving an expression)
ns:f3 = function({},{Default Local},
ns:f2;
);
// Running the script will produce a graph again...
ns:f3;
Then I noticed that modifying the function f2 to have a triple nested expression solved the issue - it saves the graph as an expression, while suppressing its evaluation:
// This can be solved by modifying f2
ns:f2 = function({},{Default Local},
ns:gr_exp2 = expr(expr(expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
)));
);
// Running f3 now acts as desired (saves expression and suppresses evaluation of graph)
ns:f3;
While I have managed to navigate through this issue, my question is:
How do I (correctly) make a function that, upon calling it, saves the expression into a variable without evaluating the expression?
I'm using JMP Pro 18.0. Any help or comments are appreciated.
Hi @ThomasB ,
please note that the last expression of a function is used as the return value.
If you just want to assign the expression without "returning" it, please add a dummy return value:
ns:f1 = function({},{Default Local},
ns:gr_exp2 = expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
);
1;
);
or
ns:f1 = function({},{Default Local},
ns:gr_exp2 = expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
);
return(1);
);
Name Expr() might be one of the options you are looking for
https://www.jmp.com/support/help/en/18.0/#page/jmp/advanced-expressions-macros-and-lists.shtml#ww339... might be a good read. Also Expression Handling Functions: Part I - Unraveling the Expr(), NameExpr(), Eval(), ... Conundrum (there is no part2 to my knowledge)
Hi @ThomasB ,
please note that the last expression of a function is used as the return value.
If you just want to assign the expression without "returning" it, please add a dummy return value:
ns:f1 = function({},{Default Local},
ns:gr_exp2 = expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
);
1;
);
or
ns:f1 = function({},{Default Local},
ns:gr_exp2 = expr(ns:gr = ns:dt << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :a ), Y( ) ),
Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ));
);
return(1);
);
Thank you for your reply and the link, Jarmo, they are also very helpful.