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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="garrison" data-post="10" data-topic="72968">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>BTW, your dedication to responding to feedback on here is amazing. Don’t think it goes unnoticed!</p>
</blockquote>
</aside>
<p>Thanks! <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"> Honestly, responding to feedback like this is a great way for me to crystallize what I have in my head and discover new ideas I hadn’t considered. These discussions really help shape Hologram’s direction.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376347" data-batch-url="/posts/batch_likers">
                        2
                      </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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-376347" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376347"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="376349" data-post-id="376349">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Alright, here are some ideas to show what I have in mind! <a class="mention" href="/u/garrison" rel="nofollow">@garrison</a> <a class="mention" href="/u/venkatd" rel="nofollow">@venkatd</a></p>
<p>The core idea: a simple, component-scoped DSL that defines how derived/computed/memoized values (terminology is up for discussion) are calculated. Hologram automatically updates these values when any dependencies change, and the values are injected into template vars accessible with the <code>@</code> syntax, e.g. <code>{@my_derived_value}</code>.</p>
<p>The dependencies for derived values can be state, props, and other derived values, so a dependency graph is built underneath and topological sort is applied to manage the recalculation order.</p>
<p><strong>The DSL can be implemented in different ways</strong> (full_name probably isn’t the best real-world use case, but it’s easy to understand):</p>
<p><strong>Option 1: Macro with explicit deps</strong></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">derived :full_name, [:first_name, :last_name] do
  "#{first_name} #{last_name}"
end
</code></pre>
<p><strong>Option 2: Attribute annotation</strong></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">@derived deps: [:first_name, :last_name]
def full_name(vars) do
  "#{vars.first_name} #{vars.last_name}"
end
</code></pre>
<p><strong>Option 3: Function-like syntax</strong></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defderived full_name(first_name, last_name) do
  "#{first_name} #{last_name}"
end
</code></pre>
<p>…and other permutations and hybrids of these approaches.</p>
<p><strong>Key characteristics:</strong></p>
<ul>
<li>Pure functions transforming immutable state (no side effects)</li>
<li>Component-scoped dependencies (local and bounded)</li>
<li>Automatically memoized (recalculated only when dependencies change)</li>
<li>Deterministic dependency graph (fully traceable)</li>
<li>Still fits the <code>ui = fn(state)</code> paradigm</li>
</ul>
<p>This is fundamentally different from the mutable observer patterns in KnockoutJS/EmberJS that created convoluted webs of interdependencies. There’s no global reactivity, no scattered side effects, no mutation-based cascading updates.</p>
<p><strong>Important clarification:</strong> This is purely for <strong>deriving/computing values</strong> without any component struct modifications. For reactive state updates, effects/watchers would be a separate concept – but that’s a different discussion.</p>
<p>Would love to hear which syntax option resonates with you, and what other ideas you might have!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376349" data-batch-url="/posts/batch_likers">
                        3
                      </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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-376349" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376349"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="376375" data-post-id="376375">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am going to try to briefly describe where modern React came from. To do this, we have to go <a href="https://legacy.reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class" rel="noopener nofollow ugc">back in time</a> to when React had class components.</p>
<p>Early React indeed had this idea that UI should be a pure function of state. The <code>render()</code> method was supposed to take the state/props and produce a pure HTML representation from them. This is an enormous improvement over trying to imperatively update the DOM by writing delta code for each state transition (like people used to do with jquery). React was better.</p>
<p>However, over time people began to build more and more complex apps with React, and as a result React’s engine slowly <a href="https://overreacted.io/react-as-a-ui-runtime/" rel="noopener nofollow ugc">became a UI runtime</a>. That is, it grew past the “V(iew) in MVC” and became the source of truth for the execution trace of the application itself.</p>
<p>The problem is that, while the <code>render()</code> function was declarative, the rest of the component was not. <a href="https://acko.net/blog/climbing-mt-effect/" rel="noopener nofollow ugc">Declarative programming is an extraordinarily powerful tool for preventing bugs</a>, but class components failed to take advantage of this. When you break apart the init/lifecycle/render codepaths you violate the declarative principle of tearing the intermediate state down and rebuilding it.</p>
<p>The hard-to-swallow-truth here is that pure functions were actually the problem, because by making the render function pure you are taking away its ability to initialize state. The path forward, ironically, is to pare the render function back to being <em>idempotent</em>. This is what React’s hooks did.</p>
<p>A function component executes from top to bottom on each render, declaratively. React then gives you tools (hooks) to keep track of and memoize state <em>as you choose</em> so that you can optimize your program. React keeps the tree in sync so that local state “lines up” on each execution, and the hooks are designed to be composed so that they line up even if factored out into libraries.</p>
<p>This solution is <em>very</em> good, because it keeps the programmer in control the whole way through.</p>
<p>There are two things that I have fundamentally come to accept (and I did not start out wanting to accept these things):</p>
<ul>
<li>The React team of the time was full of incredibly smart people who were <em>extremely</em> dedicated to solving this problem properly</li>
<li>It took them over half a decade, operating well-funded and at enormous scale, to come up with a workable solution</li>
</ul>
<p>Given this, if you are going to deviate from React’s model you should do so with <em>enormous</em> caution. You must be aware of the endless graveyard of half-baked and failed solutions to these problems.</p>
<p>I will now give you my opinion: I think you are trying to impose structure where there needn’t be any. It is my decision whether to memoize or recompute a property, not yours. It is my decision whether that property should exist within a given render <em>at all</em>.</p>
<p>The purpose of a UI runtime is to allow me to write turing-complete code for my application. No matter how fancy your DSL, you are forcing me to statically declare computed properties at compile time and taking away my control over the execution of the program. This is fundamentally inexpressive.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376375" data-batch-url="/posts/batch_likers">
                        3
                      </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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-376375" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376375"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="376425" data-post-id="376425">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>fwiw, I like the svelte approach of making dependency tracking opt-out (using <code>untrack</code>) rather than opt-in.</p>
<p>I think this would be nice:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">derived :full_name do
  "#{first_name} #{last_name}"
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376425" 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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-376425" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376425"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="376430" data-post-id="376430">
  <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>The derived stuff starts suspiciously looking like Ash’s calculations. Which is to say I like it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376430" data-batch-url="/posts/batch_likers">
                        2
                      </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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-376430" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376430"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="376488" data-post-id="376488">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I wholeheartedly agree with embracing React’s programming model.</p>
