什么时候#:给出比#。^:_ 1更理想的行为

时间:2014-05-14 17:38:39

标签: j

如果给出Base(#.^:_1)的反转列表作为左参数,它将产生与Antibase(#:)相同的结果:

   24 60 (#.^:_1) 123456
17 36
   24 60 (#:) 123456
17 36

如果您给Antibase(#:)一个左参数,它会重复残留(|),而不是Base(#.^:_1)的反转:

   8 #: 1234
2
   8 | 1234
2
   8 (#.^:_1) 1234
2 3 2 2

在什么情况下Antibase的行为优于倒置基座?为什么你不会在那些地方使用残留物?我觉得我必须遗漏一些关于Antibase行为效用的明显信息。

1 个答案:

答案 0 :(得分:5)

首先: J字典将#.^:_1定义为等同于#: ,因此它们(大多数)可以互换并不奇怪。特别是the Vocabulary page for #: says

  

r&#:与r&#。相反。“

这种理论上的等同性也得到了实践的支持。如果您要求使用超酷的副词#.^:_1来实现J的定义b.,那么您将获得:

   24 60 60&#. b._1
24 60 60&#:

在这里,我们可以看到所有#.^:_1正在做的是推迟到#:。它们被定义为等价,现在我们可以看到#.^:_1 - 至少在非标量LHA¹的情况下 - 只是将其参数传递给{{1 }}

那么我们如何解释你观察到的差异呢?事实证明,即使在J的纯粹大厅里,理论也与实践不同。对偶#:#:之间存在不一致,至少在标量左参数的情况下,后者的行为优于前者。

我愿意(和have)认为这种差异是一个错误:上面引用的词典表明两个对偶是等价的,但当{{1}时,该断言是错误的#.^:_1是一个标量)。以0-:#$r为例:r不成立。也就是说,如果Dictionary的断言(上面引用)为true,那么该语句应返回r=.2(true),但它实际返回(r&#: -: r&#.^:_1) 1 2 3(false)。

但是,正如您所指出的,它是一个有用的错误。也就是说:我希望将1的定义更改为匹配0,而不是反之亦然。但那只是 时间#:#.^:_1更方便。在所有其他情况下,它们是等价的,并且因为#.^:_1是基元而#:是具有尾随#:的复合短语,所以前者更方便。

例如,当您的右手参数是数字文字时,很容易将其无意中附加到#.^:_1中的_1,就像在_1中一样,这会引发错误(因为#.^:_1作为一个单词而被作为一个单词,因此作为一个整体,被视为2 2 2 2 #.^:_1 15 7 4 5的参数。有一些方法可以解决这个问题,但没有一种方法可以像使用_1 15 7 4 5一样方便或简单。

你可以做出反驳,在大多数情况下,LHA将是一个标量。这是一个经验论证,从代码库到代码库会有所不同,但我个人看到很多像^:这样的情况,我试图将时间戳分解为持续时间桶(小时,分钟,秒)或{ {1}},我正在尝试将字节分解为完全 8位向量(与例如#:形成对比),这会将字节分成尽可能多的位,无论是这是8或3或17¹)。而且我进一步认为,在J社区中,这些都是常用的和即时可识别的习语,因此24 60 60 #: ...的使用有助于清晰和团队沟通。

但是,尽管存在错误,最终(8#2)#: ...8 #.^:_1 ... 被定义为等同,因此您使用的是真正的品味问题。 (那么为什么要定义#:,你问?嗯,这是一个whole 'nother story。)


¹PS:想看到一些很酷的东西吗? #:如何实现标量LHA的魔力?我们问问J!

#.^:_1

首先,请注意(到现在为止)使用#.^:_1完全不足为奇。所有#.^:_1正在计算 2&#. b._1 ($&2@>:@(2&(<.@^.))@(1&>.)@(>./)@:|@, #: ]) :.(2&#.) 的适当LHA。

其次,短语#:向您展示J如何计算在基数(或基数)x中表示y(最大值)所需的位数。它本身就是一个有用的短语,以至于我在我的个人实用程序库中保留了它的一个版本:

#.^:_1