Pooh program example 18-higher-order-func.p

Test 18-higher-order-func.p

Source of programm

# Higher order functions fold/filter/map implemented as script functions.

sub foldleft2( array , func, initval )

   acc = initval

   i = size( ~arg array )
   while  i > 0
     acc = func( ~a array[ i ] ~b acc )
     i = i - 1
  end
  return acc
end

sub foldright2( array, func, initval )
    acc = initval
    i = 1
    while  i <= size( ~arg array )
      acc = func( ~a array[ i ] ~b acc )
      i = i + 1
    end 
    return acc
end

sub filter2( array, func )
   ret = []

   for v array
     if func(~arg v )
        push( ~array ret ~top v )
     end    
   end

   return ret
end


sub map2( array, func )
   ret = []

   for v array
     push( ~array ret ~top func( ~arg v ) )
   end

   return ret
end

# --------------------------------

sub sum( a, b )
  return a + b
end

sub sumsqr( a, b )
  return a * a + b
end

sub even( arg )
  return arg % 2 == 0
end

sub square( arg )
   return arg * arg
end

# --------------------------------

a = [ 1, 2, 3, 4, 5 ]

println( ~msg 'fold left - sum: ' .. foldleft2( ~array a ~func sum ~initval 0 ) ) 
println( ~msg 'fold right - sum: ' .. foldright2( ~array a ~func sum ~initval 0 ) ) 

println( ~msg 'fold left - sum of squares: ' .. foldleft2( ~array a ~func sumsqr ~initval 0 ) ) 
println( ~msg 'fold right - sum of squares: ' .. foldright2( ~array a ~func sumsqr ~initval 0 ) ) 

println( ~msg 'filter - filter odd numbers: ' .. filter2( ~array a ~func even ) ) 

println( ~msg '*** map - square root of numbers ***' )

sqa = map2( ~array a ~func square )

for v sqa 
  println( ~msg v )
end


Standard output for 18-higher-order-func.p

fold left - sum: 15
fold right - sum: 15
fold left - sum of squares: 55
fold right - sum of squares: 55
filter - filter odd numbers: [ -> 2, -> 4 ]
*** map - square root of numbers ***
1
4
9
16
25

Trace output for 18-higher-order-func.p

