
JMP 的脚本语言 JSL 是通过函数调用构建的。 几乎所有可以用 JSL 编写的内容都是函数调用。 有些事情看起来不像函数调用:
A = A + 3;
很明显,赋值语句的右侧是一个表达式。 赋值语句本身是一个表达式不太明显。
E = expr ( A = A + 3 );
expr 是一个包装器,您可以在表达式周围使用它来防止表达式求值。 E 设置为表达式,而不是表达式的计算结果。 要查看 E,请使用 head 函数。 Head 将返回表达式根部的函数名称:
show( head(E) );
头(E)=分配();
现在您会看到有一个用于进行分配的函数:
Assign( testing, 3+4 );
7
show(testing)
测试 = 7;
JSL 中的表达式实际上是树。 这是 a=a+3 树的图片,根在顶部,叶子在底部:

与Head函数类似,我们可以使用Arg函数来访问Assign函数的子函数:
show( arg(E,1) );
精氨酸(E,1)= A;左侧
show( arg(E,2) );
精氨酸(E,2)= A + 3;右侧
并进一步挖掘,
show(head(arg(E,2)))
头(Arg(E,2))=添加();右侧的头部
show(arg(arg(E,2),1))
精氨酸(精氨酸(E,2),1)= A;加号的左侧
show(arg(arg(E,2),2))
精氨酸(精氨酸(E,2),2)= 3;加号的右侧
请注意括号嵌套如何描述树。 这棵树只有二叉树。 有一个功能,纳尔格,返回子代的数量。 对于叶节点,它返回 0。
narg(E)
2分配函数有两个参数,左侧和右侧
JMP的为了语句是一个函数调用,带有四个参数。 请注意分隔参数的逗号,就像任何其他函数一样。
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
需要三个逗号来分隔四个参数。 在这个为了语句,第四个参数是两个语句,用分号分隔。 查看第四个参数,看看它是否实际上也是一个函数:
Head(
Arg(
Expr(
For( iCat = 1, iCat <= 10, iCat++,
halfCats = halfCats / 2;
Write( iCat, " ", halfCats, "\!n" );
)
),
4 /* the fourth arg */
)
);
胶水()
胶水是将一系列语句组合在一起的函数的名称。胶水的第一个参数是第一个语句,等等。
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 */
);
半猫 = 半猫 / 2
JSL 列表是同一类型的表达式:
list={33,44,55};
show(head(list));
show(narg(list));
show(arg(list,3));
头(列表)= {};列表显示头部的大括号,而不是像这样的名称分配
N Arg(列表) = 3;
arg(列表, 3) = 55;
如果你只想要列表的内容,你应该使用普通的下标:
show(list[3]);
列表[3] = 55;
但有时您想做一些事情,例如将列表转换为函数的参数。
在里面大象在这篇文章中,您会发现一个将列表转换为模式的示例(第 5 行)。 我很难想出另一个像那个例子一样酷的例子,但假设你想检查列表是否按字母顺序排列。 JMP 的 < 运算符可以在单个函数调用中完成此操作:
LT = expr("a"<"b"<"c"<"d");
show(head(LT));
show(narg(LT));
头(LT) = Less();小于运算符显示函数名称,较少的
N精氨酸(LT) = 4;
Less 函数可以接受很多参数,但您不必键入它们。 以下,名称表达式正在检索存储在单词中的表达式,之后代入修改了{列表} 成为较少的()。 然后,JMP 使用 < 显示 Less 函数,以使其更具可读性。
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);
“阿尔法” < “布拉沃” < “查理” < “德尔塔” < “回声” < “狐步舞” < “高尔夫” < “酒店” <
“印度” < “朱丽叶” < “基洛” < “利马” < “迈克” < “十一月” < “奥斯卡” < “爸爸” <
“魁北克”<“罗密欧”<“塞拉”<“探戈”<“制服”<“维克多”<“威士忌”<“X射线” <“洋基”<“祖鲁”
eval(words)
1评估(words) 返回 1,表明 Less 的结果为 true。
另一个例子。
2017 年 2 月 28 日更新 - 修复新社区的格式
克雷格,这篇文章对我不断探索如何处理表达式非常有帮助。
实际上,我对您的最后一个技巧有一个很好的应用,您可以将列表中的项目转换为 Less() 函数的参数。 我想根据对话框窗口中的用户输入生成包含 Col Mean() 函数的列公式。 Col Means() 函数接受一个或多个参数,而我从来没有一种巧妙的方法将不同数量的参数(通常是变量名)替换到函数中。 以下是我的脚本中的关键行:
arglist = {"身高", "年龄", "性别"}; // 来自对话框窗口的结果
statformula = Substitute ( arglist, Expr( {} ), Expr( Col Mean() ) ); // arglist 中的项目成为 Col Means() 函数中的参数
newcol << 公式( 名称 Expr( statformula ) );
实际的脚本更复杂,因为它需要处理需要 Name(" ") 的混乱列名称,但您明白了。 感谢您向我展示了这个巧妙的技巧。
霍华德·劳奇