将字符串评估为 J 中的动词

Evaluate a string as a verb in J

TL;DR

给定一个包含(有效)动词的字符串,我如何在不将其提交给任何变量的情况下获取该动词?例如,说 eval 是那个函数;它应该像这样工作:

   eval '+ @ >: @ %'
+@>:@%
   eval '+'
+

我只需要它能够执行动词和 return 它们,但是如果能对任意代码进行评估会很酷。 (我确实知道 ".,顺便说一句。)


作为一个有趣的小实验,我想 "hey, maybe I can make a verb that will transform a string of verbs into a train of verbs!" 我知道我可以使用 ;: 将字符串 "word-ify" 转换成 J-verbs,就像这样:

   ]str =: '+ >: %'
+ >: %
   ;: str
┌─┬──┬─┐
│+│>:│%│
└─┴──┴─┘

到目前为止,还不错。现在,我将通过使用 ,. ("ravel items"):

将 "join" 与 '@' 一起使用
   '@' ,.~ > ;: str
+ @
>:@
% @

将其展平会产生:

+ @>:@% @

最后,用 }: 砍掉尾随的 @ 会得到 + @>:@%,这是我想要的更丑陋的版本,+ @ >: @ %.

现在,一切都很好,除了一件事:它是一个字符串。差不多好了!但不完全是。我心想,"Oh! ". would be perfect for this, it's basically eval." 令我沮丧的是,文档是这样读的(emph mine):

".y executes the sentence y. If the execution results in a noun, the result of ".y is that noun; if the execution result is a verb, adverb, or conjunction, or if there is no execution result, the result of ".y is an empty vector.

好吧,该死的。那行不通的。我当然可以通过在字符串中定义一个动词来破解它:

]verb =: , }: , '@' ,.~ > ;: str
+ @>:@% 
   'ret =: ' , verb
ret =: + @>:@% 
   ". 'ret =: ' , verb
   ret
+@>:@%

这一切都很好,但相当笨拙,尤其是对 J 而言。用这个 is 动词可以稍微缓和打击:

   is =: ".@(,&'=:'@,@[,}:@,@('@',.~>@;:)@])
   'G' is '+>:%'
   G
+@>:@%
   G 5
1.2

但只有当您愿意将函数提交给变量时才有效。

所以,我的问题是:如何将包含动词的通用字符串转换为可用动词?

Evoke gerund (`:) 就是你想要的。请参阅 this short documentation 以获取很好的示例。在你的情况下:

   str=: '+ @ >: @ %'
   (;: str) `:6
+@>:@%

您可能需要查看 Tie (`) 以了解这一点。 ;: returns 在我们的案例中是动名词(原子表示),m `: 6 将动名词 m 转换为动词序列。

或者

   str =: '+ >: %'
   g =: verb def (str,' y')
   g 5
1.2

如果您愿意,您也可以尝试 monaddyad,例如

    2 (dyad def 'x * + % y') 5
0.4

或者要制作火车,请将 str 括在括号中:

   2 (dyad def 'x (* + %) y') 5
10.4