<p>The sense I got, though, is that <a class="mention" href="/u/bartblast" rel="nofollow">@bartblast</a> is really talking about memoization of function calls and not computed properties as signals are. What is your stance on the ability to memoize function calls?</p>
<p>It seems like there could be an ergonomic way to handle this with module attributes or a bit of macro syntax sugar.</p>
<p>If there is no memoization available, what would you propose?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376488" 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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-376488" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376488"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="376496" data-post-id="376496">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="garrison" data-post="14" data-topic="72968">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>There are two things that I have fundamentally come to accept (and I did not start out wanting to accept these things):</p>
<ul>
<li>The React team of the time was full of incredibly smart people who were <em>extremely</em> dedicated to solving this problem properly</li>
<li>It took them over half a decade, operating well-funded and at enormous scale, to come up with a workable solution</li>
</ul>
<p>Given this, if you are going to deviate from React’s model you should do so with <em>enormous</em> caution. You must be aware of the endless graveyard of half-baked and failed solutions to these problems.</p>
<p>I will now give you my opinion: I think you are trying to impose structure where there needn’t be any. It is my decision whether to memoize or recompute a property, not yours. It is my decision whether that property should exist within a given render <em>at all</em>.</p>
<p>The purpose of a UI runtime is to allow me to write turing-complete code for my application. No matter how fancy your DSL, you are forcing me to statically declare computed properties at compile time and taking away my control over the execution of the program. This is fundamentally inexpressive.</p>
</blockquote>
</aside>
<p>Yeah, absolutely, we should be cautious about deviating from proven solutions.</p>
<p>That said, the React team operated under specific constraints: backwards compatibility, evolving from class components, and JavaScript’s dynamic runtime. Hologram leverages Elixir’s purely functional foundation with immutable data and compile-time metaprogramming - different foundations allow for different approaches.</p>
<p>However, I’d like to challenge your argument on two fronts:</p>
<p><strong>Challenge 1: Hooks don’t actually give you complete control and freedom.</strong></p>
<p>Hooks themselves have implicit rules and limitations that constrain how you write code. There are quite a few footguns:</p>
<p><strong>Only Call Hooks at the Top Level</strong></p>
<ul>
<li>Never call hooks inside loops, conditions, or nested functions</li>
<li>Hooks must be called in the same order on every render</li>
<li>This allows React to correctly preserve hook state between multiple <code>useState</code> and <code>useEffect</code> calls</li>
</ul>
<p><strong>Only Call Hooks from React Functions</strong></p>
<ul>
<li>Call hooks from React function components</li>
<li>Call hooks from custom hooks (functions starting with “use”)</li>
<li>Don’t call hooks from regular JavaScript functions</li>
</ul>
<p><strong>Hooks Must Be Called Unconditionally</strong></p>
<ul>
<li>You cannot conditionally execute a hook based on runtime logic</li>
<li>Bad: <code>if (condition) { useMemo(() =&gt; {}, []) }</code></li>
<li>Good: <code>useMemo(() =&gt; { if (condition) { /* logic */ } }, [])</code></li>
</ul>
<p>In practice, you kind of have <strong>two separate parts in the render() function</strong> - the hooks part at the top (with strict structure) and the “template” code at the bottom. I’d say that’s imposing structure already. It’s not that you can do whatever you want. You need to know what you’re doing and follow the rules.</p>
<p><strong>Challenge 2: The compile-time approach is essentially equivalent to useMemo through static analysis.</strong></p>
<p>I’d argue that a <code>derived</code> macro would be <strong>essentially equivalent to useMemo</strong> in terms of expressiveness. The <code>useMemo</code> dependency arrays are built from props and state. Hologram could determine these dependencies at compile-time through static analysis. For example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">derived :my_value do
  {my_prop, my_state.x.y}
end
</code></pre>
<p>Here Hologram could determine through compile-time dependency analysis that <code>my_value</code> depends on <code>my_prop</code> and <code>my_state.x.y</code> (so if only <code>my_state.x.z</code> changed, this wouldn’t need to recalculate).</p>
<p><strong>Not having to manually specify dependencies is actually more declarative, in my opinion.</strong> It removes boilerplate and prevents bugs through compile-time analysis (like missing dependencies in the dependency array, which is a common React bug).</p>
<p><strong>Regarding expressiveness:</strong> You mention that this DSL approach is “fundamentally inexpressive”. I agree that DSLs are generally less expressive than raw functions - but it depends on how close they stay to pure functions. The less constraint a DSL imposes, the less expressiveness you lose. In this case, the <code>derived</code> macro is essentially generating pure functions underneath - you’re writing the same functional code you would in useMemo. The difference is that you gain compile-time static analysis and eliminate the need to execute hook calls on each render. You’re not losing expressiveness; you’re trading runtime flexibility for compile-time guarantees and performance.</p>
<p><strong>I’m confident this compile-time approach handles typical scenarios (probably 99.9%) through appropriate dependency modeling.</strong> If there are common patterns you think require runtime flexibility that this wouldn’t cover, I’d be genuinely interested to understand them - but I suspect most real-world use cases map cleanly to this model.</p>
<p><strong>Additional benefit: Compile-time performance</strong></p>
<p>Moving derived values outside the render cycle and determining dependencies at compile-time eliminates runtime overhead. In React, every hook call (useMemo, useState, etc.) executes on each render - even if the memoized computation doesn’t re-run, there’s still overhead from calling the hook and checking dependencies. With compile-time analysis, this overhead disappears entirely, making the code both simpler and more efficient.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376496" 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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-376496" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376496"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="376500" data-post-id="376500">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="venkatd" data-post="17" data-topic="72968" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/venkatd/48/9419_2.png" class="avatar"> venkatd:</div>
<blockquote>
<p>I wholeheartedly agree with embracing React’s programming model.</p>
<p>The sense I got, though, is that <a class="mention" href="/u/bartblast" rel="nofollow">@bartblast</a> is really talking about memoization of function calls and not computed properties as signals are. What is your stance on the ability to memoize function calls?</p>
<p>It seems like there could be an ergonomic way to handle this with module attributes or a bit of macro syntax sugar.</p>
<p>If there is no memoization available, what would you propose?</p>
</blockquote>
</aside>
<p>I want to jump in here to clarify, since I think there’s some confusion about what I’m proposing.</p>
<p>You mentioned “memoization of function calls” versus “computed properties as signals are” - but I think this creates a false dichotomy. What I’m proposing is actually both, unified into a single pattern.</p>
<p>Here’s the key insight: <strong>signals as typically implemented in JavaScript frameworks don’t align with purely functional programming.</strong> Traditional signals use mutable observables - you mutate a signal’s value and side effects cascade through the dependency graph. That approach is incompatible with immutable data and pure functions.</p>
<p>However, signals/computed properties solve real problems:</p>
<ol>
<li><strong>Automatic dependency tracking</strong> - knowing what data a computation depends on</li>
<li><strong>Memoization with reactive updates</strong> - caching results and recalculating only when dependencies change</li>
</ol>
<p>What I’m proposing achieves these same goals but within functional programming constraints:</p>
<ul>
<li>Immutable data and pure functions (not mutable observables)</li>
<li>Compile-time dependency analysis (not runtime tracking)</li>
<li>Component-scoped (not potentially global)</li>
<li>Explicit state updates via actions (not implicit reactivity everywhere)</li>
</ul>
<p>So yes, I’m proposing reactive computed properties that solve the same problems as signals, but implemented with functional programming principles and compile-time analysis. It’s the same category of solution - just architecturally different because it needs to work within a purely functional paradigm.</p>
<p>An added benefit: this pattern lets you extract business logic from templates into small, focused, pure functions that are independently testable, while keeping templates clean and focused on presentation.</p>
<p>Hope that helps clarify!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376500" data-batch-url="/posts/batch_likers">
                        2
                      </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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-376500" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376500"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="376506" data-post-id="376506">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="jam" data-post="15" data-topic="72968" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jam/48/36266_2.png" class="avatar"> jam:</div>
