[stack] map fusion

John Nowak <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
In a functional language, the following optimization is valid  
(assuming F and G are pure functions that terminate):

    map G (map F xs)  ->  map (G . F) xs

This is not only an optimization: It is a law that can be used for  
understanding and proving program properties.

For a concatenative language, we might assume the following rule  
(using Joy's syntax):

    [F] map [G] map  ->  [F G] map

Unfortunately, this is not valid because 'F' and 'G' can access more  
than one value on the stack. Here is a counterexample to the above rule:

    9 [1 2 3] [drop dup] map [[1 -] dip] map  -- yields 6 [9 9 9]
    9 [1 2 3] [drop dup [1 -] dip] map        -- yields 6 [9 8 7]

This seems to be yet another argument against n-ary combinators where  
the quotation is not called a fixed number of times. (Combinators that  
call their quotation a fixed number of times like 'dip', 'twice', or  
'@bi' are fine.) The fact that 'map' in a concatenative language is  
still "purely functional" doesn't change the fact that the  
unrestricted stack access complicates things the same way mutable  
local variables do.

It seems the solution is to offer two versions of certain combinators.  
The restricted versions ('map, 'each', etc) will be easier to reason  
about and optimize, while the unrestricted versions ('map*', 'each*',  
etc) will remain useful in a way only possible in stack-based  
languages. I think this would be worthwhile to adopt in both typed and  
untyped languages.

- John
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.