cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
Craige_Hales
Super User
Introspection

tree8786.jpg

JMP's scripting language, JSL, is built out of function calls. Pretty much everything you can write in JSL is a function call. Some things don't look like function calls:

A = A + 3;

It's pretty obvious the right-hand-side of the assignment statement is an expression. It's less obvious the assignment statement itself is an expression.

E = expr ( A = A + 3 );

expr is a wrapper that you can use around an expression to prevent the expression from evaluating. E is set to the expression, not the expression's evaluated result. To take a peek at E, use the head function. Head will return the name of the function at the root of the expression:

show( head(E) );

Head(E) = Assign();

Now you see there is a function for making assignments:

Assign( testing, 3+4 );

7

show(testing)

testing = 7;

Expressions in JSL are actually trees. Here's a picture of the a=a+3 tree, root at top, leaves at bottom:

tree.png

Similar to the Head function, we can use the Arg function to access the children of the Assign function:

show( arg(E,1) );

Arg(E, 1) = A; the left-hand side

show( arg(E,2) );

Arg(E, 2) = A + 3; the right-hand side

and digging deeper,

show(head(arg(E,2)))

Head(Arg(E, 2)) = Add();  the head of the right-hand side

show(arg(arg(E,2),1))

Arg(Arg(E, 2), 1) = A;  the left side of the plus

show(arg(arg(E,2),2))

Arg(Arg(E, 2), 2) = 3;  the right side of the plus

Notice how the parenthesis nesting describes the tree. This tree only has binary splits. There is a function, narg, that returns the number of children. It returns 0 for leaf nodes. 

narg(E)

2  the assign function has two arguments, the left-hand side and the right-hand side

JMP's for statement is a function call, taking four arguments. Notice the commas separating the arguments, just like any other function.

halfCats = 1;
for( iCat = 1, iCat <= 10, iCat++, 
   halfCats = halfCats / 2; 
   write( iCat, " ", halfCats , "\!n" ) 
);

1 0.5

2 0.25

3 0.125

4 0.0625

5 0.03125

6 0.015625

7 0.0078125

8 0.00390625

9 0.001953125

10 0.0009765625

It takes three commas to separate four arguments. In this for statement, the fourth argument is two statements, separated by a semicolon. Peek at the fourth argument to see if it is actually a function too:

Head(
    Arg(
        Expr(
            For( iCat = 1, iCat <= 10, iCat++,  
               halfCats = halfCats / 2;  
               Write( iCat, " ", halfCats, "\!n" );  
            )
        ), 
        4 /* the fourth arg */
    )
);

Glue() 

Glue is the name of the function that holds a sequence of statements together.  Glue's first argument is the first statement, etc.

Arg(
    Arg(
        Expr(
            For( iCat = 1, iCat <= 10, iCat++,  
               halfCats = halfCats / 2;  
               Write( iCat, " ", halfCats, "\!n" );  
            )
        ), 
        4 /* the fourth arg is two statements, glued together */
    ), 
    1 /* the first arg is the first of the two glued statements */
);

halfCats = halfCats / 2

A JSL list is the same sort of expression:

list={33,44,55};
show(head(list));
show(narg(list));
show(arg(list,3));

Head(list) = {};  list displays curly brackets for the head, rather than a name like Assign

N Arg(list) = 3;

Arg(list, 3) = 55;

If you just want the contents of the list, you should use normal subscripting:

show(list[3]);

list[3] = 55;

But sometimes you want to do something like turning a list into arguments to a function.

In the Elephant post you'll find an example of turning a list into a pattern (line 5). I'm having a hard time coming up with another example as cool as that one, but suppose you wanted to check if the list was in alphabetical order. JMP's < operator can do that in a single function call:

LT = expr("a"<"b"<"c"<"d");
show(head(LT));
show(narg(LT));

Head(LT) = Less();  the less-than operator displays a function name, Less

N Arg(LT) = 4;

The Less function can take a lot of arguments, but you don't have to type them. Below, NameExpr is retrieving the expresion stored in words, after the SubstituteInto modified the { list } to be Less(). JMP then displays the Less function using < to make it more readable. 

words =
{"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India",
"Juliet", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo",
"Sierra", "Tango", "Uniform", "Victor", "Whiskey", "Xray", "Yankee", "Zulu"};
Substitute Into( words, Expr( {} ), Expr( Less() ) );
nameExpr(words);

"Alpha" < "Bravo" < "Charlie" < "Delta" < "Echo" < "Foxtrot" < "Golf" < "Hotel" <

"India" < "Juliet" < "Kilo" < "Lima" < "Mike" < "November" < "Oscar" < "Papa" <

"Quebec" < "Romeo" < "Sierra" < "Tango" < "Uniform" < "Victor" < "Whiskey" < "Xray" < "Yankee" < "Zulu"

eval(words)

eval(words) returns 1, indicating the result of Less was true.

Another example.

Update 28Feb2017 - repair formatting for new community

Last Modified: Feb 28, 2017 1:20 PM
Comments