068|a = [ 1 , 2 , 3 , 4 , 5] 
070|println( ~msg 'fold left - sum: ' .. foldleft2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sum(~a , ~b) ~initval 0 )...
005| acc = initval:0
007| ... = size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
007| i = size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5
008| while (i:5 > 0):true
009|  ... = func:sub sum( ~a array[i:5]:5 ~b acc:0 )...
051|   return (a:-> 5 + b:0):5
009|  acc = func:sub sum( ~a array[i:5]:5 ~b acc:0 ):5
010|  i = (i:5 - 1):4
011| end
008| while (i:4 > 0):true
009|  ... = func:sub sum( ~a array[i:4]:4 ~b acc:5 )...
051|   return (a:-> 4 + b:5):9
009|  acc = func:sub sum( ~a array[i:4]:4 ~b acc:5 ):9
010|  i = (i:4 - 1):3
011| end
008| while (i:3 > 0):true
009|  ... = func:sub sum( ~a array[i:3]:3 ~b acc:9 )...
051|   return (a:-> 3 + b:9):12
009|  acc = func:sub sum( ~a array[i:3]:3 ~b acc:9 ):12
010|  i = (i:3 - 1):2
011| end
008| while (i:2 > 0):true
009|  ... = func:sub sum( ~a array[i:2]:2 ~b acc:12 )...
051|   return (a:-> 2 + b:12):14
009|  acc = func:sub sum( ~a array[i:2]:2 ~b acc:12 ):14
010|  i = (i:2 - 1):1
011| end
008| while (i:1 > 0):true
009|  ... = func:sub sum( ~a array[i:1]:1 ~b acc:14 )...
051|   return (a:-> 1 + b:14):15
009|  acc = func:sub sum( ~a array[i:1]:1 ~b acc:14 ):15
010|  i = (i:1 - 1):0
011| end
008| while (i:0 > 0):false
011| end # finish loop
012| return acc:15
070|println( ~msg 'fold left - sum: ' .. foldleft2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sum(~a , ~b) ~initval 0 ):15 )...
071|println( ~msg 'fold right - sum: ' .. foldright2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sum(~a , ~b) ~initval 0 )...
016| acc = initval:0
017| i = 1
018| while (i:1 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:1 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sum( ~a array[i:1]:1 ~b acc:0 )...
051|   return (a:-> 1 + b:0):1
019|  acc = func:sub sum( ~a array[i:1]:1 ~b acc:0 ):1
020|  i = (i:1 + 1):2
021| end
018| while (i:2 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:2 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sum( ~a array[i:2]:2 ~b acc:1 )...
051|   return (a:-> 2 + b:1):3
019|  acc = func:sub sum( ~a array[i:2]:2 ~b acc:1 ):3
020|  i = (i:2 + 1):3
021| end
018| while (i:3 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:3 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sum( ~a array[i:3]:3 ~b acc:3 )...
051|   return (a:-> 3 + b:3):6
019|  acc = func:sub sum( ~a array[i:3]:3 ~b acc:3 ):6
020|  i = (i:3 + 1):4
021| end
018| while (i:4 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:4 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sum( ~a array[i:4]:4 ~b acc:6 )...
051|   return (a:-> 4 + b:6):10
019|  acc = func:sub sum( ~a array[i:4]:4 ~b acc:6 ):10
020|  i = (i:4 + 1):5
021| end
018| while (i:5 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:5 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sum( ~a array[i:5]:5 ~b acc:10 )...
051|   return (a:-> 5 + b:10):15
019|  acc = func:sub sum( ~a array[i:5]:5 ~b acc:10 ):15
020|  i = (i:5 + 1):6
021| end
018| while (i:6 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:6 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):false
021| end # finish loop
022| return acc:15
071|println( ~msg 'fold right - sum: ' .. foldright2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sum(~a , ~b) ~initval 0 ):15 )...
073|println( ~msg 'fold left - sum of squares: ' .. foldleft2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sumsqr(~a , ~b) ~initval 0 )...
005| acc = initval:0
007| ... = size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
007| i = size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5
008| while (i:5 > 0):true
009|  ... = func:sub sumsqr( ~a array[i:5]:5 ~b acc:0 )...
055|   return ((a:-> 5 * a:-> 5):25 + b:0):25
009|  acc = func:sub sumsqr( ~a array[i:5]:5 ~b acc:0 ):25
010|  i = (i:5 - 1):4
011| end
008| while (i:4 > 0):true
009|  ... = func:sub sumsqr( ~a array[i:4]:4 ~b acc:25 )...
055|   return ((a:-> 4 * a:-> 4):16 + b:25):41
009|  acc = func:sub sumsqr( ~a array[i:4]:4 ~b acc:25 ):41
010|  i = (i:4 - 1):3
011| end
008| while (i:3 > 0):true
009|  ... = func:sub sumsqr( ~a array[i:3]:3 ~b acc:41 )...
055|   return ((a:-> 3 * a:-> 3):9 + b:41):50
009|  acc = func:sub sumsqr( ~a array[i:3]:3 ~b acc:41 ):50
010|  i = (i:3 - 1):2
011| end
008| while (i:2 > 0):true
009|  ... = func:sub sumsqr( ~a array[i:2]:2 ~b acc:50 )...
055|   return ((a:-> 2 * a:-> 2):4 + b:50):54
009|  acc = func:sub sumsqr( ~a array[i:2]:2 ~b acc:50 ):54
010|  i = (i:2 - 1):1
011| end
008| while (i:1 > 0):true
009|  ... = func:sub sumsqr( ~a array[i:1]:1 ~b acc:54 )...
055|   return ((a:-> 1 * a:-> 1):1 + b:54):55
009|  acc = func:sub sumsqr( ~a array[i:1]:1 ~b acc:54 ):55
010|  i = (i:1 - 1):0
011| end
008| while (i:0 > 0):false
011| end # finish loop
012| return acc:55
073|println( ~msg 'fold left - sum of squares: ' .. foldleft2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sumsqr(~a , ~b) ~initval 0 ):55 )...
074|println( ~msg 'fold right - sum of squares: ' .. foldright2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sumsqr(~a , ~b) ~initval 0 )...
016| acc = initval:0
017| i = 1
018| while (i:1 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:1 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sumsqr( ~a array[i:1]:1 ~b acc:0 )...
055|   return ((a:-> 1 * a:-> 1):1 + b:0):1
019|  acc = func:sub sumsqr( ~a array[i:1]:1 ~b acc:0 ):1
020|  i = (i:1 + 1):2
021| end
018| while (i:2 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:2 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sumsqr( ~a array[i:2]:2 ~b acc:1 )...
055|   return ((a:-> 2 * a:-> 2):4 + b:1):5
019|  acc = func:sub sumsqr( ~a array[i:2]:2 ~b acc:1 ):5
020|  i = (i:2 + 1):3
021| end
018| while (i:3 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:3 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sumsqr( ~a array[i:3]:3 ~b acc:5 )...
055|   return ((a:-> 3 * a:-> 3):9 + b:5):14
019|  acc = func:sub sumsqr( ~a array[i:3]:3 ~b acc:5 ):14
020|  i = (i:3 + 1):4
021| end
018| while (i:4 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:4 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sumsqr( ~a array[i:4]:4 ~b acc:14 )...
055|   return ((a:-> 4 * a:-> 4):16 + b:14):30
019|  acc = func:sub sumsqr( ~a array[i:4]:4 ~b acc:14 ):30
020|  i = (i:4 + 1):5
021| end
018| while (i:5 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:5 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):true
019|  ... = func:sub sumsqr( ~a array[i:5]:5 ~b acc:30 )...
055|   return ((a:-> 5 * a:-> 5):25 + b:30):55
019|  acc = func:sub sumsqr( ~a array[i:5]:5 ~b acc:30 ):55
020|  i = (i:5 + 1):6
021| end
018| while (i:6 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] )...
018| while (i:6 <= size( ~arg array:-> [ -> 1, -> 2, -> 3, -> 4, -> 5 ] ):5):false
021| end # finish loop
022| return acc:55
074|println( ~msg 'fold right - sum of squares: ' .. foldright2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub sumsqr(~a , ~b) ~initval 0 ):55 )...
076|println( ~msg 'filter - filter odd numbers: ' .. filter2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub even(~arg) )...
026| ret = [ ] 
028| for v = 1
029|  if func:sub even( ~arg v:1 )...
059|   return ((arg:1 % 2):1 == 0):false
029|  if func:sub even( ~arg v:1 ):0
030|  end # if
028| end
028| for ...
028| for v = 2
029|  if func:sub even( ~arg v:2 )...
059|   return ((arg:2 % 2):0 == 0):true
029|  if func:sub even( ~arg v:2 ):1
030|   push( ~array ret:[  ] ~top v:2 )...
030|  end # if
028| end
028| for ...
028| for v = 3
029|  if func:sub even( ~arg v:3 )...
059|   return ((arg:3 % 2):1 == 0):false
029|  if func:sub even( ~arg v:3 ):0
030|  end # if
028| end
028| for ...
028| for v = 4
029|  if func:sub even( ~arg v:4 )...
059|   return ((arg:4 % 2):0 == 0):true
029|  if func:sub even( ~arg v:4 ):1
030|   push( ~array ret:[ -> 2 ] ~top v:4 )...
030|  end # if
028| end
028| for ...
028| for v = 5
029|  if func:sub even( ~arg v:5 )...
059|   return ((arg:5 % 2):1 == 0):false
029|  if func:sub even( ~arg v:5 ):0
030|  end # if
028| end
028| for ...
028| end # finish for loop
034| return ret:[ -> 2, -> 4 ]
076|println( ~msg 'filter - filter odd numbers: ' .. filter2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub even(~arg) ):[ -> 2, -> 4 ] )...
078|println( ~msg '*** map - square root of numbers ***' )...
080|... = map2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub square(~arg) )...
039| ret = [ ] 
041| for v = 1
042|  push( ~array ret:[  ] ~top func:sub square( ~arg v:1 )...
063|   return (arg:1 * arg:1):1
042|  push( ~array ret:[  ] ~top func:sub square( ~arg v:1 ):1 )...
041| end
041| for ...
041| for v = 2
042|  push( ~array ret:[ -> 1 ] ~top func:sub square( ~arg v:2 )...
063|   return (arg:2 * arg:2):4
042|  push( ~array ret:[ -> 1 ] ~top func:sub square( ~arg v:2 ):4 )...
041| end
041| for ...
041| for v = 3
042|  push( ~array ret:[ -> 1, -> 4 ] ~top func:sub square( ~arg v:3 )...
063|   return (arg:3 * arg:3):9
042|  push( ~array ret:[ -> 1, -> 4 ] ~top func:sub square( ~arg v:3 ):9 )...
041| end
041| for ...
041| for v = 4
042|  push( ~array ret:[ -> 1, -> 4, -> 9 ] ~top func:sub square( ~arg v:4 )...
063|   return (arg:4 * arg:4):16
042|  push( ~array ret:[ -> 1, -> 4, -> 9 ] ~top func:sub square( ~arg v:4 ):16 )...
041| end
041| for ...
041| for v = 5
042|  push( ~array ret:[ -> 1, -> 4, -> 9, -> 16 ] ~top func:sub square( ~arg v:5 )...
063|   return (arg:5 * arg:5):25
042|  push( ~array ret:[ -> 1, -> 4, -> 9, -> 16 ] ~top func:sub square( ~arg v:5 ):25 )...
041| end
041| for ...
041| end # finish for loop
045| return ret:[ -> 1, -> 4, -> 9, -> 16, -> 25 ]
080|sqa = map2( ~array a:[ -> 1, -> 2, -> 3, -> 4, -> 5 ] ~func sub square(~arg) ):[ -> 1, -> 4, -> 9, -> 16, -> 25 ]
082|for v = 1
083| println( ~msg v:1 )...
082|end
082|for ...
082|for v = 4
083| println( ~msg v:4 )...
082|end
082|for ...
082|for v = 9
083| println( ~msg v:9 )...
082|end
082|for ...
082|for v = 16
083| println( ~msg v:16 )...
082|end
082|for ...
082|for v = 25
083| println( ~msg v:25 )...
082|end
082|for ...
082|end # finish for loop