Of course, all terms can't be computed, so we have to limit the numbers of terms to add.

To add the first n terms of S = sum(1/(k^2)), we can write :

- Code: Select all
`: sumZ(n) { 0 n seq apply(#[ sq inv + ]) }`

- 0 is pushed on the stack. This will be used to accumulate the sum.

- n seq creates (and pushes) a sequence of integers from 1 to n. A sequence is a collection

- #apply will apply something on each element of a collection ie push an element on the stack, then push "something" then call perform.

- Here, we apply a block, an object that implement an anonymous function. When a block is performed, code into the block is performed.

- So, for each element of the sequence, we perform "sq inv +", which accumulates the sum we are computing.

>sumZ(1000) .s

[1] (Float) 1.64393456668156

This approximates series sum value when all terms are added, which is : Pi^2 / 6

>Pi sq 6 / .s

[1] (Float) 1.64493406684823

[2] (Float) 1.64393456668156

ok

>

But it would be cool to have a function that calculates the sum of a serie that is sent as a parameter.

Blocks can do this because if a block uses a parameter, it becomes a closure :

- Code: Select all
`: sumSerie(s, n) { 0 n seq apply(#[ s perform + ]) }`

Here, the serie is sent as parameter and the block uses s.

Now, if we want to calculate our serie (1/(k^2)), we can send it as a parameter :

>sumSerie(#[ sq inv ], 1000) .s

[1] (Float) 1.64393456668156

If we want to appromimate the sum of serie T = sum(1/(k^4)), which value is Pi^4 / 90,

>sumSerie(#[ sq sq inv ], 1000) .s

[1] (Float) 1.08232323337831

Franck