将副词应用于动名词列表

Applying an adverb to a list of gerunds

考虑一个动名词列表和一些我们希望循环应用它们的数据:

ms=.*`+`-     NB. list of gerunds
d =.3 4 5 6   NB. some data

我们可以做到:

ms/ d    NB. returns 9, ie, the result of 3 * 4 + 5 - 6

现在我们提出问题:如果我们改变应用动词的顺序,结果会发生什么变化?也就是说,我们考虑所有 6 种可能的顺序:

allms=. (A.~i.@!@#) ms

看起来像:

┌─┬─┬─┐
│*│+│-│
├─┼─┼─┤
│*│-│+│
├─┼─┼─┤
│+│*│-│
├─┼─┼─┤
│+│-│*│
├─┼─┼─┤
│-│*│+│
├─┼─┼─┤
│-│+│*│
└─┴─┴─┘

要回答这个问题,我们可以这样做:

allms (4 : 'x/ y')"1 d

NB. returns 9 _21 _1 _23 _41 _31

但是请注意,我被迫使用匿名的、非默认的 动词来完成此操作。因为为了应用副词 /,我必须有一个 命名的动词 。当我真正想做的是将 / 视为 1 级动词并 "map" 它在我的列表 allms 上时, 在精神上 就像非法公式:

/&d"1 allms  NB. This is invalid J

即,对于列表中的每个动名词,用副词/进行转换,并将其应用于数据d

J似乎很抗拒这种高阶的"treating verbs like data"思维。所以我想知道解决这个问题的自然 J 方法是什么。

具体来说,您将获得如上定义的动名词列表 ms 和数据 d。任务是创建一个 returns 结果列表 ms/ d 的动词,用于 ms 的每个可能排序(即 returns 9 _21 _1 _23 _41 _31在我们的例子中)。动词必须是 默示动词

ms=.*`+`-     NB. list of gerunds
d =.3 4 5 6   NB. some data
allms=. (A.~i.@!@#) ms

我首先 "treating my verbs like data" 使用字符串来表示动名词

*`+`-

附加 '/' 字符,然后使用 128!:2(应用),它将描述动词的字符串作为其左参数,并将其应用于作为其右参数的名词。当然,要做到这一点,您需要将 allms 变成动词串。

可以使用:

   [ ger=. ,&'/' @ }: @ (1j1 #!.'`' ;)"1 allms
*`+`-/
*`-`+/
+`*`-/
+`-`*/
-`*`+/
-`+`*/

然后使用128!:2(应用)

   ger  128!:2 d
9 _21 _1 _23 _41 _31

作为一行默认动词

   gvt=. ,&'/'@ }:@(1j1 #!.'`' ;)"1 @: [ 128!: 2 ] 
   allms gvt d
9 _21 _1 _23 _41 _31

我很少玩这些游戏,所以我并不是说这是最好的方法,但它确实有效。

你真的不想要那个

有一些基本的句法原因可以解释为什么您不能默契地对运算符(副词和连词)的参数进行切片和切块。

无需详细说明,允许运算符被其他运算符修改,就像您提议的 /"1 修改一样,需要对 J 的语法进行根本性的重组。并且会有重大的权衡,特别是在简单性和表现力(即符号优雅)¹²。

因此,如果您想要像这样在动名词上分配运算符,您将必须为其编写实用程序,目前最直接的方法是使用显式代码。在此域中要考虑的一个预打包实用程序是 doog script, available in the J Wiki and SVN repo.

反正就在这里

但是,doog 脚本和您的方法一样,基本上是明确的³。 所以如果你真的想默契地达到这些目的:

   D       =.   foo`bar`baz 
   t       =.   D / (@:])  NB. Here's our "over" (/)

   over    =.  [^:(D -: ]) L: (L.D) & (5!:1<,'t')
   allOver =:  (]^:[~ 1:`'' , over f.)~


   3 4 5 6 allOver"1~ (A.~i.@!@#) *`+`-       NB. Note the "1
9 _21 _1 _23 _41 _31

我警告过你

无需过多赘述,这里的技巧是使用动词 ]^:[ 允许 ^: 执行任意原子表示作为输入。

也就是说,some_atomic_rep f^:[ data 变成 f^:some_atomic_rep data,对于合适的原子表示,它可以执行任何操作,同时使用动词可用的所有参数处理优点(特别是,排名)。

剩下的只是一种优雅的(读作:懒惰的)方式,可以将你的动名词输入(无论你为具有等级或其他参数选择机制的动词提供哪些部分)转换为适合右手的原子表示^: 的参数。

它的核心是我们有模板 D / (@:]) 并且我们将 D 替换为您选择的动名词(@:] 是必要的,因为当动名词被执行时,它将有两个输入:您的实际输入,d,以及它本身,D)4.

Lasciate ogne speranza

要访问这些邪恶愚蠢的 Ultima Thule,请查看 dont in J 的发现,它就像 do (".),除了......真的,你不应该。


¹ 举个简单的例子:弄清楚这对词类之间的优先级意味着什么。

² 话虽如此,Jose "Pepe" Quintana,地下J俱乐部F^4的领袖(The Fully Fixable Functional Faction), once found a backdoor that actually did allow operators to take other operators as inputs. See this message in the "J Myths Puzzles" thread from 2008(滚过所有剧透-隐藏空行。当然,他一提,罗杰就注意到了,立马把缺口堵上了。

³ I once put it 的方式是 "Yes, dcog is ugly, but I like to think of it as Messiah Code: it's ugly so that other code doesn't have to be. A sponge for sin"。

4 请注意,模板动名词 foo`bar`baz 可以是任何你喜欢的东西,任何长度,使用任何名称。没关系。重要的是您使用的名称是谚语或未定义的(解释器按设计将其视为谚语)。使用代词或亲运营商会破坏东西。或者,您可以使用另一种名词,例如 __ 或其他名词(我发现 的助记符填入 ____)。