Task

Provide code that produces a list of numbers which is the   nth  order forward difference, given a non-negative integer (specifying the order) and a list of numbers.



The first-order forward difference of a list of numbers   A   is a new list   B,   where   Bn = An+1 - An.

List   B   should have one fewer element as a result.

The second-order forward difference of   A   will be:

tdefmodule Diff do
	def forward(arr,i\\1) do
		forward(arr,[],i)
	end

	def forward([_|[]],diffs,i) do
		if i == 1 do
			IO.inspect diffs
		else 
			forward(diffs,[],i-1)
		end
	end

	def forward([val1|[val2|vals]],diffs,i) do
		forward([val2|vals],diffs++[val2-val1],i) 
	end
end 

The same as the first-order forward difference of   B.

That new list will have two fewer elements than   A   and one less than   B.

The goal of this task is to repeat this process up to the desired order.

For a more formal description, see the related   Mathworld article.



Algorithmic options

 Iterate through all previous forward differences and re-calculate a new array each time.
 Use this formula (from Wikipedia):


 




Δ

n


[
f
]
(
x
)
=

∑

k
=
0


n





(


n
k


)



(
−
1

)

n
−
k


f
(
x
+
k
)


{\displaystyle \Delta ^{n}[f](x)=\sum _{k=0}^{n}{n \choose k}(-1)^{n-k}f(x+k)}




 (Pascal's Triangle   may be useful for this option.)


/*REXX program  computes the   forward difference   of a  list of numbers.              */
numeric digits 100                               /*ensure enough accuracy (decimal digs)*/
parse arg e ',' N                                /*get a list:  ε1 ε2 ε3 ε4 ··· , order */
if e==''  then e=90 47 58 29 22 32 55 5 55 73    /*Not specified?  Then use the default.*/
#=words(e)                                       /*#  is the number of elements in list.*/
                                                 /* [↓]  assign list numbers to @ array.*/
   do i=1  for #;  @.i=word(e, i)/1;  end /*i*/  /*process each number one at a time.   */
                                                 /* [↓]  process the optional order.    */
if N==''  then parse value 0 # # with bot top N  /*define the default  order  range.    */
          else parse var N bot 1 top             /*Not specified?  Then use only 1 order*/
say right(#  'numbers:', 44)  e                  /*display the header title   and  ···  */
say left('', 44)copies('─', length(e)+2)         /*   "     "     "   fence.            */
                                                 /* [↓]  where da rubber meets da road. */
      do o=bot  to top;        do r=1  for #;  !.r=@.r;     end /*r*/;        $=
        do j=1  for o; d=!.j;  do k=j+1  to #; parse value !.k !.k-d with d !.k; end /*k*/
        end   /*j*/
                               do i=o+1  to #; $=$ !.i/1;   end /*i*/
      if $==''  then $=' [null]'
      say right(o, 7)th(o)'─order forward difference vector ='     $
      end     /*o*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
th: procedure; x=abs(arg(1)); return word('th st nd rd',1+x//10*(x//100%10\==1)*(x//10<4))