简体   繁体   English

在J中创建递归默认函数

[英]Creating a recursive tacit function in J

I'm a newcomer to J and I've been trying to create a Fibonacci function as an exercise (always the second function I create when learning a language). 我是J的新手,我一直在尝试创建一个Fibonacci函数作为练习(总是我学习语言时创建的第二个函数)。 I just can't figure out what exactly is wrong in my way of doing it. 我无法弄清楚我的做法究竟出了什么问题。 I have tried to define it as tacit, but it gets hung if argument is greater than one. 我试图将它定义为默认,但如果参数大于1则会挂起。

fib =: [ ` (($: (]-1)) + ($: (]-2))) @. (>&1)

I've also attempted to create it explicitly, and that worked fine. 我也试图明确地创建它,并且工作正常。

fib =: 3 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'

I tried to create a tacit out of that by replacing 3 with 13, but it threw an error. 我试图通过用13代替3来创建一个默认,但它引发了一个错误。

   fib =: 13 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
|spelling error
|   if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.
|   ^
|   fib=:    13 :'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'

So, I'm asking for someone to explain what exactly I am doing wrong here. 所以,我要求有人解释我在这里做错了什么。

Okay, I found it. 好的,我找到了。 I ran only the recursive block through tacit generator and got this block. 我只通过默认生成器运行递归块并得到了这个块。

   13 : '(f y-1) + (f y-2)'
([: f 1 -~ ]) + [: f 2 -~ ]

Then I inserted that to the original piece, getting this. 然后我把它插入原始的一块,得到这个。

fib =: [ ` (([: $: 1 -~ ]) + [: $: 2 -~ ]) @. (>&1)

And that works like a charm. 这就像一个魅力。 I also inserted " 0 to the end to make it accept lists. 我还插入" 0到最后使其接受列表。

Here's an alternative that I think is both clearer and more concise: 这是我认为更清晰,更简洁的替代方案:

fibn =: (-&2 +&$: -&1)^:(1&<) M."0

Compare with a more canonical (pseudocode) definition: 与更规范(伪代码)定义进行比较:

fib(n) = fib(n-1) + fib(n-2) if n > 2 else n

First, instead of using [ ` with @. (>&1) 首先,而不是使用[ ` with @. (>&1) @. (>&1) , which uses a gerund, it's better to use ^:(1&<) . @. (>&1) ,使用动名词,最好使用^:(1&<) For f(n) if cond(n) else n , using the ^: conjunction is more idiomatic; 对于f(n) if cond(n) else n ,使用^:连词更为惯用; ^:0 means "do nothing" and ^:1 means "do once," so the intent is clear. ^:0表示“什么都不做”, ^:1表示“做一次”,所以意图很清楚。 @. is better suited to nontrivial behavior. 更适合非平凡的行为。

Second, using the & bond/compose conjunction simplifies the train significantly. 其次,使用& bond / compose连接可以显着简化列车。 Repeated uses of [: and ] are rather confusing and opaque. 重复使用[:]是相当混乱和不透明的。 Refactoring using & puts together related operations: first, split n into two, namely n-2 and n-1 , and second, add together the fibn of those two numbers. 重构使用&汇总相关操作:首先,将n分成两个,即n-2n-1 ,然后将这两个数字的fibn加在一起。

And, lastly, "0 for list handling and M. for memoizing. M. is rather important from a performance perspective, as a straightforward implementation of the canonical definition will call fib(2) excessively. You can have your cake (a simple definition) and eat it too (good performance) with the built-in memoization adverb. 最后, "0用于列表处理, M.用于记忆M. 。从性能角度看是非常重要的,因为规范定义的直接实现会过度地调用fib(2) 。你可以拥有你的蛋糕(一个简单的定义)并使用内置的memoization副词来吃它(性能良好)。

Source for this particular definition: f0b on this page . 此特定定义的来源: 此页面上的f0b

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM