从J表达式系统地提取名词参数

时间:2015-03-06 23:58:19

标签: 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

我想系统地将参数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 :的定义,我可以回答我自己的问题。

2 个答案:

答案 0 :(得分:5)

如果您的目标是学习默会风格,那么您只需从头开始学习而不是尝试记住明确的算法,那就更好了 - J4CLearning 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) yG (H y)x ([: G H) y Monad / Dyad Capped Fork
  • G (x H y)x [ yxx ] yy[ y均为] y左/右

注意叉子如何使用他们的中心动词作为最外面的&#39;动词: Fork 给出y的二元应用,而 Capped Fork 给出一个monadic应用。这完全对应于J,monadic和dyadic中动词的两种应用模式。因此,一种快速而肮脏的算法可以让人默默无闻地进行调整。对于g动词和F G H名词:

,表达式可能如下所示
  1. N替换为x,将(x [ y)替换为y。 (左/右
  2. 将任何其他名词(x ] y)替换为n
  3. 如果您看到模式(x N"_ y),请将其替换为(x F y) G (x H y)。 (
  4. 如果您看到模式x (F G H) y,请将其替换为G (x H y)。 (*加盖的叉子()
  5. 重复1到4,直到您获得x ([: G H) y格式,此时您将获胜。
  6. 如果不能再进行简化而你还没有获胜,那就输了。
  7. 可以为&#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

如果您的动词是这样的单行词,您可以有时将其自动转换为默认形式,方法是将34替换为13

我有一些vocabulary可以帮助您逐步进行转换。

附录:用于将语句转换为默认dyad的伪代码

这仅涵盖单个语句(一行代码),如果您尝试提取的常量值被传递给连词或副词,则可能无效。

此外,声明不得引用其他变量。

  • [ x=. xVal [ y =. yVal附加到声明中。
  • 替换xValyVal的适当值。
  • 根据新xy重写原始表达。
  • statement [ x=. xVal [ y=. yVal重写为:

newVerb =: (4 : 0)
  statement ] y   NB. we'll fill in x later.
)
(xVal) newVerb yVal

现在,您有xy的明确定义。将它放在多行而不是使用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约定,]xu代表任意动词,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

你已经完成了。