[erlang-questions] Re: List comprehension questions

James Churchman jameschurchman@REDACTED
Fri Apr 1 19:24:22 CEST 2011


So if (from the docs) list comprehension become : 
'lc^0'([E|Tail], Expr) -> [Expr(E)|'lc^0'(Tail, Expr)];
'lc^0'([], _Expr) -> [].
then, what happens when Expr contains references to other variables in the original scope? (eg not E ) it says  Expr used to be a Fun, but now it's not, so in this case is it a Fun, or does it increase the arty of the generated lc^0 function for each of the extra referenced vars?

Also keen to know the body recursive "cost", and why it avoids using list reverse in the case when a list is required to be returned :-)

james



On 1 Apr 2011, at 12:15, Olivier BOUDEVILLE wrote:

> 
> Hello Richard, 
> 
> First of all, sorry, I had indeed missed your answer. Actually I did not see it neither at work nor at home, and I wonder whether there is not a mailing-list problem as it does not seem to appear either in gmane or in the thread as shown (at least at the time of this writing) by google groups (http://groups.google.com/group/erlang-programming/browse_thread/thread/8d339e24ed090311). 
> 
> Back on topic: as I understand now (I am not too familiar with Core Erlang), list comprehensions generate local functions that are body-recursive, i.e. involve actually a direct recursion, not using an accumulator. 
> 
> I just happened to find http://www.erlang.org/doc/efficiency_guide/listHandling.html#id61285 which gives a similar explanation (maybe a link from the reference manual to the efficiency guide could be made, to associate these two list comprehension topics). 
> 
> I was wondering if this body-recursiveness did not imply that a list comprehension operating on a longer list, whose result would be kept, could eat a lot of stack space/take longer to execute than a tail-recursive version? 
> 
> Apparently according to http://www.erlang.org/doc/efficiency_guide/myths.html#id58884 this will probably not be the case, so using list comprehension does not involve much trade-off. 
> 
> Thanks again, 
> Best regards,
> 
> Olivier Boudeville.
> ---------------------------
> Olivier Boudeville
> 
> EDF R&D : 1, avenue du Général de Gaulle, 92140 Clamart, France
> Département SINETICS, groupe ASICS (I2A), bureau B-226
> Office : +33 1 47 65 59 58 / Mobile : +33 6 16 83 37 22 / Fax : +33 1 47 65 27 13 
> 
> 
> carlsson.richard@REDACTED
> 01/04/2011 10:46
> 
> A
> erlang-questions@REDACTED, olivier.boudeville@REDACTED
> cc
> Objet
> Re: [erlang-questions] Re: List comprehension questions
> 
> 
> 
> 
> 
> On 04/01/2011 10:00 AM, Olivier BOUDEVILLE wrote:
> >
> > Hello Robert,
> >
> > Thanks for your explanation. I guess that the reversal (to restore the
> > original list order after a first "if selected by filter then apply"
> > traversal) is done then in the list:map/2 counterpart!
> >
> > My concern was that, for long lists which do not happen to have to
> > respect any particular order in their elements, two traversals would be
> > done with list comprehensions whereas just one could be sufficient.
> > Well, a minor concern as for such cases we can write our own functions
> > to do so in one pass.
> 
> Perhaps you didn't see my reply to your original mail (repeated below). 
> The point that both Robert and I are trying to make is that there is no 
> reversal involved in the code, and it only does one traversal, so you 
> don't need to worry about this.
> 
>     /Richard
> 
> 
> On 03/30/2011 01:29 PM, Olivier BOUDEVILLE wrote:
> > Reading
> > http://www.erlang.org/doc/reference_manual/expressions.html#id77052 it
> > is not obvious that the order induced by a single generator is
> > necessarily preserved by the comprehension, as nevertheless suggested by
> > all experiments like:
> >
> > 1> [ X || X <- [1,2,3] ].
> > [1,2,3]
> >
> > I suppose this order preservation is true. Then, I imagine that,
> > internally, list comprehensions are translated to code very similar to
> > the one that would be produced if the developer had written an
> > appropriate accumulator-based tail-recursive function?
> >
> > If so, does it imply that using a list comprehension on a semantically
> > unordered set of elements will involve a useless reversal (like
> > lists:reverse/1) of the resulting list?
> 
> No, the translation does a straightforward recursion over the list 
> without accumulator, automatically preserving order. To see what 
> happens, take for example the following module:
> 
>   -module(lc).
>   -export([f/1]).
>   f(Input) ->
>     [N + 1 || N <- Input].
> 
> and compile it to Core Erlang with c(lc,[to_core]) or erlc +to_core 
> lc.erl. The resulting file lc.core contains the following code:
> 
>   'f'/1 =
>     fun (_cor0) ->
>         letrec
>             'lc$^0'/1 =
>                 fun (_cor3) ->
>                     case _cor3 of
>                       <[N|_cor2]> when 'true' ->
>                           let <_cor4> =
>                               call 'erlang':'+'
>                                   (N, 1)
>                           in  let <_cor5> =
>                                   apply 'lc$^0'/1
>                                       (_cor2)
>                               in  ( [_cor4|_cor5]
>                                     -| ['compiler_generated'] )
>                       <[]> when 'true' ->
>                           []
>                       ( <_cor3> when 'true' ->
>                             primop 'match_fail'
>                                 ({( 'function_clause'
>                                     -| [{'name',{'lc$^0',1}}] ),_cor3})
>                         -| ['compiler_generated'] )
>                     end
>         in  apply 'lc$^0'/1
>                 (_cor0)
> 
> (The annotations ( Expr -| 'compiler_generated') on some subexpressions 
> are mostly needed to suppress certain compilation warnings that might 
> otherwise be triggered, such as for unused results of expressions.)
> 
>     /Richard
> 
> 
> 
> 
> Ce message et toutes les pièces jointes (ci-après le 'Message') sont établis à l'intention exclusive des destinataires et les informations qui y figurent sont strictement confidentielles. Toute utilisation de ce Message non conforme à sa destination, toute diffusion ou toute publication totale ou partielle, est interdite sauf autorisation expresse.
> 
> Si vous n'êtes pas le destinataire de ce Message, il vous est interdit de le copier, de le faire suivre, de le divulguer ou d'en utiliser tout ou partie. Si vous avez reçu ce Message par erreur, merci de le supprimer de votre système, ainsi que toutes ses copies, et de n'en garder aucune trace sur quelque support que ce soit. Nous vous remercions également d'en avertir immédiatement l'expéditeur par retour du message.
> 
> Il est impossible de garantir que les communications par messagerie électronique arrivent en temps utile, sont sécurisées ou dénuées de toute erreur ou virus.
> ____________________________________________________
> 
> This message and any attachments (the 'Message') are intended solely for the addressees. The information contained in this Message is confidential. Any use of information contained in this Message not in accord with its purpose, any dissemination or disclosure, either whole or partial, is prohibited except formal approval.
> 
> If you are not the addressee, you may not copy, forward, disclose or use any part of it. If you have received this message in error, please delete it and all copies from your system and notify the sender immediately by return message.
> 
> E-mail communication cannot be guaranteed to be timely secure, error or virus-free._______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110401/01f3f3d8/attachment.htm>


More information about the erlang-questions mailing list