cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
txnelson
Super User

Confusion with For Each resolving the value variable

In solving Iteratively create columns containing formulae I ran across a need to structure the solution in a way that I do not understand why.  My initial solution was

Names Default To Here( 1 );
dt = 
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );

colNames = dt << get column names( continuous, string );

For Each( {col}, colNames,
	theTarget = (Column( Eval( col ) ) << get property( "Spec Limits" ))["Target"];
	Eval(
		Eval Expr(
			New Column( col || " Minus Target",
				Numeric,
				"Continuous",
				Format( "Best", 10 ),
				Formula( As Column( Eval( col ) ) - Expr( theTarget ) )
			)
		)
	);
);

And it fails for


Column NPN1 Minus Target Formula Interrupted Name Unresolved: col at row 1 in access or evaluation of 'col' , col/*###*/ Formula evaluation errors have been ignored Column NPN1 Minus Target Formula Interrupted Name Unresolved: col at row 1001 in access or evaluation of 'col' , col/*###*/ Formula evaluation errors have been ignored

While by forcing an assignment of the variable  col  The code will work

Names Default To Here( 1 );
dt = 
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );

colNames = dt << get column names( continuous, string )

For Each( {xcol}, colNames, col = xcol; theTarget = (Column( Eval( col ) ) << get property( "Spec Limits" ))["Target"]; Eval( Eval Expr( New Column( col || " Minus Target", Numeric, "Continuous", Format( "Best", 10 ), Formula( As Column( Eval( col ) ) - Expr( theTarget ) ) ) ) ); );

Also, once I run the code with 

	col = xcol;

I can run the code without the xcol assignment, and the original code will work.

 

This is confusing to me.  Can anyone explain the reasoning behind this?

Jim
1 ACCEPTED SOLUTION

Accepted Solutions
jthi
Super User

Re: Confusion with For Each resolving the value variable

Most likely someone from JMP has to provide the correct answer . @EvanMcCorkle ?

 

I'm not sure about the exact reason, but one reason is that the col won't get evaluated inside the formula (change Eval() to Expr() to force column name inside As Column()) (Or I think you can run << run formulas after formula creation and then remove formula immediately to make sure it won't get re-evaluated with incorrect column).

 

If col is the variable you store for each container values, it won't exist outside the loop with those values (setting xcol to col somewhat bypasses this)

 

Names Default To Here(1);

a = {"a", "b", "c"};
b = "z";

show(b);
For Each({b}, a,
	show(b);
);
show(b);

/*
b = "z";
b = "a";
b = "b";
b = "c";
b = "z";
*/

 

I prefer using this method (Expr(NameExpr(AsColumn())) as this leaves the formula "cleaner" (:name instead of AsColumn("name").

 

Names Default To Here(1);
dt = Open("$SAMPLE_DATA/semiconductor capability.jmp");

colNames = (dt << get column names(continuous, string))[1::10];

For Each({col}, colNames,
	theTarget = (Column(Eval(col)) << get property("Spec Limits"))["Target"];
	Eval(
		Eval Expr(
			New Column(col || " Minus Target",
				Numeric,
				"Continuous",
				Format("Best", 10),
				Formula(Expr(NameExpr(As Column(col))) - Expr(theTarget))
			)
		)
	);
);

 

 

This is most likely not the same issues as ... Each loops have with function local scope (this is extremely annoying ... Each loops do not behave properly with function's local scope. I have reported this to JMP support)

 

Names Default To Here(1);

b = 2;

my_f = function({a}, {Default Local},

	c = Transform Each({item}, a,
		a * b
	);
	return(c);
);

my_f2 = function({a}, {Default Local},
	
	b = b; // "Fix"
	c = Transform Each({item}, a,
		a * b
	);
	return(c);
);

Try(
	show(my_f({1,2,3}));
,
	show(exception_msg);
);

Try(
	show(my_f2({1,2,3}));
,
	show(exception_msg);
);

 

 

-Jarmo

View solution in original post

1 REPLY 1
jthi
Super User

Re: Confusion with For Each resolving the value variable

Most likely someone from JMP has to provide the correct answer . @EvanMcCorkle ?

 

I'm not sure about the exact reason, but one reason is that the col won't get evaluated inside the formula (change Eval() to Expr() to force column name inside As Column()) (Or I think you can run << run formulas after formula creation and then remove formula immediately to make sure it won't get re-evaluated with incorrect column).

 

If col is the variable you store for each container values, it won't exist outside the loop with those values (setting xcol to col somewhat bypasses this)

 

Names Default To Here(1);

a = {"a", "b", "c"};
b = "z";

show(b);
For Each({b}, a,
	show(b);
);
show(b);

/*
b = "z";
b = "a";
b = "b";
b = "c";
b = "z";
*/

 

I prefer using this method (Expr(NameExpr(AsColumn())) as this leaves the formula "cleaner" (:name instead of AsColumn("name").

 

Names Default To Here(1);
dt = Open("$SAMPLE_DATA/semiconductor capability.jmp");

colNames = (dt << get column names(continuous, string))[1::10];

For Each({col}, colNames,
	theTarget = (Column(Eval(col)) << get property("Spec Limits"))["Target"];
	Eval(
		Eval Expr(
			New Column(col || " Minus Target",
				Numeric,
				"Continuous",
				Format("Best", 10),
				Formula(Expr(NameExpr(As Column(col))) - Expr(theTarget))
			)
		)
	);
);

 

 

This is most likely not the same issues as ... Each loops have with function local scope (this is extremely annoying ... Each loops do not behave properly with function's local scope. I have reported this to JMP support)

 

Names Default To Here(1);

b = 2;

my_f = function({a}, {Default Local},

	c = Transform Each({item}, a,
		a * b
	);
	return(c);
);

my_f2 = function({a}, {Default Local},
	
	b = b; // "Fix"
	c = Transform Each({item}, a,
		a * b
	);
	return(c);
);

Try(
	show(my_f({1,2,3}));
,
	show(exception_msg);
);

Try(
	show(my_f2({1,2,3}));
,
	show(exception_msg);
);

 

 

-Jarmo