Pooh program example 18-higher-order-func.p
# 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
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 25Trace 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