[erlang-questions] Compiler list comprehension optimizations

Anthony Ramine <>
Fri Jun 14 09:48:10 CEST 2013


Hello Jonathan,

Replied inline.

Regards,

-- 
Anthony Ramine

Le 14 juin 2013 à 03:38, Jonathan Leivent a écrit :

> I have some questions about compiler optimizations on list comprehensions.
> 
> The efficiency guide says that list comprehensions that are "neither assigned to a variable, nor passed to another function, nor returned" will be optimized by the compiler to avoid the list construction.
> 
> However, Dialyzer sometimes complains about such list comprehensions with "Expression produces a value of type ['ok'], but this value is unmatched".  So I have developed the habit of assigning to "_", as with:
> 
> foo(...) ->
>  ...,
>  _ = [bar(X) || ...],
>  ....
> 
> After re-reading that line in the efficiency guide, it seems like this assignment might actually defeat the above compiler optimization.  Does it?  Or does the compiler still manage to do the optimization?

It doesn't, the compiler knows that "_" is not a variable and thus that the value of the expression ins't used. The match is there solely to silence the Dialyzer warning, to tell him you know what you are doing.

> If this does prevent the optimization, is there a way to get the optimization and prevent the Dialyzer warning while still using a list comprehension?
> 
> Another question about list comprehension optimizations:  If a list being iterated over is generated from a function that just builds the list element-wise, can the compiler inline that function so that the intermediate list isn't built?  For instance, if the function is something like the very useful list of all non-empty tails of a list:
> 
>  alltails(L=[_|T]) -> [L|alltails(T)];
>  alltails([]) -> [].
> 
>  [... || T <- alltails(L), ...]
> 
> can the compiler generate code that avoids actually building the list of all tails of L?
> 
> Obviously, one could write alltails in (reversed) tail-recursive form, but I would think that if the compiler has any chance of inlining alltails into that list comprehension to remove the intermediate list, the best chance would be with the simpler non-tail-recursive form.

If you tell the compiler to inline alltails/1, it could do some optimisations but I don't think it is smart enough, at the very least it won't inline anything if you don't tell it so.




More information about the erlang-questions mailing list