cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Discussions

Solve problems, and share tips and tricks with other JMP users.
Choose Language Hide Translation Bar
hogi
Level XIII

Indexing the return value of a function

Today's challenge:

f=Function({}, {1,2,3});

tmp=f();
y=tmp[1]; // works

x=f()[1] // doesn't work


understanding the issue helps a lot to understand how JSL works  : - )

5 REPLIES 5
hogi
Level XIII

Re: Indexing the return value of a function

the inverse problem:

names default to here(1);
x=1;
Eval(x=1); // "does the same"

x= Expr(hello);
Eval(x= Expr(hello)); // fails
hogi
Level XIII

Re: Indexing the return value of a function

Does Head evaluate its argument? 

concerning assign, does it evaluate its arguments?
1. arg: no
2. arg: yes

If you need to evaluate an expression "manually" [before taking the fist item from the result], use Eval():

x=f()[1] // doesn't work
x=Eval(f())[1] // works

concerning glue:
any args: yes

.... and Eval:
yes, of course!

besides that, there is an additional evaluation of the return value *) - after a first evaluation of the argument. So

Eval(print(1);x= Expr(hello);print(x); Expr(print(2)));

correctly assigns x=Expr(hello) and prints:

hogi_0-1769516471823.png

*) -> link / documentation / community?

jthi
Super User

Re: Indexing the return value of a function


If you need to evaluate an expression "manually" [before taking the fist item from the result], use Eval():

In my opinion that creates code which is difficult to read and should not be used, just return the value and use that. If you know you want just a  specific index (and know how many there are) you can use a list and "throw away" the rest

 

Names Default To Here(1);

return_list = Function({}, {Default Local}, return({1,2,3}));

{res, _, _} = return_list(); 
show(res, _);

 


correctly assigns x=Expr(hello) and prints:


In my opinion that should result in an error (currently it is in my opinion unexpected behavior). My guess is that this works due to how Glue behaves (it returns the last result and it then gets evaluated)

 

Names Default To Here(1);

Eval(
	x = Expr(hello);
	Print(x);
);
// Eval(Glue(Assign(x, Expr(hello)), Print(x)));

vs (Name Unresolved: hello in access or evaluation of 'hello' , hello/*###*/

 

 

Names Default To Here(1);

Eval(
	x = Expr(hello);
);
// Eval(Assign(x, Expr(hello))); 

I feel like this is what should always happen if Eval is being used in a case like this (attempt to evaluate Expr() -> fail evaluating it -> throw error). @EvanMcCorkle . 

 

View more...
Names Default To Here(1);

a = 1;

Try(
	Eval(
		x = Expr(hello);
		y = Expr(a);
	);
,
	Write("\!NFirst Example: ", exception_msg);
);

Try(
	Eval(
		y = Expr(a);
		x = Expr(hello);
	);
,
	Write("\!Second Example: ", exception_msg);
);

 

If you wish store just the hello name in variable, use Name Expr()

 

Names Default To Here(1);

x = NameExpr(hello);

 

Scripting Guide > Programming Methods > Advanced Expressions, Macros, and Lists this does have some mistakes but overall it is correct and a good read.

-Jarmo
hogi
Level XIII

Re: Indexing the return value of a function

Thanks for the additional examples and your thoughts.

hogi
Level XIII

Re: Indexing the return value of a function

Ah, things get much clearer when we take a function which is defined with arguments:

g=Function({x}, {1,2,3});
x=g()[1] //  doesn't work  (uses the function itself and takes the first element)

x=g("")[1] // works -> 1   (runs the function - then takes the first element)

 

  • If there is a function with empty brackets:
    take the function itself -  don't evaluate it.

  • If the function shows up with argument(s) inside the brackets:
    run the function! then take the first element of the result

    especially if the function is send()
    img = new image(Open( "$SAMPLE_IMAGES/tile.jpg", jpg ));
    x = (img << get size)[1];  // works
    x = send(img, getsize)[1] ; // same as this one

Recommended Articles