[英]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-2
和n-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.