将字符串评估为 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
如果您愿意,您也可以尝试 monad
或 dyad
,例如
2 (dyad def 'x * + % y') 5
0.4
或者要制作火车,请将 str
括在括号中:
2 (dyad def 'x (* + %) y') 5
10.4
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"):
'@'
一起使用
'@' ,.~ > ;: str
+ @
>:@
% @
将其展平会产生:
+ @>:@% @
最后,用 }:
砍掉尾随的 @
会得到 + @>:@%
,这是我想要的更丑陋的版本,+ @ >: @ %
.
现在,一切都很好,除了一件事:它是一个字符串。差不多好了!但不完全是。我心想,"Oh! ".
would be perfect for this, it's basically eval." 令我沮丧的是,文档是这样读的(emph mine):
".y
executes the sentencey
. 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
如果您愿意,您也可以尝试 monad
或 dyad
,例如
2 (dyad def 'x * + % y') 5
0.4
或者要制作火车,请将 str
括在括号中:
2 (dyad def 'x (* + %) y') 5
10.4