J中隐性编程的优缺点

use*_*733 5 explicit implicit j tacit-programming

作为JI的初学者,我常常遇到隐性程序,与更熟悉的显式形式相比,它们看起来相当拜占庭.

现在只是因为我发现解释困难并不意味着默会形式是错误的或错误的.通常,默认形式比显式形式短得多,因此更容易在视觉上同时看到所有形式.

专家提问:这些隐性形式是否表达了更好的结构感,并可能提炼出潜在的计算机制?还有其他好处吗?

我希望答案是肯定的,对于一些非平凡的例子也是如此......

alg*_*ark 7

默认编程通常更快,更有效,因为你可以告诉J你想要做什么,而不是让它在你的句子中找到它.但是,作为一个喜欢默契编程的人,我还可以说隐性编程鼓励你以J方式思考问题.

破坏结局并回答你的问题:是的,隐性编程可以并确实传达有关结构的信息.从技术上讲,它强调的意义高于一切,但许多在你将遇到的不那么平凡的表达中突出显示的运算符(@: & &. ^:仅举几例)具有非常与结构相关的含义.

编写隐性代码所付出代价的典型例子是模幂运算的特殊代码,同时保证还有更多类似的快捷方式:

   ts =: 6!:2, 7!:2@]  NB. time and space
   100 ts '2 (1e6&| @ ^) 8888x'
2.3356e_5 16640
   100 ts '1e6 | 2 ^ 8888x'
0.00787232 8.496e6
Run Code Online (Sandbox Code Playgroud)

您将听到的另一个主要内容是,当J看到一个明确的定义时,它必须在每次应用它时解析并评估它:

   NB. use rank 0 to apply the verb a large number of times
   100 ts 'i (4 : ''x + y + x * y'')"0 i=.i.100 100'  NB. naive
0.0136254 404096
   100 ts 'i (+ + *)"0 i=.i.100 100'                  NB. tacit
0.00271868 265728
   NB. J is spending the time difference reinterpreting the definition each time
   100 ts 'i (4 : ''x (+ + *) y'')"0 i=.i.100 100'
0.0136336 273024
Run Code Online (Sandbox Code Playgroud)

但是这两个原因都让人认为J有一种非常独特的解决问题的方式.没有,如果,有^:.没有循环,有排名.同样,肯在美学看到了这样一个事实:在微积分中,f + g是函数的逐点和 - 实际上,人们将f + g定义为函数,其中(f + g)(x)= f(x)+ g( x) - 因为J在逐点数组中已经很好了,为什么要停在那里呢?

正如像Haskell这样的语言将高阶函数组合在一起而不是"手动"端到端地同步它们的乐趣,J也是如此.从语义上讲,请看下面的例子:

  • h =: 3 : '(f y) + g y'- h是一个抓住其参数的函数y,将其插入f并将g结果汇总为一个总和.
  • h =: f + g- h是函数f和的总和g.
  • (A < B) +. (A = B) - "A小于B或A等于B."
  • A (< +. =) B - "A小于或等于B."

这是更多的代数.到目前为止我只谈过火车; 关于像^:或的工具的便利性有很多话要说&..但是,这一课程相当清楚:J希望能够以代数方式轻松地讨论您的函数.如果你不得不将你的所有行动都包裹在一个3 :''4 :''更糟糕的地方,那就把它们命名为另一条线! - 每当你想要有趣地应用它们时(比如via /^:or ;.),你可能会非常关注J.

当然,我承认你很难找到像这些一样优雅的例子,因为你的表达变得更加复杂.默许风格只需要一些人习惯.词汇必须熟悉(如果不是第二天性)给你,即使这样,有时候你也有可能通过简单不可原谅的代码.任何语言都可能发生这种情况.


bob*_*bob 3

虽然不是专家,但对我来说,默认编码的最大积极方面是 1)它使编写程序的程序变得更容易一些,2)对我来说更容易掌握解决问题的 J 方法(这就是为什么喜欢用 J 编程的一个重要原因)。显式感觉更像是过程式编程,特别是当我使用诸如if.,while.或 之类的控制字时select.

挑战在于 1) 显式代码有时比隐式代码运行得更快,但这取决于任务和算法,2) 隐式代码在解析时会被解释,这意味着有时显式代码更干净,因为您可以让代码等待仅在运行时定义的变量值。