duk*_*reg 2 refactoring j tacit-programming
从J中的表达式中提取名词作为参数的系统方法是什么?要清楚,包含两个文字的表达式应该成为一个二元表达式,使用左右参数而不是文字.
我正在尝试学习默认风格,所以如果可以避免,我不想使用命名变量.
一个具体的例子是我制作的简单模具辊模拟器:
>:?10#6 NB. Roll ten six sided dice.
2 2 6 5 3 6 4 5 4 3
>:?10#6
2 1 2 4 3 1 3 1 5 4
Run Code Online (Sandbox Code Playgroud)
我想系统地将参数10和6提取到表达式的外部,以便它可以滚动任意数量的任何大小的骰子:
d =. <new expression here>
10 d 6 NB. Roll ten six sided dice.
1 6 4 6 6 1 5 2 3 4
3 d 100 NB. Roll three one hundred sided dice.
7 27 74
Run Code Online (Sandbox Code Playgroud)
随意使用我的示例来说明,但我希望能够遵循任意表达式的过程.
编辑:我刚刚发现使用x和y的引用版本可以使用eg自动转换为默认形式13 : '>:?x#y'
.如果有人可以告诉我如何找到13 :
我可能能够回答我自己的问题的定义.
如果你的目标是学习默会风格,那么你最好从头开始学习它而不是试图记住一个明确的算法 - J4C和学习J是很好的资源 - 因为将表达式从显式转换为默认的一般情况是棘手的.
甚至忽略了自J4以来没有默认连词的事实,在动词的明确定义中你可以(1)使用控制词,(2)使用和修改全局变量,(3)将表达式包含x
和/或y
作为副词或连词的操作数,以及(4)引用自身.在一般情况下解决(1),(3)或(4)是非常困难的,并且(2)只是平坦无法实现.*
如果你的J语句是一小类表达式之一,有一种简单的方法可以应用fork规则使其默认,这或多或少是实现的13 :
.回想起那个
(F G H) y
是(F y) G (H y)
,x (F G H) y
是(x F y) G (x H y)
(Monad/Dyad Fork)([: G H) y
是的G (H y)
,x ([: G H) y
是G (x H y)
(Monad/Dyad Capped Fork)x [ y
是x
,x ] y
是y
,两者的[ y
和] y
是y
(左/右)注意forks如何使用他们的中心动词作为"最外层"动词:Fork给出了二元应用g
,而Capped Fork给出了一个monadic 动词.这完全对应于J,monadic和dyadic中动词的两种应用模式.因此,对于F G H
动词和N
名词而言,一个快速而肮脏的算法,使隐性"二元"表达式可能如下所示:
x
用(x [ y)
和y
用(x ] y)
.(左/右)n
用(x N"_ y)
(x F y) G (x H y)
,请将其替换为x (F G H) y
.(叉)G (x H y)
,请将其替换为x ([: G H) y
.(*上限叉()x F y
,此时你获胜.可以为"monadic表达式"导出类似的算法,表达式仅依赖于y
.这是一个示例派生.
<. (y - x | y) % x NB. start
<. ((x ] y) - (x [ y) | (x ] y)) % (x [ y) NB. 1
<. ((x ] y) - (x ([ | ]) y)) % (x [ y) NB. 3
<. (x (] - ([ | ])) y) % (x [ y) NB. 3
<. x ((] - ([ | ])) % [) y NB. 3
x ([: <. ((] - ([ | ])) % [)) y NB. 4 and we win
Run Code Online (Sandbox Code Playgroud)
这忽略了一些明显的简化,但实现了目标.您可以混合使用各种其他规则来简化,例如长列车规则 - 如果Train
是奇数长度的列车然后(F G (Train))
是等效的(F G Train)
- 或者观察到x ([ F ]) y
并且x F y
是等效的.在学习规则之后,修改算法以获得结果应该不难[: <. [ %~ ] - |
,这就是13 : '<. (y - x | y) % x'
给出的结果.
只要表达式包含x
和/或是y
副词或连词的操作数,就会获得失败条件.它有时可以恢复默认的形式与一些深层次的重构,以及动词和动名词形式的知识^:
和}
,但我怀疑,这是可以编程方式.
这使得(1),(3)和(4)变硬而不是不可能.鉴于如何$:
运作的知识,一个默认的程序员可以找到一个默认的形式,比如阿克曼功能,而不会有太多的麻烦,聪明的人甚至可以重构效率.如果你能找到一个算法,你就可以避免程序员,句号.
ack1 =: (1 + ])`(([ - 1:) $: 1:)`(([ - 1:) $: [ $: ] - 1:)@.(, i. 0:)
ack2 =: $: ^: (<:@[`]`1:) ^: (0 < [) >:
3 (ack1, ack2) 3
61 61
TimeSpace =: 6!:2, 7!:2@] NB. iterations TimeSpace code
10 TimeSpace '3 ack1 8'
2.01708 853504
10 TimeSpace '3 ack2 8'
0.937484 10368
Run Code Online (Sandbox Code Playgroud)
*这是一种谎言.你可以通过一些先进的巫术魔法来重构涉及这种动词的整个程序,参见 Pepe Quintana在2012年J大会上的演讲.它不漂亮.