tag:github.com,2008:https://github.com/SymbolicML/DynamicExpressions.jl/releases Release notes from DynamicExpressions.jl 2025-07-26T18:58:47Z tag:github.com,2008:Repository/552482193/v2.3.0 2025-07-26T18:58:48Z v2.3.0 <h2>DynamicExpressions v2.3.0</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v2.2.1...v2.3.0">Diff since v2.2.1</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>Parse expressions without interpolation (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3265846847" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/137" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/137/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/137">#137</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v2.2.1 2025-06-27T11:07:10Z v2.2.1 <h2>DynamicExpressions v2.2.1</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v2.2.0...v2.2.1">Diff since v2.2.0</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>fix: precompilation warning (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3182111764" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/136" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/136/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/136">#136</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v2.2.0 2025-06-26T11:27:28Z v2.2.0 <h2>DynamicExpressions v2.2.0</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v2.1.0...v2.2.0">Diff since v2.1.0</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>feat: option to skip fused kernels (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3091589615" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/128" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/128/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/128">#128</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v2.1.0 2025-06-24T22:12:56Z v2.1.0 <h2>DynamicExpressions v2.1.0</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v2.0.1...v2.1.0">Diff since v2.0.1</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>fix: <code>default_node_type</code> should not prescribe degree (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3173046202" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/133" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/133/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/133">#133</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> <li>test: fix issue where test eval fails due to incomplete eval (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3173051070" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/134" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/134/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/134">#134</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v2.0.1 2025-06-20T11:37:29Z v2.0.1 <h2>DynamicExpressions v2.0.1</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v2.0.0...v2.0.1">Diff since v2.0.0</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>Permit n-argument operators (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3054125537" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/127" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/127/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/127">#127</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> <li>fix: recursive type inference issue (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3162906845" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/132" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/132/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/132">#132</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v2.0.0 2025-06-15T02:51:53Z v2.0.0 <p>DynamicExpressions.jl v2.0 introduces support for n-arity operators (nodes with arbitrary numbers of children), which required some breaking changes to implement. This guide will help you migrate your code from v1.x to v2.0.</p> <h2>Summary</h2> <ul> <li>Types <ul> <li><code>Node{T}</code> is now <code>Node{T,D}</code> where <code>D</code> is the maximum degree</li> <li><code>AbstractExpressionNode{T}</code> is now <code>AbstractExpressionNode{T,D}</code></li> <li><code>AbstractNode</code> is now <code>AbstractNode{D}</code></li> <li>Before, <code>Node{T}</code> had fields <code>l::Node{T}</code> and <code>r::Node{T}</code>. Now, the type is <code>Node{T,D}</code>, and it has the field <code>children::NTuple{D,Nullable{Node{T,D}}}</code>.</li> </ul> </li> <li>Accessors <ul> <li>You can now access children by index with <code>get_child(tree, i)</code> <ul> <li><code>tree.l</code> can now be written as <code>get_child(tree, 1)</code></li> <li><code>tree.r</code> can now be written as <code>get_child(tree, 2)</code></li> <li><em>note: you can access multiple children with <code>get_children(tree, Val(degree))</code></em></li> </ul> </li> <li>You can now set children by index with <code>set_child!(tree, child, i)</code> <ul> <li><code>tree.l = child</code> should now be written as <code>set_child!(tree, child, 1)</code></li> <li><code>tree.r = child</code> should now be written as <code>set_child!(tree, child, 2)</code></li> <li><em>note: you can set multiple children with <code>set_children!(tree, children)</code></em></li> </ul> </li> </ul> </li> <li>Constructors <ul> <li><code>Node{T}(; op=1, l=x)</code> should now be written as <code>Node{T}(; op=1, children=(x,))</code></li> <li><code>Node{T}(; op=1, l=x, r=y)</code> should now be written as <code>Node{T}(; op=1, children=(x, y))</code></li> <li>You may now use <code>Node{T,D}(; op=1, children=(x,))</code> to specify degree other than the default of 2.</li> </ul> </li> <li>OperatorEnum <ul> <li><code>OperatorEnum</code> (and <code>GenericOperatorEnum</code>) now uses a single <code>ops</code> field: this is a tuple of tuples, indexed by arity. <ul> <li><code>operators.unaops</code> is now written as <code>operators.ops[1]</code>, and <code>operators.binops</code> is now written as <code>operators.ops[2]</code>.</li> </ul> </li> <li><code>OperatorEnum(binary_operators=(+, -, *), unary_operators=(sin, cos))</code> can now be written as <code>OperatorEnum(2 =&gt; (+, -, *), 1 =&gt; (sin, cos))</code> <ul> <li>This API permits higher-arity operators: <code>OperatorEnum(1 =&gt; (sin, cos), 2 =&gt; (+, -, *), 3 =&gt; (fma, max))</code>.</li> </ul> </li> </ul> </li> </ul> <h2>Breaking Changes</h2> <p>The main breaking change is that <code>Node{T}</code> is now <code>Node{T,D}</code> where <code>D</code> is the <strong>maximum degree</strong> of any possible node in the tree. <code>node.degree</code> is <em>still</em> the same as before, and is such that <code>node.degree &lt;= D</code>.</p> <p>Similarly, <code>AbstractExpressionNode{T}</code> is now <code>AbstractExpressionNode{T,D}</code>, and <code>AbstractNode</code> is now <code>AbstractNode{D}</code>.</p> <p>Before, <code>Node{T}</code> had fields <code>l::Node{T}</code> and <code>r::Node{T}</code>. Now, it has a single combined field <code>children::NTuple{D,Nullable{Node{T,D}}}</code>. This is a tuple of wrapped node objects, which should be accessed with <code>get_child(tree, i)</code> and set with <code>set_child!(tree, child, i)</code>. However, the old getters and setters will still function for binary trees (<code>.l</code> and <code>.r</code>).</p> <p>You may now use <code>Node{T,D}(; op=1, children=(x,))</code> to specify degree other than the default of 2. However, the default <code>Node{T}(; op=1, children=(x,))</code> is still available and will result in type <code>Node{T,2}</code>.</p> <h3>Necessary Changes to Your Code</h3> <p>The main breaking change that requires some modifications is patterns that explicitly match <code>tree.degree</code> in conditional logic. The <code>tree.degree == 0</code> branch can be left alone, but higher arity nodes should be generalized.</p> <p>For code like this:</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# This pattern ONLY works for binary trees (degree ≤ 2) if tree.degree == 0 # leaf node elseif tree.degree == 1 # unary operator else # tree.degree == 2 # &lt;-- This violates the assumption in 2.0 # binary operator end"><pre><span class="pl-c"><span class="pl-c">#</span> This pattern ONLY works for binary trees (degree ≤ 2)</span> <span class="pl-k">if</span> tree<span class="pl-k">.</span>degree <span class="pl-k">==</span> <span class="pl-c1">0</span> <span class="pl-c"><span class="pl-c">#</span> leaf node</span> <span class="pl-k">elseif</span> tree<span class="pl-k">.</span>degree <span class="pl-k">==</span> <span class="pl-c1">1</span> <span class="pl-c"><span class="pl-c">#</span> unary operator</span> <span class="pl-k">else</span> <span class="pl-c"><span class="pl-c">#</span> tree.degree == 2 # &lt;-- This violates the assumption in 2.0</span> <span class="pl-c"><span class="pl-c">#</span> binary operator</span> <span class="pl-k">end</span></pre></div> <p>You have two options for upgrading</p> <ol> <li> <p>Constrain your type signatures: Use <code>::AbstractExpressionNode{T,2}</code> to only accept binary trees, and refuse higher-arity nodes</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function my_function(tree::AbstractExpressionNode{T,2}) where T if tree.degree == 0 # leaf elseif tree.degree == 1 # unary else # tree.degree == 2, guaranteed # binary end end"><pre><span class="pl-k">function</span> <span class="pl-en">my_function</span>(tree<span class="pl-k">::</span><span class="pl-c1">AbstractExpressionNode{T,2}</span>) <span class="pl-k">where</span> T <span class="pl-k">if</span> tree<span class="pl-k">.</span>degree <span class="pl-k">==</span> <span class="pl-c1">0</span> <span class="pl-c"><span class="pl-c">#</span> leaf</span> <span class="pl-k">elseif</span> tree<span class="pl-k">.</span>degree <span class="pl-k">==</span> <span class="pl-c1">1</span> <span class="pl-c"><span class="pl-c">#</span> unary </span> <span class="pl-k">else</span> <span class="pl-c"><span class="pl-c">#</span> tree.degree == 2, guaranteed</span> <span class="pl-c"><span class="pl-c">#</span> binary</span> <span class="pl-k">end</span> <span class="pl-k">end</span></pre></div> </li> <li> <p>Rewrite your code to be more generic. (<em>Note that for recursive algorithms, you can often do things with a <code>tree_mapreduce</code>, which already handles the general case.</em>)</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# 2: Handle arbitrary arity function my_function(tree::AbstractExpressionNode{T}) where T if tree.degree == 0 # leaf else # higher arity deg = tree.degree for i in 1:deg child = get_child(tree, i) # process child... end end end"><pre><span class="pl-c"><span class="pl-c">#</span> 2: Handle arbitrary arity</span> <span class="pl-k">function</span> <span class="pl-en">my_function</span>(tree<span class="pl-k">::</span><span class="pl-c1">AbstractExpressionNode{T}</span>) <span class="pl-k">where</span> T <span class="pl-k">if</span> tree<span class="pl-k">.</span>degree <span class="pl-k">==</span> <span class="pl-c1">0</span> <span class="pl-c"><span class="pl-c">#</span> leaf</span> <span class="pl-k">else</span> <span class="pl-c"><span class="pl-c">#</span> higher arity</span> deg <span class="pl-k">=</span> tree<span class="pl-k">.</span>degree <span class="pl-k">for</span> i <span class="pl-k">in</span> <span class="pl-c1">1</span><span class="pl-k">:</span>deg child <span class="pl-k">=</span> <span class="pl-c1">get_child</span>(tree, i) <span class="pl-c"><span class="pl-c">#</span> process child...</span> <span class="pl-k">end</span> <span class="pl-k">end</span> <span class="pl-k">end</span></pre></div> <p>However, normally what is done internally for max efficiency for the general approach is to use patterns like:</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@generated function my_function(tree::AbstractExpressionNode{T,D}) where {T,D} quote deg = tree.degree deg == 0 &amp;&amp; process_leaf(tree) Base.Cartesian.@nif( $deg, i -&gt; i == deg, i -&gt; let children = get_children(tree, Val(i)) # Now, `children` is a type-stable tuple of children end, ) end end"><pre><span class="pl-c1">@generated</span> <span class="pl-k">function</span> <span class="pl-en">my_function</span>(tree<span class="pl-k">::</span><span class="pl-c1">AbstractExpressionNode{T,D}</span>) <span class="pl-k">where</span> {T,D} <span class="pl-k">quote</span> deg <span class="pl-k">=</span> tree<span class="pl-k">.</span>degree deg <span class="pl-k">==</span> <span class="pl-c1">0</span> <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">process_leaf</span>(tree) Base<span class="pl-k">.</span>Cartesian<span class="pl-k">.</span><span class="pl-c1">@nif</span>( <span class="pl-k">$</span>deg, i <span class="pl-k">-&gt;</span> i <span class="pl-k">==</span> deg, i <span class="pl-k">-&gt;</span> <span class="pl-k">let</span> children <span class="pl-k">=</span> <span class="pl-c1">get_children</span>(tree, <span class="pl-c1">Val</span>(i)) <span class="pl-c"><span class="pl-c">#</span> Now, `children` is a type-stable tuple of children</span> <span class="pl-k">end</span>, ) <span class="pl-k">end</span> <span class="pl-k">end</span></pre></div> <p>Note that the <code>@generated</code> is needed to pass <code>D</code> to the Cartesian macro.</p> </li> </ol> <h2>Property Access (Non-Breaking)</h2> <p>Note: <code>.l</code> and <code>.r</code> property access still work and will continue to be supported on types with <code>D == 2</code>. However, the generic accessors are more flexible, so upgrading to them is recommended.</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# old_child = tree.l old_child = get_child(tree, 1) # tree.r = new_child set_child!(tree, new_child, 2)"><pre><span class="pl-c"><span class="pl-c">#</span> old_child = tree.l</span> old_child <span class="pl-k">=</span> <span class="pl-c1">get_child</span>(tree, <span class="pl-c1">1</span>) <span class="pl-c"><span class="pl-c">#</span> tree.r = new_child</span> <span class="pl-c1">set_child!</span>(tree, new_child, <span class="pl-c1">2</span>)</pre></div> <p>This lets you write code that prescribes arbitrary arity.</p> <h2>Node Construction (Non-Breaking)</h2> <p>For binary trees, you can still use the syntax:</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="x = Node{Float64}(; feature=1) tree = Node{Float64}(; op=1, children=(x,))"><pre>x <span class="pl-k">=</span> <span class="pl-c1">Node</span><span class="pl-c1">{Float64}</span>(; feature<span class="pl-k">=</span><span class="pl-c1">1</span>) tree <span class="pl-k">=</span> <span class="pl-c1">Node</span><span class="pl-c1">{Float64}</span>(; op<span class="pl-k">=</span><span class="pl-c1">1</span>, children<span class="pl-k">=</span>(x,))</pre></div> <p>For higher-arity trees, you may pass <code>D</code> to specify the maximum degree in the tree:</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="x = Node{Float64,3}(; feature=1) y = Node{Float64,3}(; feature=2) z = Node{Float64,3}(; feature=3) tree = Node{Float64,3}(; op=1, children=(x, y, z))"><pre>x <span class="pl-k">=</span> <span class="pl-c1">Node</span><span class="pl-c1">{Float64,3}</span>(; feature<span class="pl-k">=</span><span class="pl-c1">1</span>) y <span class="pl-k">=</span> <span class="pl-c1">Node</span><span class="pl-c1">{Float64,3}</span>(; feature<span class="pl-k">=</span><span class="pl-c1">2</span>) z <span class="pl-k">=</span> <span class="pl-c1">Node</span><span class="pl-c1">{Float64,3}</span>(; feature<span class="pl-k">=</span><span class="pl-c1">3</span>) tree <span class="pl-k">=</span> <span class="pl-c1">Node</span><span class="pl-c1">{Float64,3}</span>(; op<span class="pl-k">=</span><span class="pl-c1">1</span>, children<span class="pl-k">=</span>(x, y, z))</pre></div> <h2>OperatorEnum redesign (Non-Breaking)</h2> <p><code>OperatorEnum</code> (and <code>GenericOperatorEnum</code>) now uses a single <code>ops</code> field: this is a tuple of tuples, indexed by arity. <code>operators.unaops</code> is now written as <code>operators.ops[1]</code>, and <code>operators.binops</code> is now written as <code>operators.ops[2]</code>.</p> <p>However, the properties are aliased, so the old syntax will still work.</p> <p>Along with this, there is a new API for constructing <code>OperatorEnum</code>s:</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# operators = OperatorEnum(binary_operators=(+, -, *), unary_operators=(sin, cos)) # old operators = OperatorEnum(2 =&gt; (+, -, *), 1 =&gt; (sin, cos))"><pre><span class="pl-c"><span class="pl-c">#</span> operators = OperatorEnum(binary_operators=(+, -, *), unary_operators=(sin, cos)) # old</span> operators <span class="pl-k">=</span> <span class="pl-c1">OperatorEnum</span>(<span class="pl-c1">2</span> <span class="pl-k">=&gt;</span> (<span class="pl-k">+</span>, <span class="pl-k">-</span>, <span class="pl-k">*</span>), <span class="pl-c1">1</span> <span class="pl-k">=&gt;</span> (sin, cos))</pre></div> <p>This API permits higher-arity operators:</p> <div class="highlight highlight-source-julia notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="operators = OperatorEnum(1 =&gt; (sin, cos), 2 =&gt; (+, -, *), 3 =&gt; (fma, max))"><pre>operators <span class="pl-k">=</span> <span class="pl-c1">OperatorEnum</span>(<span class="pl-c1">1</span> <span class="pl-k">=&gt;</span> (sin, cos), <span class="pl-c1">2</span> <span class="pl-k">=&gt;</span> (<span class="pl-k">+</span>, <span class="pl-k">-</span>, <span class="pl-k">*</span>), <span class="pl-c1">3</span> <span class="pl-k">=&gt;</span> (fma, max))</pre></div> <p>(Note that the order you pass the pairs is not important.)</p> <p><strong>Full Changelog</strong>: <a class="commit-link" href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v1.10.3...v2.0.0"><tt>v1.10.3...v2.0.0</tt></a></p> MilesCranmer tag:github.com,2008:Repository/552482193/v1.10.3 2025-06-14T21:11:48Z v1.10.3 <h2>DynamicExpressions v1.10.3</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v1.10.2...v1.10.3">Diff since v1.10.2</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>fix: mutation error for Zygote (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3146666563" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/130" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/130/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/130">#130</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> <li>fix: move non_differentiable to special module for JET masking (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3146692419" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/131" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/131/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/131">#131</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v1.10.2 2025-05-23T21:39:52Z v1.10.2 <h2>DynamicExpressions v1.10.2</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v1.10.1...v1.10.2">Diff since v1.10.1</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>CompatHelper: bump compat for Zygote in [weakdeps] to 0.7, (keep existing compat) (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="2769067944" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/119" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/119/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/119">#119</a>) (@github-actions[bot])</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v1.10.1 2025-04-29T10:56:01Z v1.10.1 <h2>DynamicExpressions v1.10.1</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v1.10.0...v1.10.1">Diff since v1.10.0</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>fix: avoid returning view for generic operators (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="3027788036" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/126" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/126/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/126">#126</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot] tag:github.com,2008:Repository/552482193/v1.10.0 2025-02-28T20:38:03Z v1.10.0 <h2>DynamicExpressions v1.10.0</h2> <p><a href="https://github.com/SymbolicML/DynamicExpressions.jl/compare/v1.9.4...v1.10.0">Diff since v1.9.4</a></p> <p><strong>Merged pull requests:</strong></p> <ul> <li>Fix minute typo (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="2783799233" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/120" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/120/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/120">#120</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/sunxd3/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/sunxd3">@sunxd3</a>)</li> <li>feat: allow separate operator names for pretty printing (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="2887914438" data-permission-text="Title is private" data-url="https://github.com/SymbolicML/DynamicExpressions.jl/issues/122" data-hovercard-type="pull_request" data-hovercard-url="/SymbolicML/DynamicExpressions.jl/pull/122/hovercard" href="https://github.com/SymbolicML/DynamicExpressions.jl/pull/122">#122</a>) (<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/MilesCranmer/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/MilesCranmer">@MilesCranmer</a>)</li> </ul> github-actions[bot]