<blockquote>
<p>fwiw, I like the svelte approach of making dependency tracking opt-out (using <code>untrack</code>) rather than opt-in.</p>
<p>I think this would be nice:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">derived :full_name do
  "#{first_name} #{last_name}"
end
</code></pre>
</blockquote>
</aside>
<p>I like it - it could provide great DX.</p>
<p>The key question: how much “magic” is acceptable to the Elixir community? Automatic dependency tracking through compile-time analysis removes boilerplate and prevents bugs (like missing deps in arrays). But is this too “revolutionary” for Elixir’s explicit culture?</p>
<p>I personally favor a holistic view and lean toward pragmatism over dogmatism. The philosophical question is: should we sacrifice practical benefits to avoid 0.1% of edge cases - cases that could still be handled through alternative approaches?</p>
<p><strong>Important</strong>: these are still pure Elixir functions underneath. The macro simply extracts business logic and enables compile-time analysis. It would generate testable functions like <code>derived_full_name/2</code> for isolated unit tests, plus perhaps <code>MyComponent.derived(state, props)</code> to test the entire computation graph, returning something like <code>%{full_name: "Bruce Wayne", ...}</code>.</p>
<p>I think this strikes a good balance - you get the convenience of automatic tracking while maintaining testability and the functional foundation Elixir developers expect.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376506" data-batch-url="/posts/batch_likers">
                        2
                      </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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-376506" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376506"
                     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 #19"></div>
  </section>
</div>
    <div class="postbit" id="376520" data-post-id="376520">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m fairly new to the Elixir community but my sense of it and the language itself is more along the lines of “pragmatic”. I hadn’t really considered “explicit” as a defining characteristic, particularly when it invokes macros in common places.</p>
<p>I do think keeping the “magic” to a minimum is a good idea and macros should be used sparingly and with good reason. IMO, this is a great opportunity to introduce some “magic” that provides a much better DX and has a relatively straightforward rule that can be digested and understood quickly.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376520" 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/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-376520" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376520"
                     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 #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/72968/load_more?page=3">Load more posts (21 remaining)</a>
</div></template></turbo-stream>