从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
我想系统地将参数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
使用我的示例随意说明,但我希望能够遵循任意表达式的过程。
编辑:我刚刚发现使用x和y的引用版本可以使用例如自动转换为默认形式。 13 : '>:?x#y'
。如果有人可以告诉我如何找到13 :
的定义,我可以回答我自己的问题。
答案 0 :(得分:5)
如果您的目标是学习默会风格,那么您只需从头开始学习而不是尝试记住明确的算法,那就更好了 - J4C和Learning J是很好的资源 - 因为将表达式从显式转换为默认的一般情况是难以处理的。
甚至忽略了自J4以来没有默认连词的事实,在动词的明确定义中你可以(1)使用control words,(2)使用和修改全局变量,(3)将包含x
和/或y
的表达式作为副词或连词的操作数,以及(4)引用自身。解决(1),(3)或(4)在一般情况下非常困难,(2)只是不可能。*
如果你的J语句是一小类表达式之一,有一种简单的方法可以应用fork规则使其默认,这或多或少是在{{ {1}}。回想一下
13 :
为(F G H) y
,(F y) G (H y)
为x (F G H) y
( Monad / Dyad Fork )(x F y) G (x H y)
为([: G H) y
,G (H y)
为x ([: G H) y
( Monad / Dyad Capped Fork )G (x H y)
为x [ y
,x
为x ] y
,y
和[ y
均为] y
(左/右)注意叉子如何使用他们的中心动词作为最外面的&#39;动词: Fork 给出y
的二元应用,而 Capped Fork 给出一个monadic应用。这完全对应于J,monadic和dyadic中动词的两种应用模式。因此,一种快速而肮脏的算法可以让人默默无闻地进行调整。对于g
动词和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
格式,此时您将获胜。可以为&#34; monadic表达式&#34;导出类似的算法,表达式仅依赖于x F y
。这是一个样本推导。
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
是一段奇数长度的列车,那么Train
等同于(F G (Train))
- 或(F G Train)
的观察}和x ([ F ]) y
是等价的。在学习规则之后,不应该修改算法以获得结果x F y
,这是[: <. [ %~ ] - |
给出的结果。
只要包含13 : '<. (y - x | y) % x'
和/或x
的表达式是副词或连词的操作数,就会获得失败条件。有时可以通过一些深度重构来恢复隐性形式,以及y
和^:
的动词和动态形式的知识,但我怀疑这是否可以通过编程方式完成。
这使得(1),(3)和(4)变硬而不是不可能。鉴于}
如何运作的知识,一个默认的程序员可以找到一个默认的形式,比如说Ackermann function没有太多的麻烦,一个聪明的人甚至可以为了效率而重构它。如果你能找到一个算法,你就可以避免程序员,期间。
$:
*这是一种谎言。你可以通过一些先进的巫术魔法来重构涉及这种动词的整个程序,参见Pepe Quintana's talk 2012 J Conference。它不漂亮。
答案 1 :(得分:3)
13 :
记录在:
或x
下[
(明确)。
基本的想法是,您想要成为y
的值变为]
,而您希望成为[
的值变为]
。但是,一旦最右边的标记从名词(值)变为动词如[:
或@
,整个语句就会成为一个列,你可能需要使用动词{{1} }或连词@:
或x
来恢复之前的构图行为。
您还可以使用实际名称y
和(dyad : ' ... ')
替换值,然后将整个内容包装在(>:?10#6 NB. Roll ten six sided dice.
)中。那就是:
10 (dyad : '>: ? x # y') 6 NB. dyad is predefined. It's just 4.
可以成为:
y
如果您只需要monad
参数,则可以使用预先定义为3
的{{1}}。名称verb
也是3
。当我提供monadic和dyadic版本时,我倾向于使用verb :
,而当我只需要monadic含义时,我倾向于使用monad
。
如果您的动词是这样的单行词,您可以有时将其自动转换为默认形式,方法是将3
或4
替换为13
。
我有一些vocabulary可以帮助您逐步进行转换。
附录:用于将语句转换为默认dyad的伪代码
这仅涵盖单个语句(一行代码),如果您尝试提取的常量值被传递给连词或副词,则可能无效。
此外,声明不得引用其他变量。
[ x=. xVal [ y =. yVal
附加到声明中。xVal
和yVal
的适当值。x
和y
重写原始表达。statement [ x=. xVal [ y=. yVal
重写为:newVerb =: (4 : 0)
statement ] y NB. we'll fill in x later.
)
(xVal) newVerb yVal
现在,您有x
和y
的明确定义。将它放在多行而不是使用x (4 : 'expr') y
的原因是,如果expr
仍包含字符串文字,则必须摆脱单引号的转义。
转换第一个名词
由于之前只有一个管道,statement
内最右边的表达式必须是名词。使用以下规则将其转换为fork:
y
→(])
x
→]x ([)
_
,__
,_9
... 9
→(_:)
,(__:)
,(_9:)
... { {1}} (9:)
→n
(任何其他任意名词)这使整体含义保持不变,因为您刚刚创建的动词会立即被调用并应用于n"_
。
无论如何,括号中的这个新的默认动词将成为你将要建立的火车的核心。从现在开始,你通过在语句中使用最右边的表达式,并在括号内移动它来工作。
分叉正常表格
从现在开始,我们将假设我们创造的默认动词始终是一个分叉。
这个新的默认动词实际上并不是一个分支,但我们会假装它,因为任何单一标记动词都可以使用规则重写为分叉:
[ y
没有理由实际进行这种转换,只是为了简化下面的规则,并将其称为分叉。
我们不会使用钩子,因为任何钩子都可以用规则重写为叉子:
(u v)→(] u [:v])
以下规则应自动生成此表格中的列车。
转换剩余的令牌
现在我们可以使用以下规则转换原始管道的其余部分,一次将一个项目移动到fork中。
对于所有这些规则,v → ([: ] v).
不是J语法。这意味着(]x)?
可能存在也可能不存在。您无法将]x
放入,直到转换] x
的用法,而不会更改代码的含义。转换x
的实例后,x
是必需的。
遵循J约定,]x
和u
代表任意动词,v
是任意名词。请注意,这些包括动词
n
副词或连词没有规则,因为你应该把它们视为动词的一部分。例如,tokens y u (]x)? (fork) ] y → tokens (]x)? (] u fork) ] y
tokens x u (]x)? (fork) ] y → tokens ]x ([ u fork) ] y
tokens n u (]x)? (fork) ] y → tokens (]x)? (n u fork) ] y
tokens u v (]x)? (fork) ] y → tokens u (]x)? ([: v fork) ] y
应被视为单个动词。同样,括号中的任何内容都应该单独留作一个短语。
无论如何,继续应用这些规则,直到用完代币为止。
<强>清理强>
你最终应该:
+:^:3
这可以改写为:
newVerb =: (4 : 0)
] x (fork) ] y
)
(xVal) newVerb yVal
你已经完成了。