<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Since I needed a bit more space to write an answer 🙄 I replied on <a href="https://medium.com/erlang-battleground/how-to-comprehend-comprehensions-c924f92a97e1?sk=b668da926f05b7293f34dafa48fa5654" class="">my blog</a> 😉<div class="">Cheers :)<br class=""><div class="">
<div style="color: rgb(0, 0, 0); font-family: 'Trebuchet MS'; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><span id="docs-internal-guid-e691a4cc-056a-0210-b8b7-ea8d87d888ad" class=""><span style="font-size: 11pt; font-family: Arial; font-weight: 700; font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; vertical-align: baseline; white-space: pre-wrap;" class=""><br class="Apple-interchange-newline"><hr class=""></span></span><div class=""><b class=""><i class=""><a href="http://about.me/elbrujohalcon" class="">Brujo Benavides</a></i></b></div></div></div><div style="color: rgb(0, 0, 0); font-family: 'Trebuchet MS'; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><b class=""><br class=""></b></div><br class="Apple-interchange-newline">
</div>
<div><br class=""><blockquote type="cite" class=""><div class="">On 23 Aug 2019, at 10:47, Jesper Louis Andersen <<a href="mailto:jesper.louis.andersen@gmail.com" class="">jesper.louis.andersen@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div dir="ltr" class=""><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif" class="">On Fri, Aug 23, 2019 at 2:03 PM I Gusti Ngurah Oka Prinarjaya <<a href="mailto:okaprinarjaya@gmail.com" class="">okaprinarjaya@gmail.com</a>> wrote:</span><br class=""></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="">Hi,<div class=""><br class=""></div><div class="">Now I read Joe's book titled Programming Erlang 2nd Edition. I practice some functions such as for/3, quicksort/1, pythag/1, and perms/1, and perms/1 is the function that hard to understand.</div><div class=""><br class=""></div><div class="">I understand comprehension lists, I fully understand for/3, I fully understand quicksort/1, pythag/1. But it's really hard for me to understand <font face="monospace" class="">perms/1</font>. Please teach me how to read and understand this <font face="monospace" class="">perms/1</font> function.</div><div class=""><br class=""></div><div class=""><font face="monospace" class="">perms([]) -> [[]];<br class="">perms(List) -> [ [H|T] || H <- List, T <- perms(List--[H]) ].</font><br class=""></div><div class=""><br class=""></div></div></blockquote><div class=""><br class=""></div><div class=""><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Note you have two generators in the comprehension. So for each generated H, it generates all the possible T's. Also note that the T's depend on the H. It is akin to having a for-loop within a for-loop:</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br class=""></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">for H := range(List) {</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"> for T := perms(List -- [H]) {</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"> Res := append(Res, [H|T])</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"> }</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">}</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br class=""></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Now, to understand why this works, the argument is based on an induction principle:</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br class=""></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Observe that to generate a permutation, you first select something which goes first, H, and then you need to generate a permutation out of the remaining elements, List -- [H]. Suppose we fix H to some value in the list. Then surely, we can generate all the permutations where H goes first, by generating perms(List - [H]) and then attaching H to all the results:</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br class=""></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">perms(List) -></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"> H = pick_among(List),</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"> [ [H|T] || T <- perms(List -- [H]) ].</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br class=""></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">But now note that to generate all permutations, any element could have been picked by pick_among/1. So we need to loop over all elements in the list one at a time, and consider what happens if that element goes first. This is what the original code is doing.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br class=""></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Alternative wordings by Sverker and Fred :)</div><br class=""></div></div></div>
_______________________________________________<br class="">erlang-questions mailing list<br class=""><a href="mailto:erlang-questions@erlang.org" class="">erlang-questions@erlang.org</a><br class="">http://erlang.org/mailman/listinfo/erlang-questions<br class=""></div></blockquote></div><br class=""></div></body></html>