<br><font size=2 face="sans-serif">Hello Richard,</font>
<br>
<br><font size=2 face="sans-serif">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).</font>
<br>
<br><font size=2 face="sans-serif">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.</font>
<br>
<br><font size=2 face="sans-serif">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).</font>
<br>
<br><font size=2 face="sans-serif">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?</font>
<br>
<br><font size=2 face="sans-serif">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.</font>
<br>
<br><font size=2 face="sans-serif">Thanks again,</font>
<br><font size=2 face="sans-serif">Best regards,<br>
<br>
Olivier Boudeville.<br>
---------------------------<br>
Olivier Boudeville<br>
<br>
EDF R&D : 1, avenue du Général de Gaulle, 92140 Clamart, France<br>
Département SINETICS, groupe ASICS (I2A), bureau B-226<br>
Office : +33 1 47 65 59 58 / Mobile : +33 6 16 83 37 22 / Fax : +33 1 47
65 27 13</font>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=40%><font size=1 face="sans-serif"><b>carlsson.richard@gmail.com</b>
</font>
<p><font size=1 face="sans-serif">01/04/2011 10:46</font>
<td width=59%>
<table width=100%>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">A</font></div>
<td><font size=1 face="sans-serif">erlang-questions@erlang.org, olivier.boudeville@edf.fr</font>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">Objet</font></div>
<td><font size=1 face="sans-serif">Re: [erlang-questions] Re: List comprehension
questions</font></table>
<br>
<table>
<tr valign=top>
<td>
<td></table>
<br></table>
<br>
<br>
<br><tt><font size=2>On 04/01/2011 10:00 AM, Olivier BOUDEVILLE wrote:<br>
><br>
> Hello Robert,<br>
><br>
> Thanks for your explanation. I guess that the reversal (to restore
the<br>
> original list order after a first "if selected by filter then
apply"<br>
> traversal) is done then in the list:map/2 counterpart!<br>
><br>
> My concern was that, for long lists which do not happen to have to<br>
> respect any particular order in their elements, two traversals would
be<br>
> done with list comprehensions whereas just one could be sufficient.<br>
> Well, a minor concern as for such cases we can write our own functions<br>
> to do so in one pass.<br>
<br>
Perhaps you didn't see my reply to your original mail (repeated below).
<br>
The point that both Robert and I are trying to make is that there is no
<br>
reversal involved in the code, and it only does one traversal, so you <br>
don't need to worry about this.<br>
<br>
/Richard<br>
<br>
<br>
On 03/30/2011 01:29 PM, Olivier BOUDEVILLE wrote:<br>
> Reading<br>
> http://www.erlang.org/doc/reference_manual/expressions.html#id77052
it<br>
> is not obvious that the order induced by a single generator is<br>
> necessarily preserved by the comprehension, as nevertheless suggested
by<br>
> all experiments like:<br>
><br>
> 1> [ X || X <- [1,2,3] ].<br>
> [1,2,3]<br>
><br>
> I suppose this order preservation is true. Then, I imagine that,<br>
> internally, list comprehensions are translated to code very similar
to<br>
> the one that would be produced if the developer had written an<br>
> appropriate accumulator-based tail-recursive function?<br>
><br>
> If so, does it imply that using a list comprehension on a semantically<br>
> unordered set of elements will involve a useless reversal (like<br>
> lists:reverse/1) of the resulting list?<br>
<br>
No, the translation does a straightforward recursion over the list <br>
without accumulator, automatically preserving order. To see what <br>
happens, take for example the following module:<br>
<br>
-module(lc).<br>
-export([f/1]).<br>
f(Input) -><br>
[N + 1 || N <- Input].<br>
<br>
and compile it to Core Erlang with c(lc,[to_core]) or erlc +to_core <br>
lc.erl. The resulting file lc.core contains the following code:<br>
<br>
'f'/1 =<br>
fun (_cor0) -><br>
letrec<br>
'lc$^0'/1 =<br>
fun (_cor3) -><br>
case _cor3 of<br>
<[N|_cor2]> when 'true' -><br>
let <_cor4> =<br>
call 'erlang':'+'<br>
(N, 1)<br>
in let <_cor5> =<br>
apply 'lc$^0'/1<br>
(_cor2)<br>
in ( [_cor4|_cor5]<br>
-| ['compiler_generated']
)<br>
<[]> when 'true' -><br>
[]<br>
( <_cor3> when 'true' -><br>
primop 'match_fail'<br>
({( 'function_clause'<br>
-| [{'name',{'lc$^0',1}}]
),_cor3})<br>
-| ['compiler_generated'] )<br>
end<br>
in apply 'lc$^0'/1<br>
(_cor0)<br>
<br>
(The annotations ( Expr -| 'compiler_generated') on some subexpressions
<br>
are mostly needed to suppress certain compilation warnings that might <br>
otherwise be triggered, such as for unused results of expressions.)<br>
<br>
/Richard<br>
</font></tt>
<br><font face="monospace"><br>
<br>
<br>
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.<br>
<br>
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.<br>
<br>
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.<br>
____________________________________________________<br>
<br>
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.<br>
<br>
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.<br>
<br>
E-mail communication cannot be guaranteed to be timely secure, error or virus-free.</font>