如果给出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行为效用的明显信息。
答案 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