What's the difference between partial evaluation and function inlining in a functional language?

前端 未结 2 1474
走了就别回头了
走了就别回头了 2021-02-19 05:53

I know that:

  1. Function inlining is to replace a function call with the function definition.
  2. Partial evaluation is to evaluate the known (static) parts of a
2条回答
  •  轮回少年
    2021-02-19 06:15

    Consider the following code:

    map f xs = case xs of [] -> []; (x:xs') -> f x : map f xs'
    f x y = if x % 2 == 0 then y + x / 2 else y + x
    
    main = map (f 3) [1..100]
    

    After partial evaluating f 3:

    f3 y = if 3 % 2 == 0 then y + 3 / 2 else y + 3
    main = map f3 [1..100]
    

    And then after constant folding 3 % 2 == 0:

    f3 y = y + 3
    main = map f3 [1..100]
    

    Now let's consider inlining f:

    NOTICE: f in f 3 will not be inlined since it is not a fully application, but we can adjust f's definition to make it happen, for more detail, see the ghc doc here

    f x = \y -> if x % 2 == 0 then y + x / 2 else y + x
    
    main = map (\y -> if 3 % 2 == 0 then y + 3 / 2 else y + 3) [1..100]
    

    And then after constant folding 3 % 2 == 0:

    main = map (\y -> y + 3) [1..100]
    

    The above example shows that, both inlining and partial evaluation can provide extra optimization opportunities, but they are still very different:

    1. when the special version (f 3 in the above example) appears many times, inlining will produce very many duplicated codes.
    2. partial evaluation still works when the first argument is not a static constant, but inlining will not.

    For the second point, consider the following example:

    main = [f x y | x <- [1..10], y <- [1..100]]
    

    In this case, partial evaluation can generate 10 specialized version for f x dynamically, but inlining can do nothing.

提交回复
热议问题