<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="309873" data-post-id="309873">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Elixir’s AST isn’t specified so they were relying on implementation details anyway.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309873" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/64">Post #63</a>
	                </div>
	            </div>
              <div id="likers-container-309873" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309873"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #63"></div>
  </section>
</div>
    <div class="postbit" id="309874" data-post-id="309874">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tmbb" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tmbb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The AST is definitely described in the docs: <a href="https://hexdocs.pm/elixir/1.14/syntax-reference.html#the-elixir-ast" class="inline-onebox" rel="noopener nofollow ugc">Syntax reference — Elixir v1.14.5</a>. As such, it’s very common to rely on the exact format of the AST (most macros can’t be written if the concrete form of the AST can’t be assumed to be of a given shape).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309874" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/65">Post #64</a>
	                </div>
	            </div>
              <div id="likers-container-309874" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309874"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #64"></div>
  </section>
</div>
    <div class="postbit" id="309877" data-post-id="309877">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yes, but as far as I am aware there is no promise it will never change. At least I remember that said in the forum a few years ago. Things might have changed.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309877" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/66">Post #65</a>
	                </div>
	            </div>
              <div id="likers-container-309877" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309877"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #65"></div>
  </section>
</div>
    <div class="postbit" id="309883" data-post-id="309883">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hst337" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hst337
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am strongly against this proposal, I have objective points and I’ll explain them one by one</p>
<ol>
<li>The problem is not important.</li>
<li>Existing solution is okay.</li>
<li>There are other solutions for other traversals which do not require any changes in the language.</li>
<li>Mutable variables bring more confusion.</li>
<li>Proposal is unclear.</li>
</ol>
<h2><a name="p-309883-the-problem-1" class="anchor" href="#p-309883-the-problem-1" aria-label="Heading link" rel="nofollow"></a>The Problem</h2>
<p>Nested structures traversal has always been a difficult problem for Elixir, because language is immutable (therefore nested traversals require careful rewriting of the parts of the structures) and <code>Access</code> is quite limited, since it is not working with structs out of box, it is missing most common lenses for different traversals and it is just not popular (most of the Elixir developers I’ve worked with didn’t know about `Access.key</p>
<h2><a name="p-309883-described-solution-2" class="anchor" href="#p-309883-described-solution-2" aria-label="Heading link" rel="nofollow"></a>Described solution</h2>
<p>It is okay</p>
<ul>
<li>
<p><strong>Amount of code</strong>. Yes, it doesn’t look as short as Python’s solution, but it has lower cognitive load (it can be read from top to bottom, without keeping in mind mutable variables and when can they be changed).</p>
</li>
<li>
<p><strong>“Lack of reassignment” and “Lack of mutability”</strong> can be downsides only for developers coming from the other languages. It is a great goal to have lower learning curve than other languages, especially for functional language aiming at Ruby and Python developer’s auditory, but I’ll describe why local mutable variables will make everything more difficult in the separate point. This point just states that for Elixir developers, these are not downsides.</p>
</li>
<li>
<p><strong>It is not hard to write</strong>. When I did Elixir teaching, <code>Enum.reduce</code> was taught on 2nd or 3rd lesson, and students were using it comfortable after a first week or so. These kinds of problems are solved within a 5 minutes max.</p>
</li>
<li>
<p><strong>It is not hard to read</strong>. And this point comes from immutability. In immutable languages, developer doesn’t need to track every change of the variable.</p>
</li>
</ul>
<h2><a name="p-309883-other-solutions-3" class="anchor" href="#p-309883-other-solutions-3" aria-label="Heading link" rel="nofollow"></a>Other solutions</h2>
<p>However, there are third-party solutions for these kinds of problems which work this just fine. I don’t want to rename all of them, but I know for sure that they exist.</p>
<h1><a name="p-309883-local-mutable-variables-will-bring-more-confusion-4" class="anchor" href="#p-309883-local-mutable-variables-will-bring-more-confusion-4" aria-label="Heading link" rel="nofollow"></a>Local mutable variables will bring more confusion</h1>
<p>And this is the most important point. I want to make clear that I am explaining this not from a point that always immutable variables are better, but from a point that exactly for the language in it’s current state, it’s current design and it’s current ecosystem, they will do more harm than good.</p>
<h3><a name="p-309883-context-dependency-5" class="anchor" href="#p-309883-context-dependency-5" aria-label="Heading link" rel="nofollow"></a>Context-dependency</h3>
<ul>
<li>
<p><strong>Technical differences will require rewrite, while semantics will stay the same.</strong> It is clear, that mutable variables will be used as a part of <code>for</code> macro and possible other macros/functions for enumerables traversals. However, the exact context where this feature will be applicable is unclear. For example, let’s take pretty regular optimization, where some traversal is parallelized with <code>Task.async_stream</code>. I am pretty sure that it is not a use case for local mutable variables, however it is a list traversal semantically. Or, as far as I can see right now, it will be applicable to <code>for</code>, but not to <code>Enum</code> functions. These are different versions of the exactly same approaches to the problem, but with local mutable variables they’ll have to be read and written in extremely different ways.</p>
</li>
<li>
<p><strong>Unclear edge-cases</strong>. Nested <code>for</code>s? Two <code>for</code>s in a row? <code>for</code> with a macro over a <code>value</code> which doesn’t know about this mutability feature. If I use a <code>for</code> and define a new variable like</p>
</li>
</ul>
<pre data-code-wrap="elixir"><code class="lang-elixir">mut value = 0
for entry &lt;- list do
  [
    value = value + entry,
    value = value + entry + 1
  ]
end
</code></pre>
<p>What will it return where <code>list = [123]</code>? <code>[[123, 124]]</code> and <code>value = 124</code>? Or <code>[[123, 247]]</code> and <code>value = 247</code>? Extremely unclear.</p>
<h3><a name="p-309883-it-will-make-learning-process-harder-6" class="anchor" href="#p-309883-it-will-make-learning-process-harder-6" aria-label="Heading link" rel="nofollow"></a>It will make learning process harder</h3>
<p>Having a single functional approach with high-order traversal functions is a feature of the language. Small core of the features, almost no intrinsics are what Elixir is loved for. Having a special context-dependent language feature, which semantically goes against the general language design and is an exception, is always a hard to learn thing.</p>
<h3><a name="p-309883-h-180-degrees-opposite-to-the-mutable-languages-in-terms-of-performance-7" class="anchor" href="#p-309883-h-180-degrees-opposite-to-the-mutable-languages-in-terms-of-performance-7" aria-label="Heading link" rel="nofollow"></a>180 degrees opposite to the mutable languages in terms of performance</h3>
<p><code>for</code> macro is already underperforming. Plus, both Elixir and Erlang are missing loop optimizations (and it seems that I am the only one who cares about it). Loop written in a Python style will generate performance penalties. For example,</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def sum(list) do
  mut value = 0
  for entry &lt;- list do
    value = value + entry
  end
  value
end
</code></pre>
<p>Will be underperforming, since it’ll have to generate a list and return a value, but semantically it is clear that list is not required here. And Python-to-Elixir developer will have an incorrect feeling that this is the fastest way to sum a list, while it is actually a slowest. Any compiler with top-level optimizations would be able to optimize it, Elixir’s one is uncapable of doing it.</p>
<h3><a name="p-309883-for-is-already-not-popular-8" class="anchor" href="#p-309883-for-is-already-not-popular-8" aria-label="Heading link" rel="nofollow"></a><code>for</code> is already not popular</h3>
<p>I’ve just grepped the opensource I have locally cloned. <code>for</code> is used 10x less frequently than all of the <code>Enum</code> functions (and most of the time it is used in <code>.heex</code> templates, because it requires less escapes). And I can tell that it is for a reason. <code>for</code> has lower performance, it has too many features and it is really easy to misuse because of it’s filtering-by-pattern approach. Adding a new feature won’t make it more popular, it will make it more feature-creeping.</p>
<h1><a name="p-309883-proposal-is-unclear-9" class="anchor" href="#p-309883-proposal-is-unclear-9" aria-label="Heading link" rel="nofollow"></a>Proposal is unclear</h1>
<p>After writing this text it is still unclear for me what problem is actually being solved by addition of local mutable variables. We’re already able to efficiently traverse nested structures and we’re able to do it from “readable but slow” to “the most efficient” way.</p>
<p>Perhaps new feature improves readability? Perhaps this feature will make it easier to switch languages from Ruby to Elixir, for example? Perhaps this feature will make our code more efficient? Perhaps this feature will solve some other problem? I’ve read the subject post carefully several times, and it is still unclear.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309883" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/67">Post #66</a>
	                </div>
	            </div>
              <div id="likers-container-309883" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309883"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #66"></div>
  </section>
</div>
    <div class="postbit" id="309885" data-post-id="309885">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hi <span class="mention">@hissssst</span>, I will focus my reply mostly on the inaccuracies and disagreements (and I will reopen the thread so the discussion can continue).</p>
<p>First of all, I understand some believe that the problem is not worth solving and the current approaches are fine. I don’t think our <em>opinions</em> will change on this one, so I will skip this part.</p>
<aside class="quote no-group" data-username="hissssst" data-post="67" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
 hissssst:</div>
<blockquote>
<p><code>Access</code> is quite limited, since it is not working with structs out of box, it is missing most common lenses for different traversals and it is just not popular</p>
</blockquote>
</aside>
<p>I would love to see a solution to this problem that uses Access and traversals as a starting point. It is a route that I have explored but I could not come up with anything satisfactory. So if improving Access is answer, I would like to see something concrete towards this direction.</p>
<aside class="quote no-group" data-username="hissssst" data-post="67" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
 hissssst:</div>
<blockquote>
<p>However, there are third-party solutions for these kinds of problems which work this just fine. I don’t want to rename all of them, but I know for sure that they exist.</p>
</blockquote>
</aside>
<p><strong>Please name them</strong>, otherwise it is hard to agree that there are solutions to this problem if we can’t see nor evaluate them.</p>
<aside class="quote no-group" data-username="hissssst" data-post="67" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
 hissssst:</div>
<blockquote>
<p>However, the exact context where this feature will be applicable is unclear. For example, let’s take pretty regular optimization, where some traversal is parallelized with <code>Task.async_stream</code>.</p>
</blockquote>
</aside>
<p>It is not unclear. Local mutable variables do not cross functions (anonymous or not), as they would no longer be local. This is mentioned in the proposal and in the discussion. You are correct that using them would require reframing the problem, but so would any <code>Enum.map_reduce</code> (the current solution) that needs to become a Task.async_stream.</p>
<aside class="quote no-group" data-username="hissssst" data-post="67" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
 hissssst:</div>
<blockquote>
<p><strong>Unclear edge-cases</strong>. Nested <code>for</code>s? Two <code>for</code>s in a row? <code>for</code> with a macro over a <code>value</code> which doesn’t know about this mutability feature.</p>
</blockquote>
</aside>
<p>Please provide examples, as I fail to see how these can be edge cases. The only edge case you gave as an example it is not unclear nor new. Let’s take a look at it:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">mut value = 0
for entry &lt;- list do
  [
    value = value + entry,
    value = value + entry + 1
  ]
end
</code></pre>
<p>To answer what is the value of <code>value</code>, it is the same as if you wrote this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  value = 0
  entry = 123
  [
    value = value + entry,
    value = value + entry + 1
  ]
  # value?
</code></pre>
<p>There is nothing new to the language semantics here.</p>
<aside class="quote no-group" data-username="hissssst" data-post="67" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
 hissssst:</div>
<blockquote>
<p>Will be underperforming, since it’ll have to generate a list and return a value, but semantically it is clear that list is not required here. And Python-to-Elixir developer will have an incorrect feeling that this is the fastest way to sum a list, while it is actually a slowest.</p>
</blockquote>
</aside>
<p>This is 100% inaccurate. Today Elixir already does not generate the list of a comprehension if the result is unused and it would be trivial to extend that to this proposal.</p>
<aside class="quote no-group" data-username="hissssst" data-post="67" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
 hissssst:</div>
<blockquote>
<p>I’ve just grepped the opensource I have locally cloned. <code>for</code> is used 10x less frequently than all of the <code>Enum</code> functions (and most of the time it is used in <code>.heex</code> templates, because it requires less escapes). And I can tell that it is for a reason. <code>for</code> has lower performance, it has too many features and it is really easy to misuse because of it’s filtering-by-pattern approach.</p>
</blockquote>
</aside>
<p>No, you cannot tell us it is for that reason, unless you do studies with the community that proves that’s the root cause. Enums also provide more functionality that cannot be expressed with <code>for</code> and one <code>for</code> can be a replacement to several Enum calls, so this measurement is hardly a concrete measure of anything.</p>
<p>You said earlier that not many people are interested in improving comprehensions. If their performance was a concern, as you claim to be, wouldn’t we see more people interested in speeding them up? So these two arguments seem to contradict each other. In practice I haven’t seen anyone, except you, concerned about their performance to the point where their usage would be a deal breaker, and we are always glad to continue improving things where we can.</p>
<p>Look, I really struggle joining discussions where opinions are presented as facts. They are very draining because I have to be the one presenting logical arguments to things that are often subjective. It is ok to say your opinions but it is unfair to present them as something other than that. I like to think I have a pretty good feeling of the community needs and asks, and even then I try to be careful to not present my perception as a single and correct point of view, and I would like to ask you to do the same.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309885" data-batch-url="/posts/batch_likers">
                        11
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/69">Post #68</a>
	                </div>
	            </div>
              <div id="likers-container-309885" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309885"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #68"></div>
  </section>
</div>
    <div class="postbit" id="309889" data-post-id="309889">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hst337" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hst337
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p><strong>Please name them</strong>, otherwise it is hard to agree that there are solutions to this problem if we can’t see nor evaluate them.</p>
</blockquote>
</aside>
<p>Yes, sure, I just didn’t want it to sound like advertising. One is Pathex traversal with pdict, other is Iteraptor by <a class="mention" href="/u/mudasobwa" rel="nofollow">@mudasobwa</a>, which is more suitable for this exact problem.</p>
<hr>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>To answer what is the value of <code>value</code>, it is the same as if you wrote this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  value = 0
  entry = 123
  [
    value = value + entry,
    value = value + entry + 1
  ]
</code></pre>
</blockquote>
</aside>
<p>Than it is not mutable in a traditional sense, it is semi-mutable. Erlang lists compilation works in a way, that context is not inherited between instantiation of list items. But “mutability”-as-a-term means that it is. That’s the problem which can not be easily fixed on the level of Elixir’s compiler.</p>
<p>To rephrase it, Python (and any other mutable language) dev would expect</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">x = 0
[
  x = x + 100500,
  x = x + 1
]
</code></pre>
<p>To be <code>[100500, 100501]</code> and <code>x = 100501</code>, but in Elixir this would actually be <code>[100500, 1]</code> and <code>x = 1</code>. This is not mutability by definition.</p>
<p>You can say that you didn’t mean classic mutability, but I can say that it will be a huge problem to learn how this kind of semi-mutable and semi-immutable approach works for both functional and oo devs.</p>
<hr>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>No, you cannot tell us it is for that reason, unless you do studies with the community that proves that’s the root cause</p>
</blockquote>
</aside>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Look, I really struggle joining discussions where opinions are presented as facts</p>
</blockquote>
</aside>
<p>That’s true, I didn’t mean that my opinions were facts. I am not tagging anything as a fact or opinion, because I thought that reader will distinguish it on he*'s own. If you feel that something is not a fact (and my words about reasons of unpopularity of <code>for</code> were completely subjective), than it is not a fact and it is an opinion <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>Considering the unpopularity of <code>for</code>, it is just my feeling and my experience from talking with other people. Most of them say “that’s how I was taught”.</p>
<hr>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>This is 100% inaccurate. Today Elixir already does not generate the list of a comprehension if the result is unused and it would be trivial to extend that to this proposal.</p>
</blockquote>
</aside>
<p>What do you mean? As far as I know, Elixir’s <code>for</code> is just a wrapper around <code>Enum</code>. If I write</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def send_messages(pids, message) do
  for pid &lt;- pids, send(pid, message)
end
</code></pre>
<p>It will generate</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Enum.reduce(pids, [], fn pid, acc -&gt; [send(pid, message) | acc]) |&gt; Enum.reverse()
</code></pre>
<p>Which will instantiate a list of <code>message</code>s.</p>
<p>Vanilla compiler is uncapable of performing dead code analysis of inter-module call or which requires some inlining to perform correctly, since it requires analysis of whole graph of modules, which can change in runtime, and that’s what I meant. I can extend the <code>sum</code> example to reflect my point better, if you want <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<hr>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>You said earlier that not many people are interested in improving comprehensions.</p>
</blockquote>
</aside>
<p>I didn’t say that. I meant that there is already a solution to this problem, and everybody knows how to use <code>Enum</code> to write this solution. Everything can be improved, even comprehensions. And I am working on it in my free time</p>
<hr>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>If their performance was a concern, as you claim to be, wouldn’t we see more people interested in speeding them up?</p>
</blockquote>
</aside>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>In practice I haven’t seen anyone, except you, concerned about their performance to the point where their usage would be a deal breaker</p>
</blockquote>
</aside>
<p>That’s not quite true, but what you’re saying is technically correct. I’ve never seen any person or company choosing other language over Elixir because list comprehensions were slow (and that’s where I agree with you here). But I’ve seen a lot of companies switching from Elixir to Go, or from Elixir to Kotlin or to the other languages because of Elixir’s performance.</p>
<p>And if we’re talking about performance in general, loop optimizations are a part of them. And they’re very important, since first it is usually a low-hanging fruit and second they’re one of the few language features where runtime penalty heavily affects the performance (alongside with GC and dynamic typing dispatch).</p>
<p>So that’s why performance of Enum and comprehensions is important, and I once again want to mention <a class="mention" href="/u/sabiwara" rel="nofollow">@sabiwara</a> for putting some effort into improving performance of Elixir library and Enumancer which became an inspiration for my currently WIP Enum pipes optimizer.</p>
<hr>
<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="69" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>I would love to see a solution to this problem that uses Access and traversals as a starting point. It is a route that I have explored but I could not come up with anything satisfactory. So if improving Access is answer, I would like to see something concrete towards this direction.</p>
</blockquote>
</aside>
<p>I’ve been exploring it some time ago, let me get my ideas together and I’ll present a solution within the Pathex update (and what can be done in Pathex, can be a part of Access for sure)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309889" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/71">Post #70</a>
	                </div>
	            </div>
              <div id="likers-container-309889" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309889"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #70"></div>
  </section>
</div>
    <div class="postbit" id="309890" data-post-id="309890">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hst337" data-post="71" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/41988e/48.png" class="avatar"> hst337:</div>
<blockquote>
<p>That’s true, I didn’t mean that my opinions were facts.</p>
</blockquote>
</aside>
<p>It is a difference in communication style then, thank you for clarifying. I also apologize for assuming you were passing your opinions as facts.</p>
<p>If you find it useful, I suggest making it clearer in your texts when something is based on something objective, such as “<code>for</code> is slow because of benchmarks which I can show”, and when it is an opinion. It can be as simple as adding “I believe”, “I think”, when you emit an opinion or something based on subjective experience, and providing evidence in concrete cases. This way you don’t leave it up to the reader to guess which is which (which would be a shame, because someone may also misjudge something objective you say as subjective). <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> It is also important to make sure we are not just rehashing subjective opinions in discussions.</p>
<p>It is also always worth adding an extra effort in making your texts objective, if you can, as it leads to more productive discussions.</p>
<aside class="quote no-group" data-username="hst337" data-post="71" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/41988e/48.png" class="avatar"> hst337:</div>
<blockquote>
<p>What do you mean? As far as I know, Elixir’s <code>for</code> is just a wrapper around <code>Enum</code>.</p>
</blockquote>
</aside>
<p>In your earlier example, it was clear within the <strong>local</strong> context that the result of <code>for</code> is not used, which is always the case when using local accumulators, as you need to read the value of the local accumulator if you want to use it afterwards. So you are right, we do not perform inter-module analysis but local analysis is enough here (or when you use comprehensions for purely side-effects).</p>
<aside class="quote no-group" data-username="hst337" data-post="71" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/41988e/48.png" class="avatar"> hst337:</div>
<blockquote>
<p>Yes, sure, I just didn’t want it to sound like advertising. One is Pathex traversal with pdict, other is Iteraptor by <a class="mention" href="/u/mudasobwa" rel="nofollow">@mudasobwa</a>, which is more suitable for this exact problem.</p>
</blockquote>
</aside>
<p>Could the problem statement be solved by any of those? <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20">  I am looking forward to other approaches you come up with!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309890" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/72">Post #71</a>
	                </div>
	            </div>
              <div id="likers-container-309890" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309890"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #71"></div>
  </section>
</div>
    <div class="postbit" id="309891" data-post-id="309891">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="adw632" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  adw632
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="57" data-topic="60093">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Thank you. These points convinced me that <code>@@</code> is a very sensible prefix in case we want to go ahead with this proposal. The “a” in @ (“at”) also matches the “a” in accumulator (as it matches the “a” in attributes). I think I have all of the pieces in place to submit a new proposal, so I will do that later. Thank you.</p>
</blockquote>
</aside>
<p>This is just my opinion but I associate <code>@</code> with module variables. Module variable behaviour is also different to assignment to an <code>@@variable</code> which <em>does not</em> collect/accumulate, it just binds a value.</p>
<p>Can we consider <strong>binding to outer scope</strong> as a concept, rather than decorating a variable as “mutable”.</p>
<p>For example adopt a special assignment/binding operator such as <code>:=</code> for binding to the outer scope <em>within</em> the same function. Again this should not cross function boundaries, so anonymous functions cannot bind outside their scope.</p>
<p>The code would look like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">section_counter = 0
lesson_counter = 0

for section &lt;- sections do
  if section["reset_lesson_position"] do
    lesson_counter := 0
  end

  section_counter := section_counter + 1

  lessons =
    for lesson &lt;- section["lessons"] do
      lesson_counter := lesson_counter + 1
      Map.put(lesson, "position", lesson_counter)
    end

  section
  |&gt; Map.put("lessons", lessons)
  |&gt; Map.put("position", section_counter)
end
</code></pre>
<p>This could also work for things like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{foo, bar} := some_func(args)
{:ok, bar} := another_func(args)
</code></pre>
<p>Anyway it’s just another idea on avoiding the mutability concept but providing the usability to bind to parent scope within the same function.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309891" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/73">Post #72</a>
	                </div>
	            </div>
              <div id="likers-container-309891" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309891"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #72"></div>
  </section>
</div>
    <div class="postbit" id="309895" data-post-id="309895">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Unfortunately I don’t think the operator is good enough, given the different ways we can assign/bind to a variable in Elixir. And the fact that in the same pattern we can have both variables and local accumulators.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309895" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/74">Post #73</a>
	                </div>
	            </div>
              <div id="likers-container-309895" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309895"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #73"></div>
  </section>
</div>
    <div class="postbit" id="309898" data-post-id="309898">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The new proposal is here: <a href="https://forum.elixirforum.com/t/local-accumulators-for-cleaner-comprehensions/60130" class="inline-onebox" rel="nofollow">Local accumulators for cleaner comprehensions</a>.</p>
<p><a href="https://forum.elixirforum.com/t/local-accumulators-for-cleaner-comprehensions/60130#local-accumulators-3" rel="nofollow">Click here</a> if you want to jump directly to the new part of the proposal.</p>
<p>Everyone is welcome to post your opinions and feedback on the new thread, even if the new proposal does not really change the opinion you posted here.</p>
<p>I will close this thread. <a class="mention" href="/u/hst337" rel="nofollow">@hst337</a> (and anyone else), alternative answers to the problem statement with Pathex, Iteraptor, or anything else is very welcome in the new thread.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="309898" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/koka-inspired-local-mutable-variables-for-cleaner-comprehensions/60093/75">Post #74</a>
	                </div>
	            </div>
              <div id="likers-container-309898" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="309898"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>