cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
Kelly
Level III

How do functions have access to script variables when those script variables are not passed to the function?

I have a function with no input parameters, that uses a script variable. 
From my understanding with other programming languages, function should only have access to variables passed to or defined in the function. 

 

When I run the script below it returns 14. Why does this work? Is there a way to make the variables used by the function more exclusive?

 

scriptVar = 14;
myFunction = function({},{default local},
	functionVar = scriptVar;
	return(functionVar); 
);

returnVar = myFunction();

Thanks for your help.

 

1 ACCEPTED SOLUTION

Accepted Solutions
ih
Super User (Alumni) ih
Super User (Alumni)

Re: How do functions have access to script variables when those script variables are not passed to the function?

The function first looks in its own namespace to resolve symbols/variables, then if it doesn't find a variable it progressively looks through parent namespaces to find a value before returning a missing value.  Note that if the variable were created within the function it would not be accessible in the rest of your code.  I agree this is a common source of errors.

 

You can use the local function to ensure you are working with a local variable.  This is often helpful for common iterating variables like 'i' which might be inadvertently used in nested for loops. Here is an example;

 

scriptVar = 14;
myFunction = function({},{default local},
	local({scriptVar},
		functionVar = scriptVar;
		return(functionVar);
	);
);

returnVar = myFunction(); //Returns empty

 Since declaring local variables in functions is a common use case, this behavior is embedded in the 'function' function:

scriptVar = 14;
myFunction = function({}, {scriptVar = .},
	functionVar = scriptVar;
	return(functionVar);
);

returnVar = myFunction();

 

View solution in original post

7 REPLIES 7
ih
Super User (Alumni) ih
Super User (Alumni)

Re: How do functions have access to script variables when those script variables are not passed to the function?

The function first looks in its own namespace to resolve symbols/variables, then if it doesn't find a variable it progressively looks through parent namespaces to find a value before returning a missing value.  Note that if the variable were created within the function it would not be accessible in the rest of your code.  I agree this is a common source of errors.

 

You can use the local function to ensure you are working with a local variable.  This is often helpful for common iterating variables like 'i' which might be inadvertently used in nested for loops. Here is an example;

 

scriptVar = 14;
myFunction = function({},{default local},
	local({scriptVar},
		functionVar = scriptVar;
		return(functionVar);
	);
);

returnVar = myFunction(); //Returns empty

 Since declaring local variables in functions is a common use case, this behavior is embedded in the 'function' function:

scriptVar = 14;
myFunction = function({}, {scriptVar = .},
	functionVar = scriptVar;
	return(functionVar);
);

returnVar = myFunction();

 

Kelly
Level III

Re: How do functions have access to script variables when those script variables are not passed to the function?

Thanks!
I appreciate the explanation and examples I can use as alternatives.

Re: How do functions have access to script variables when those script variables are not passed to the function?

Variables are global by default and persist after script runs.

 

Why do you use a global variable in the expression for the function definition? If you need the value, use a function parameter and pass the argument when you call the function.

ih
Super User (Alumni) ih
Super User (Alumni)

Re: How do functions have access to script variables when those script variables are not passed to the function?

If I understand Kelly's question the goal is to avoid inadvertently using global variables, rather than that being the desired behavior.

 

What do you mean by functions are global by default?  My understanding was that functions persist only as long as their containing namespace exists, so in the example below fn1 is stored in the here namespace (or global in absence of names default to here(1)) but fn2 goes away as soon as fn1 finishes running, so it is recreated every time fn1 runs.

 

names default to here(1);

delete symbols();

fn1 = function({},
	fn2 = function({},
		1
	);
);

show symbols();

/*
Returns:
// Here

fn1 = Function( {},
	fn2 = Function( {}, 1 )
);

// 1 Here
*/

 

David_Burnham
Super User (Alumni)

Re: How do functions have access to script variables when those script variables are not passed to the function?

To control scope of variables in functions we use the {default local} declaration.  But variables outside of functions have global scope - that is why 'scriptvar' was visible to the function.  To prevent that behaviour we use the declaration 'names default to here(1)'.

-Dave

Re: How do functions have access to script variables when those script variables are not passed to the function?

Thanks for catching my mistake. I meant to say that variables are global by default.

 

You changed things when you invoked the Here name space. I modified your script to illustrate the global name space in effect:

 

// Names Default To Here( 1 );

Delete Symbols();

fn1 = Function( {x},
	fn2 = Function( {x},
		2*x;
	);
	5*fn2(x);
);

Show Symbols();

y = fn1(10);

Show( y );
Show Symbols();

The Log shows:

 

// Global

fn1 = Function( {x},
	fn2 = Function( {x}, 2 * x );
	5 * fn2( x );
);

// 1 Global

y = 100;
// Global

fn1 = Function( {x},
	fn2 = Function( {x}, 2 * x );
	5 * fn2( x );
);
fn2 = Function( {x}, 2 * x );
y = 100;

// 3 Global

So fn2 is also a global variable, by default. You must indicate that you prefer the exception, a local variable, when necessary.

 

ih
Super User (Alumni) ih
Super User (Alumni)

Re: How do functions have access to script variables when those script variables are not passed to the function?

Ah, that is clear now.  I guess that shows how often I don't use Names default to here(1)...