<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrey S Kalmatskiy</title>
    <description>The latest articles on DEV Community by Andrey S Kalmatskiy (@karol11).</description>
    <link>https://dev.to/karol11</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1130995%2F033e8f43-6d00-4525-a8d6-5940326ffb23.png</url>
      <title>DEV Community: Andrey S Kalmatskiy</title>
      <link>https://dev.to/karol11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karol11"/>
    <language>en</language>
    <item>
      <title>CardDOM in C++: Ownership, Cycles, and Smart Pointers</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Sat, 20 Sep 2025 21:02:58 +0000</pubDate>
      <link>https://dev.to/karol11/carddom-in-c-ownership-cycles-and-smart-pointers-5fdj</link>
      <guid>https://dev.to/karol11/carddom-in-c-ownership-cycles-and-smart-pointers-5fdj</guid>
      <description>&lt;p&gt;This is the third article in DOM-handling series.&lt;/p&gt;

&lt;p&gt;If you haven't read the prior parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/karol11/which-language-handles-dom-like-models-best-4e8l"&gt;Which Language Handles DOM-Like Models Best&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/karol11/building-a-dom-in-javascript-ownership-x-refs-and-copy-semantics-ojb"&gt;Building a DOM in JavaScript: Ownership, X-Refs, and Copy Semantics&lt;/a&gt;
you might want to start there for context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;C++ offers no garbage collector or borrow checker, but its smart pointers can model ownership hierarchies - if you treat them like the sharp tools they are. The challenge: building a DOM-ish structure (Document → Card → CardItem) that supports cross-references, shared immutable resources, and topological deep copies without leaks or undefined behavior.&lt;/p&gt;

&lt;p&gt;Result: A &lt;a href="https://www.mycompiler.io/view/G4ypqaNpDml" rel="noopener noreferrer"&gt;working C++ implementation of the CardDOM in ~150 LOC&lt;/a&gt; that survives Valgrind, enforces immutability at compile time, and auto-expires weak references - though it demands constant vigilance against pointer misuse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ownership and Reference Tracking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shared_ptrs&lt;/code&gt; holding all nodes, with runtime checks preventing multiparenting or cycles.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;weak_ptrs&lt;/code&gt; for cross-links (connectors, buttons) to ensure automatic expiry on deletion:&lt;/li&gt;
&lt;li&gt;No manual unlinking required; expired &lt;code&gt;weak_ptrs&lt;/code&gt; are safely handled with &lt;code&gt;.lock()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Parent pointers validated at runtime during add/remove to block self-nesting or duplicate parents.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Handling / Avoidance of Shared Mutable State
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Const &lt;code&gt;Style&lt;/code&gt; types enforce immutability at compile time, blocking direct mutation of shared resources.&lt;/li&gt;
&lt;li&gt;Copy-on-write via explicit &lt;code&gt;clone()&lt;/code&gt;: Mutations require creating a mutable copy first.&lt;/li&gt;
&lt;li&gt;No shared mutable state in the graph; reassigned clones become &lt;code&gt;const&lt;/code&gt; again post-mutation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Trade-Offs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No &lt;code&gt;unique_ptr&lt;/code&gt; for hierarchy roots: since all nodes of DOM-like structure can be targets of cross-references (weak-ptrs) this force &lt;code&gt;shared_ptr&lt;/code&gt; everywhere, complicating single ownership.&lt;/li&gt;
&lt;li&gt;Two-phase deep copy: Custom traversal needed to resolve topology and rewire weak_ptrs correctly.&lt;/li&gt;
&lt;li&gt;Discipline required: Smart pointers prevent use-after-free but not leaks from cycles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Safety Guarantees
&lt;/h2&gt;

&lt;h3&gt;
  
  
  From the Language/runtime
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Smart pointers automate deallocation and prevent use-after-free via reference counting.&lt;/li&gt;
&lt;li&gt;Const-correctness rejects mutable access to shared data at compile time.  But it does not prevent having const and non-const pointers to the same objects. In should be enforced manually.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Weak_ptr&lt;/code&gt; auto-expiry prevents dangling cross-references without explicit cleanup.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  From the Design
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Runtime exceptions on multiparenting/cycles maintain graph integrity during modifications.&lt;/li&gt;
&lt;li&gt;Stack reference protection: All params should be passed by value/reference to smart_ptrs; no raw pointer exposure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Size &amp;amp; Cognitive Overhead
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Size: ~150 LOC, focused on pointer management, assertions, and two-phase copy logic.&lt;/li&gt;
&lt;li&gt;Cognitive load: Every new DOM node must reimplement copy/add/drop-child logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//// Creation&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Times"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;16.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;card&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TextItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ButtonItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Click me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ConnectorItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GroupItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa6gf4oq0j7vypeigt33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpa6gf4oq0j7vypeigt33.png" alt="Newly created CardDOM" width="634" height="324"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Unshare-on-modification&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;hello_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dynamic_pointer_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TextItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Compile-time prevention of direct mutation:&lt;/span&gt;
&lt;span class="n"&gt;hello_text&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ERROR&lt;/span&gt;

&lt;span class="c1"&gt;// Explicit clone to mutate:&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;new_style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hello_text&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;new_style&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;hello_text&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Stack references prevent objects from being deleted&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;hello_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dynamic_pointer_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TextItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;remove_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hello_text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// hello_text is still alive here&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;dynamic_pointer_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ConnectorItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expired&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Actual deletion occurs here&lt;/span&gt;

&lt;span class="c1"&gt;// Topologically correct copy&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;new_doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deep_copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;
    &lt;span class="n"&gt;dynamic_pointer_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ConnectorItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;new_doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;
    &lt;span class="n"&gt;dynamic_pointer_cast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ButtonItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;new_doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;target_card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9l5pqh8bgpcigrqls0mh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9l5pqh8bgpcigrqls0mh.png" alt="A copy of the CardDOM document" width="634" height="542"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Runtime multiparenting prevention&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;runtime_error&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"multiparented!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Runtime cycle detection&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GroupItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;subgroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_shared&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GroupItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subgroup&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;subgroup&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;add_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;runtime_error&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"loop&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Evaluation Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory safety&lt;/td&gt;
&lt;td&gt;Avoids unsafe access patterns&lt;/td&gt;
&lt;td&gt;⚠️ Smart pointers block UAF; const prevents shared mutations, but raw pointer slips possible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leak prevention&lt;/td&gt;
&lt;td&gt;Avoids memory leaks&lt;/td&gt;
&lt;td&gt;⚠️ Reference counting + RAII handles most cases; cycles or forgotten drops need Valgrind&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ownership clarity&lt;/td&gt;
&lt;td&gt;Are ownership relations clear and enforced?&lt;/td&gt;
&lt;td&gt;⚠️ Shared_ptr enables cross-refs but blurs single ownership; runtime checks enforce rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy semantics&lt;/td&gt;
&lt;td&gt;Are copy/clone operations predictable and correct?&lt;/td&gt;
&lt;td&gt;⚠️ Manual two-phase deep_copy preserves topology and rewires &lt;code&gt;weak_ptrs&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weaks handling&lt;/td&gt;
&lt;td&gt;Survives partial deletions and dangling refs?&lt;/td&gt;
&lt;td&gt;✔️ Weak_ptrs expire automatically; no manual cleanup, stack refs extend lifetime safely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime resilience&lt;/td&gt;
&lt;td&gt;Can DOM ops crash app?&lt;/td&gt;
&lt;td&gt;⚠️ Exceptions on violations (multiparent, cycles); survives partial deletes via RAII&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code expressiveness&lt;/td&gt;
&lt;td&gt;Concise and maintainable?&lt;/td&gt;
&lt;td&gt;⚠️ Verbose pointer boilerplate offsets readable API; manual copy/loop logic adds overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ergonomic trade-offs&lt;/td&gt;
&lt;td&gt;Difficulty of enforcing invariants?&lt;/td&gt;
&lt;td&gt;❌ High; relies on developer discipline - no compile-time ownership beyond const&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Verdict
&lt;/h2&gt;

&lt;p&gt;C++ can model complex DOM-like graphs if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You standardize on &lt;code&gt;shared_ptr&lt;/code&gt; for cross-referenced nodes,&lt;/li&gt;
&lt;li&gt;Leverage const for compile-time immutability,&lt;/li&gt;
&lt;li&gt;Implement two-phase &lt;code&gt;deep_copy&lt;/code&gt; for topology-aware cloning,&lt;/li&gt;
&lt;li&gt;And cultivate pointer discipline with runtime guards and Valgrind.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's powerful but unforgiving - demanding vigilance.&lt;/p&gt;

&lt;p&gt;At 150 LOC, it proves modern C++ handles shared mutable structures robustly, though leaks and UB lurk for the unwary. Ref-counting languages like Rust offer similar foundations with panic-based safety nets, but neither category natively groks DOM topologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust: Honorable Mention
&lt;/h2&gt;

&lt;p&gt;Rust's borrow checker shines for stack values but falls back to ref-counting for heap graphs, mirroring C++'s smart pointers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Box&amp;lt;t&amp;gt;&lt;/code&gt; = &lt;code&gt;unique_ptr&amp;lt;t&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Rc&amp;lt;t&amp;gt;&lt;/code&gt; = &lt;code&gt;shared_ptr&amp;lt;const t&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Rc&amp;lt;RefCell&amp;lt;t&amp;gt;&amp;gt;&lt;/code&gt; ≈ &lt;code&gt;shared_ptr&amp;lt;t&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Weak&amp;lt;RefCell&amp;lt;t&amp;gt;&amp;gt;&lt;/code&gt; ≈ &lt;code&gt;weak_ptr&amp;lt;t&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Differences between languages are centered around idea of how to handle object disposal while it's still referenced from stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C++ risks UB (and almost always damages memory)&lt;/li&gt;
&lt;li&gt;Rust handles this situation in &lt;code&gt;RefCell.drop()&lt;/code&gt; and if &lt;code&gt;Rc&lt;/code&gt; is deleted while its inner &lt;code&gt;RefCell&lt;/code&gt; is in a borrowed state, it panics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So for DOMs, Rust adds safety via panics but sacrifices resilience and clarity.&lt;/p&gt;

&lt;p&gt;The bigger revelation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Almost every modern app depends on DOM-like structures.&lt;/li&gt;
&lt;li&gt;Yet no GC-languages (JS) nor ref-counted languages (C++) is truly equipped to handle them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next: &lt;/p&gt;

</description>
      <category>programming</category>
      <category>datastructures</category>
      <category>cpp</category>
      <category>rust</category>
    </item>
    <item>
      <title>Building a DOM in JavaScript: Ownership, X-Refs, and Copy Semantics</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Sun, 10 Aug 2025 19:06:37 +0000</pubDate>
      <link>https://dev.to/karol11/building-a-dom-in-javascript-ownership-x-refs-and-copy-semantics-ojb</link>
      <guid>https://dev.to/karol11/building-a-dom-in-javascript-ownership-x-refs-and-copy-semantics-ojb</guid>
      <description>&lt;p&gt;This is the &lt;strong&gt;second article&lt;/strong&gt; in my DOM-handling series.&lt;br&gt;&lt;br&gt;
If you haven’t read the first part - &lt;a href="https://dev.to/karol11/which-language-handles-dom-like-models-best-4e8l"&gt;Which Language Handles DOM-Like Models Best?&lt;/a&gt; - you might want to start there for context.&lt;/p&gt;




&lt;p&gt;JavaScript’s garbage collection frees you from explicit memory frees, but it won’t save you from "dangling" references to semi-destroyed objects, multiparenting, or topology corruption in complex object graphs.&lt;br&gt;&lt;br&gt;
Building a DOM-ish model (&lt;code&gt;Document → Card → CardItem&lt;/code&gt;) with predictable behavior means making &lt;strong&gt;manual decisions about ownership, weak references, and deep copying&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Design Decisions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Full JS solution (~330 LOC) here: 🔗 &lt;a href="https://jsfiddle.net/0tv5yj37/4/" rel="noopener noreferrer"&gt;https://jsfiddle.net/0tv5yj37/4/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Ownership and Reference Tracking&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parent pointers&lt;/strong&gt; (&lt;code&gt;parent&lt;/code&gt; field) enforce single ownership of a node at runtime.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registration sets&lt;/strong&gt; (&lt;code&gt;inboundButtons&lt;/code&gt;, &lt;code&gt;inboundConnectors&lt;/code&gt;) simulate weak references:

&lt;ul&gt;
&lt;li&gt;When an object is detached, it actively clears inbound links.
&lt;/li&gt;
&lt;li&gt;This prevents dangling references after deletion.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Detachment cascade&lt;/strong&gt; ensures that deleting a node cleans up all references &lt;em&gt;to&lt;/em&gt; it before it’s gone.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Handling / Avoidance of Shared Mutable State&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Shared &lt;code&gt;Style&lt;/code&gt; and &lt;code&gt;Bitmap&lt;/code&gt; instances are protected with &lt;code&gt;Object.freeze()&lt;/code&gt; to enforce immutability at runtime.
&lt;/li&gt;
&lt;li&gt;Copy-on-write is achieved via &lt;code&gt;mutateStyle()&lt;/code&gt; - editing a shared resource automatically clones it.
&lt;/li&gt;
&lt;li&gt;No shared mutable structures exist in the graph; all shared data is immutable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Trade-Offs&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual enforcement&lt;/strong&gt;: Because JavaScript won’t stop multiparenting or cycles, we must check on every &lt;code&gt;addItem()&lt;/code&gt; and &lt;code&gt;setParent()&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two-phase deep copy&lt;/strong&gt;: Required to preserve shared topology while creating new mutable nodes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive overhead&lt;/strong&gt;: The model spans ~330 LOC, much of it boilerplate for &lt;code&gt;deepCopy()&lt;/code&gt; and &lt;code&gt;resolve()&lt;/code&gt; methods.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Safety Guarantees&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;From the Language&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Garbage collection eliminates leaks from unreferenced objects (eventually).
&lt;/li&gt;
&lt;li&gt;No raw memory access, so undefined behavior from freed memory is impossible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;From the Design&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ghosting prevention&lt;/strong&gt; via explicit unlinking (&lt;code&gt;detach()&lt;/code&gt;): On object removal, cross-references are broken to ensure no part of the remaining object hierarchy can continue accessing the removed object in a "post-detached" non-working state.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime safety&lt;/strong&gt;: Invariant checks (&lt;code&gt;Card already has a parent&lt;/code&gt;, &lt;code&gt;Loop detected&lt;/code&gt;) ensure structural integrity.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topology safety&lt;/strong&gt;: Connectors and Buttons x-refs are nulled on detach and rewired on copy.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Code Size &amp;amp; Cognitive Overhead&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Size&lt;/strong&gt;: ~330 LOC, with most complexity in repetitive deep copy/resolve patterns.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive load&lt;/strong&gt;: Developers must understand the lifecycle of every object and call &lt;code&gt;detach()&lt;/code&gt; correctly; missing one leads to “ghost” references until GC eventually runs.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Usage&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//// This code throws exception - style is immutable&lt;/span&gt;
&lt;span class="c1"&gt;// doc.cards[0].items[0].style.font = "Helvetica";&lt;/span&gt;

&lt;span class="c1"&gt;// unshare on mutate:&lt;/span&gt;
&lt;span class="nx"&gt;myText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutateStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;font&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Helvetica&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Drop X-refs&lt;/span&gt;
&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;after item deleted and link lost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Result shows that "hello" text is removed both from card and connector.&lt;/span&gt;
&lt;span class="c1"&gt;// Cross-references are explicitly broken to prevent ghosting -&lt;/span&gt;
&lt;span class="c1"&gt;// no remaining part of the object hierarchy can access the removed item.&lt;/span&gt;

&lt;span class="c1"&gt;// Copy&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newDoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deepCopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;after copy, preserving button and connector links&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newDoc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Result: newDoc is structurally and data-wise identical to doc,&lt;/span&gt;
&lt;span class="c1"&gt;// though consisting of newly allocated objects.&lt;/span&gt;

&lt;span class="c1"&gt;// Safety net against multiparenting and cycles:&lt;/span&gt;
&lt;span class="c1"&gt;// The following code successfully compiles but crashes&lt;/span&gt;
&lt;span class="c1"&gt;// because of multiparenting attempt&lt;/span&gt;
&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newDoc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// This code compiles and runs&lt;/span&gt;
&lt;span class="c1"&gt;// because copy operation prevents multiparenting&lt;/span&gt;
&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;deepCopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newDoc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cards&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Evaluation Table&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Avoids unsafe access patterns&lt;/td&gt;
&lt;td&gt;⚠️ Safe from UAF/null deref by design; GC handles deallocation, though stack references can see partially destructed (detached) objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Leak prevention&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Avoids memory leaks&lt;/td&gt;
&lt;td&gt;⚠️ GC works eventually, with memory overhead and causes sudden pauses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ownership clarity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Are ownership relations clear and enforced?&lt;/td&gt;
&lt;td&gt;⚠️ Implemented in code, enforced only at runtime via exceptions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Copy semantics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Are copy/clone operations predictable and correct?&lt;/td&gt;
&lt;td&gt;⚠️ Manual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Weaks handling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Survives partial deletions and dangling refs?&lt;/td&gt;
&lt;td&gt;⚠️ Manual, via registration sets and detach cascade; detached objects remain visible to stack references but in a post-detached, non-working state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runtime resilience&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can DOM ops crash app?&lt;/td&gt;
&lt;td&gt;⚠️ Yes, if invariants violated (multiparent) - throws exception&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code expressiveness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Concise and maintainable?&lt;/td&gt;
&lt;td&gt;⚠️ Verbose; every class needs boilerplate deep copy and detach logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ergonomic trade-offs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Difficulty of enforcing invariants?&lt;/td&gt;
&lt;td&gt;❌ High; language offers no compile-time guarantees&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Verdict&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;JavaScript can host a reasonably safe DOM-like graph if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You &lt;em&gt;manually&lt;/em&gt; enforce ownership,
&lt;/li&gt;
&lt;li&gt;Treat “weak” links as opt-in and track them explicitly,
&lt;/li&gt;
&lt;li&gt;Accept that deep copy logic will be verbose,
&lt;/li&gt;
&lt;li&gt;And rely on runtime exceptions rather than compiler errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not fully safe, but it’s miles better than a manual memory handling.&lt;/p&gt;

&lt;p&gt;These conclusions can be applied to &lt;strong&gt;all GC-driven languages&lt;/strong&gt;, which is why I won’t test Java, Kotlin, C#, Python, Dart, Go, or TypeScript - although I welcome any examples in these languages proving that they have &lt;strong&gt;extra features&lt;/strong&gt; helping with DOM handling.&lt;/p&gt;

&lt;p&gt;Next stop - C++&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Which Language Handles DOM-Like Models Best?</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Sat, 09 Aug 2025 18:37:51 +0000</pubDate>
      <link>https://dev.to/karol11/which-language-handles-dom-like-models-best-4e8l</link>
      <guid>https://dev.to/karol11/which-language-handles-dom-like-models-best-4e8l</guid>
      <description>&lt;p&gt;Modern applications - from document editors to game engines from UI frameworks to databases - rely heavily on complex, interconnected data models to represent their internal state. These models often form what we call here &lt;strong&gt;DOM-like data structures&lt;/strong&gt;, which in their simplest form can be imagined as a familiar XML or JSON tree.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are DOM-Like Data Structures?
&lt;/h2&gt;

&lt;p&gt;DOM-like data structures are &lt;strong&gt;polymorphic, interconnected object graphs&lt;/strong&gt; characterized by three fundamental layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🌲 Tree of Ownership&lt;/strong&gt;
Objects are organized hierarchically, with each parent exclusively owning its children. This structure is acyclic and maps well to serialization formats like XML, JSON, or Protocol Buffers. It forms the backbone of many application data models, enforcing clear ownership boundaries and safe, exclusive containment.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🕸 Web of Weak References&lt;/strong&gt;
Beyond ownership, objects often need to reference each other without owning - think of a GUI control referencing the currently focused element, or a paragraph linked to an entry in a document's stylesheet. These are implemented as weak references to avoid circular ownership and memory leaks, forming a web of safe, non-owning links layered on the ownership tree.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧊 Directed Acyclic Graph (DAG) of Shared Immutable Resources&lt;/strong&gt;
Immutable resources like styles, fonts, or textures are shared across multiple nodes without duplication, following the flyweight pattern. This DAG layer sits at the bottom of the ownership tree and enables efficient reuse of common immutable data while maintaining acyclic dependencies.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Real-World Examples of DOM-Like Structures
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Game engines:&lt;/strong&gt; Scene graphs with nested spatial hierarchies of entities.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI frameworks:&lt;/strong&gt; Controls grouped into panels, windows, or forms.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MVC/MVVM architectures:&lt;/strong&gt; Loosely coupled models, views, and controllers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document editors:&lt;/strong&gt; Pages containing structured text flows, paragraphs, and styles.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Object databases:&lt;/strong&gt; Graphs of owned objects representing serialized data.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relational databases:&lt;/strong&gt; Tables with nested records and fields.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Why Modern Programming Languages Must Support DOM-Like Structures
&lt;/h3&gt;

&lt;p&gt;These DOM-like object graphs represent &lt;strong&gt;the foundational data model for modern, stateful, interactive applications&lt;/strong&gt;. Unlike flat or strictly hierarchical data, these structures are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large, mutable, and heterogeneous
&lt;/li&gt;
&lt;li&gt;Richly interconnected with complex dependencies
&lt;/li&gt;
&lt;li&gt;Combining ownership, sharing, and weak references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A programming language capable of &lt;strong&gt;modeling these structures safely, efficiently, and ergonomically&lt;/strong&gt; is better suited for real-world application development. Such languages should provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory safety&lt;/strong&gt; - no dangling pointers, use after free, double free
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leak prevention&lt;/strong&gt; - guarantees against memory and other resource leaks
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear ownership semantics&lt;/strong&gt; - ideally verified at compile time
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutability and controlled mutation&lt;/strong&gt; - support for immutable objects, efficient resource sharing, and automatic unsharing on mutation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe deletion&lt;/strong&gt; - modifying the DOM should never cause crashes, memory corruption, or undefined behavior, even if deleted objects are still referenced on the stack
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weak reference invalidation&lt;/strong&gt; - when an object is deleted, all cross-weak-references to it should automatically become invalid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Evaluating languages by their ability to handle these DOM-like models offers deeper insight into their practical suitability beyond traditional benchmarks.&lt;/p&gt;




&lt;h2&gt;
  
  
  How We’re Going to Test Languages
&lt;/h2&gt;

&lt;p&gt;Let's attempt a well-defined task to evaluate and compare how different programming languages handle DOM-like structures under a common set of structural constraints.&lt;/p&gt;

&lt;h3&gt;
  
  
  Task Definition
&lt;/h3&gt;

&lt;p&gt;Participants must implement a simplified DOM for a hypothetical card editor/player application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46vt7zdm54i8b7ro04d3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46vt7zdm54i8b7ro04d3.png" alt="App look" width="415" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This DOM consists of the following components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cards&lt;/strong&gt;, each containing a list of &lt;strong&gt;Card Items&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Card Items may be one of:

&lt;ul&gt;
&lt;li&gt;Styled text blocks
&lt;/li&gt;
&lt;li&gt;Images
&lt;/li&gt;
&lt;li&gt;Connectors with arrows (auto-routing)
&lt;/li&gt;
&lt;li&gt;Buttons for navigation between cards
&lt;/li&gt;
&lt;li&gt;Groups of card items (recursive containers)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1136ntth41ksupnsuek8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1136ntth41ksupnsuek8.png" alt="Object diagram" width="586" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Constraints and Invariants
&lt;/h3&gt;

&lt;p&gt;The implementation must enforce the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mutability.&lt;/strong&gt; Cards and elements must be mutable, supporting live updates of all their attributes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared Resources.&lt;/strong&gt; Styles and bitmaps can be shared across elements, cards, or documents. Modifying a shared resource must not affect unrelated elements - mutation must be explicit and localized (copy-on-write or unshare-on-mutate behavior).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ownership Structure&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Each &lt;strong&gt;Card&lt;/strong&gt; belongs to exactly one &lt;strong&gt;Document&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Each &lt;strong&gt;Element&lt;/strong&gt; belongs to exactly one &lt;strong&gt;Card&lt;/strong&gt; or &lt;strong&gt;Group&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Groups may be nested recursively.
&lt;/li&gt;
&lt;li&gt;A group cannot - directly or indirectly - contain itself.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connectors.&lt;/strong&gt; Connectors may target arbitrary elements. If a target is deleted, connectors must safely enter a detached state without crashing.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Button Navigation.&lt;/strong&gt; Buttons link to other cards. If a target card is deleted, referencing buttons become safely detached.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Safety&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;No use after free, uninitialized pointers, double free allowed.
&lt;/li&gt;
&lt;li&gt;No memory leaks allowed.
&lt;/li&gt;
&lt;li&gt;Deleting an object must not crash the program - even if references are still on the call stack.
&lt;/li&gt;
&lt;li&gt;Runtime resilience is critical; the app must remain stable, especially for sensitive domains like medical systems.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy Semantics.&lt;/strong&gt; Copy of cards and card items must maintain predictable reference semantics and preserve topology (e.g., connectors and buttons must keep the same topology of links after duplication).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Methodology
&lt;/h3&gt;

&lt;p&gt;Participants implement the DOM model in one or more languages, adhering to the constraints. They document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design decisions on ownership and reference tracking
&lt;/li&gt;
&lt;li&gt;Handling or avoidance of shared mutable state
&lt;/li&gt;
&lt;li&gt;Safety guarantees from the language or design
&lt;/li&gt;
&lt;li&gt;Trade-offs during implementation
&lt;/li&gt;
&lt;li&gt;Code size and cognitive overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A reference class diagram is suggested, though exact design and memory management can vary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rssnln1nqstrwcccgu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rssnln1nqstrwcccgu1.png" alt="Class diagram" width="711" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation Criteria
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory safety&lt;/td&gt;
&lt;td&gt;Avoids unsafe access patterns?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leak prevention&lt;/td&gt;
&lt;td&gt;Avoids memory leaks?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ownership clarity&lt;/td&gt;
&lt;td&gt;Are ownership relations clear and enforced by the language?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy semantics&lt;/td&gt;
&lt;td&gt;Are copy/clone operations predictable and correct?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weaks handling&lt;/td&gt;
&lt;td&gt;Does the app survive partial deletions and dangling references?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime resilience&lt;/td&gt;
&lt;td&gt;Can DOM operations cause app termination?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code expressiveness&lt;/td&gt;
&lt;td&gt;Is the code concise and maintainable?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ergonomic trade-offs&lt;/td&gt;
&lt;td&gt;How difficult is enforcing invariants in the language?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Everyone’s Invited
&lt;/h2&gt;

&lt;p&gt;If you have a favorite programming language to showcase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement this DOM-like model.&lt;/li&gt;
&lt;li&gt;Share what worked, what felt clunky, and where safety relied on discipline rather than language features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💬 &lt;strong&gt;Join the Experiment!&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Whether you’re a language enthusiast, a systems programmer, or simply curious, I invite you to participate, share your experiences, and help uncover which languages truly excel at managing modern, complex application state.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;In the upcoming posts, I’ll take a deep dive into implementing this DOM model in several widely used languages with very different memory and ownership systems. After that, I’ll explore other languages and compare their strengths and challenges.&lt;/p&gt;

&lt;p&gt;Let's discover a winner - or will we confirm that no acceptable solution exists yet?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Why Your Website in 2025 Should Stop Using Raster Icons</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Thu, 19 Jun 2025 19:15:30 +0000</pubDate>
      <link>https://dev.to/karol11/why-your-website-in-2025-should-stop-using-raster-icons-m8h</link>
      <guid>https://dev.to/karol11/why-your-website-in-2025-should-stop-using-raster-icons-m8h</guid>
      <description>&lt;p&gt;I feel a little awkward saying this - it seems like I’m stating the obvious - but even in 2025, we still see websites (including those backed by billions of dollars and the work of hundreds of developers and designers) using &lt;strong&gt;raster graphics for icons&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl42cykhlz8ml1q6bwpi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl42cykhlz8ml1q6bwpi0.png" alt="Google Drive and FB.com" width="555" height="458"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(Google Drive and FB.com)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Maybe companies shy away from vector graphics because they think it's too complicated.&lt;br&gt;
This article aims to briefly dispel those doubts: vector graphics are &lt;strong&gt;simple, stylish, and modern&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why SVG is the Right Choice
&lt;/h2&gt;

&lt;p&gt;Modern web development offers two main approaches for vector graphics: &lt;strong&gt;TTF/OpenType fonts&lt;/strong&gt; and &lt;strong&gt;SVG&lt;/strong&gt;.&lt;br&gt;
Here’s why SVG is better:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crisper rendering&lt;/strong&gt; at any size, including fractional scaling - fonts can blur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better accessibility&lt;/strong&gt; - screen readers ignore decorative SVGs by default (fonts can cause confusion).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No font loading delay&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: &lt;strong&gt;a modern website should be using SVG&lt;/strong&gt;, not custom fonts.&lt;/p&gt;
&lt;h2&gt;
  
  
  Inline vs. External SVGs
&lt;/h2&gt;

&lt;p&gt;You can use SVGs in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reference an external SVG file via &lt;code&gt;&amp;lt;img src="icon.svg"&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Embed the full SVG markup inside your HTML using the &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; tag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second method has major advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No extra downloads&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full style control&lt;/strong&gt; via CSS and JS (colors, strokes, filters).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, when pages contain many repeated icons, developers often include full copies of SVG markup inline. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstewjk8doc1hzomw8wqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstewjk8doc1hzomw8wqm.png" alt="It's hard to believe that each instance of this tiny globe icon has 1.5Kb of coordinates in text form" width="555" height="245"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(It's hard to believe that each instance of this tiny globe icon has 1.5Kb of coordinates in text form)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That &lt;strong&gt;needlessly bloats page size&lt;/strong&gt; and creates serious performance issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page size increases dramatically (see the above image).&lt;/li&gt;
&lt;li&gt;Every SVG fragment is &lt;strong&gt;parsed and rendered separately&lt;/strong&gt;, consuming CPU/GPU.&lt;/li&gt;
&lt;li&gt;Each instance occupies &lt;strong&gt;separate GPU memory&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  A Better Way: Define Symbols Once
&lt;/h2&gt;

&lt;p&gt;There’s a simple solution - define all your icons once at the top of your HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:none;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;defs&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;symbol&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"like-svg"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 170 170"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"#000"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M 74 122 L 31 81 ... Z"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Put the content of your SVG-file. --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;symbol&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"close-svg"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24 24"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"#fff"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt; &lt;span class="na"&gt;stroke-linecap=&lt;/span&gt;&lt;span class="s"&gt;"round"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;line&lt;/span&gt; &lt;span class="na"&gt;x1=&lt;/span&gt;&lt;span class="s"&gt;"17"&lt;/span&gt; &lt;span class="na"&gt;y1=&lt;/span&gt;&lt;span class="s"&gt;"7"&lt;/span&gt; &lt;span class="na"&gt;x2=&lt;/span&gt;&lt;span class="s"&gt;"7"&lt;/span&gt; &lt;span class="na"&gt;y2=&lt;/span&gt;&lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Same here- just an SVG-file data --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;line&lt;/span&gt; &lt;span class="na"&gt;x1=&lt;/span&gt;&lt;span class="s"&gt;"7"&lt;/span&gt; &lt;span class="na"&gt;y1=&lt;/span&gt;&lt;span class="s"&gt;"7"&lt;/span&gt; &lt;span class="na"&gt;x2=&lt;/span&gt;&lt;span class="s"&gt;"17"&lt;/span&gt; &lt;span class="na"&gt;y2=&lt;/span&gt;&lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- More symbols... --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/defs&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, whenever you need an icon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"main-icon"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"24"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"24"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#like-svg"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voila.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of This Method
&lt;/h2&gt;

&lt;p&gt;This approach gives you the best of all worlds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No delays from additional resource loading.&lt;/li&gt;
&lt;li&gt;No page size bloat from repeated code.&lt;/li&gt;
&lt;li&gt;Potential for &lt;strong&gt;symbol-level caching&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Full &lt;strong&gt;CSS/JS control&lt;/strong&gt; over transforms, scale, color, fill, stroke.&lt;/li&gt;
&lt;li&gt;Ability to &lt;strong&gt;compose complex icons&lt;/strong&gt; from layered elements.&lt;/li&gt;
&lt;li&gt;Support for **filters **like soft shadows or outlines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Native Light/Dark Theme Support with SVG
&lt;/h2&gt;

&lt;p&gt;One of SVG’s most powerful features is its &lt;strong&gt;automatic adaptation to light and dark themes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Replace fixed &lt;code&gt;fill/stroke&lt;/code&gt; in SVG with: &lt;code&gt;fill="currentColor"&lt;/code&gt; &lt;code&gt;stroke="currentColor"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assign icon color via CSS:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.main-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--iconColor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Define light/dark values:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--iconColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#225&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--iconColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#aaf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. &lt;strong&gt;No JS required&lt;/strong&gt; - your SVG icons will &lt;strong&gt;automatically recolor&lt;/strong&gt; based on the system theme using &lt;strong&gt;just one image&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example: latis.cc in light and dark mode&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8alkzjomvmdooi1y0c8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8alkzjomvmdooi1y0c8.png" alt="dark and light mode example" width="555" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;Using embedded &lt;code&gt;SVGs&lt;/code&gt; + &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; + &lt;code&gt;currentColor&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delivers &lt;strong&gt;instant, synchronous rendering&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enables &lt;strong&gt;GPU caching&lt;/strong&gt; of rendered images (depending on engine).&lt;/li&gt;
&lt;li&gt;Keeps your single-page app **lean **and removes all coordinate/geometry duplication.&lt;/li&gt;
&lt;li&gt;Allows you to style icons freely via CSS.&lt;/li&gt;
&lt;li&gt;Supports &lt;strong&gt;any scale or pixel density&lt;/strong&gt; - your UI won’t feel outdated.&lt;/li&gt;
&lt;li&gt;Supports any number of color schemes, with &lt;strong&gt;fill, stroke, and filters&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly: it’s much &lt;strong&gt;easier than it seems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, my &lt;a href="https://latis.cc" rel="noopener noreferrer"&gt;favorite community link sharing site, latis.cc&lt;/a&gt;, uses &lt;strong&gt;no raster graphics at all&lt;/strong&gt; — except for user-uploaded images.&lt;br&gt;
Even the &lt;strong&gt;logo and favicon are SVG&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is how nice and sleek it looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmphi6szhd72flzxfn8g6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmphi6szhd72flzxfn8g6.png" alt="Latis.cc 100% SVG" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Upcoming Topics
&lt;/h2&gt;

&lt;p&gt;A few things I plan to cover in future posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimizing SVG path coordinates - with a few simple tricks, you can reduce size &lt;strong&gt;up to 10×&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Implementing a **programmatic light/dark **theme toggle.&lt;/li&gt;
&lt;li&gt;Hosting icon atlases in &lt;strong&gt;external SVG files&lt;/strong&gt;, referencing them via &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; - useful for multi-page sites.&lt;/li&gt;
&lt;li&gt;Exploring SVG &lt;strong&gt;animations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Soft shadows with &lt;strong&gt;filters&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Bitmap icons got zero rizz, fr. SVGs only — no cap. 🧢✨&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>design</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Test Your Layout for Zoom — Not Just Screen Size</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Fri, 13 Jun 2025 01:40:09 +0000</pubDate>
      <link>https://dev.to/karol11/test-your-layout-for-zoom-not-just-screen-size-4867</link>
      <guid>https://dev.to/karol11/test-your-layout-for-zoom-not-just-screen-size-4867</guid>
      <description>&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/MDvRQzEFhC0"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;
&lt;br&gt;
Modern web design focuses on &lt;strong&gt;accessibility *&lt;em&gt;and **responsiveness *&lt;/em&gt;— but there's one crucial detail we often miss: **zoom adaptability&lt;/strong&gt;.&lt;br&gt;
🔍Users (especially 40+ or visually impaired) often set site zoom to 130+ to read comfortably. But many layouts &lt;strong&gt;break&lt;/strong&gt;: horizontal scroll, clipped text, hidden content, ellipses instead of info, that’s a UX failure.&lt;br&gt;
How to test:&lt;br&gt;
💡DevTools → mobile mode → set zoom at the top, next to sizes&lt;br&gt;
💡Check on real device - mobile browser main menu → zoom. Try zooming in/out ±60%. Your layout should flex — not break.&lt;br&gt;
Good news: with plain HTML/CSS, it’s easy to achieve:&lt;br&gt;
🔧Use flex and grid (with media queries for ≤240px)&lt;br&gt;
🔧Set sizes in fr, %, em&lt;br&gt;
🔧Avoid hardcoded widths and positions&lt;br&gt;
🔧Let containers auto-resize&lt;br&gt;
🔧Don’t fight the layout engine (but sometimes you need to fight managers and designers which love pixels).&lt;br&gt;
Zoom support is just as important as screen width adaptation — Your users (and their eyes) will thank you.

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>uxdesign</category>
      <category>a11y</category>
    </item>
    <item>
      <title>About Likes</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Mon, 09 Jun 2025 01:05:23 +0000</pubDate>
      <link>https://dev.to/karol11/about-likes-2lpg</link>
      <guid>https://dev.to/karol11/about-likes-2lpg</guid>
      <description>&lt;p&gt;"Like" is a button with a counter and a thumb-up icon. What function does it serve? It’s meant to rank posts and comments, helping to separate more valuable ones from less valuable ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the "like" is a UI/UX mistake
&lt;/h2&gt;

&lt;p&gt;The "like" was created in an earlier era when social networks were filled with posts like “me and my dog,” “my kids’ graduation,” or “me in Bali.” A valuable post or comment was simply one that many people liked: it simply brought them positive emotions. But times have changed. Nowadays social media is a space for social and political discourse, where difficult topics are raised and proposed solutions aren’t always soft or pleasant.&lt;/p&gt;

&lt;p&gt;Let’s consider the following image:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ha18wig7b08yol3elag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ha18wig7b08yol3elag.png" alt="Image description" width="482" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Be honest — does this post deserve public attention? Is it valuable? Now, another question: do you _like _the content of this post? Are you ready to hit this "like" button?&lt;/p&gt;

&lt;p&gt;The problem with the "like" is that it carries emotionally overloaded meaning and symbolism, while many posts and comments deserve public attention despite offering no pleasure. These posts don’t get likes, don't get high ranks, and simply vanish. Our problem is: we’ve conflated two concepts: a &lt;strong&gt;value indicator&lt;/strong&gt; and a positive &lt;strong&gt;emotional reaction&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How attempts to fix "likes" with "reactions" only made things worse
&lt;/h2&gt;

&lt;p&gt;Many modern platforms sensed this issue, but without understanding the root cause, they layered in more UI/UX: instead of the simple "like" button, they introduced lists of emotional reactions: anger, surprise, joy, sympathy...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why doesn’t this solve the problem?&lt;/strong&gt; The original like button was a value counter. Now we have 3 to 10 separate counters. How should we evaluate or compare comment values now? What formula should we use? Is 2 “angry” equal to 1 “happy”? Should we count them all equally? If a comment gets 5 “laugh” reactions — are people laughing &lt;em&gt;at&lt;/em&gt; it (mocking it, a downvote), or &lt;em&gt;with&lt;/em&gt; it (finding it funny, an upvote)? No one knows.&lt;/p&gt;

&lt;p&gt;Let’s take a look at another picture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fte976f0l1ia0hz1m0mkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fte976f0l1ia0hz1m0mkw.png" alt="Image description" width="341" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personally, I find the first 3 reactions nearly identical, and the next 4 could be (mis)interpreted as either upvotes or downvotes.&lt;/p&gt;

&lt;p&gt;So "reactions" come with &lt;strong&gt;three main problems&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There are too many to avoid confusion, yet too few to express the full emotional range.&lt;/li&gt;
&lt;li&gt;They duplicate what comments do better. And now, with voice input, swipe keyboards, and emoji palettes, writing a quick emotional comment is just as easy as picking a reaction.&lt;/li&gt;
&lt;li&gt;They fragment feedback into multiple independent counters — making clear, consistent ranking of posts and comments impossible.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How Latis.cc do it right
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The solution can be simple.&lt;/strong&gt; It comes from rethinking the purpose of the like counter: to reflect the value of a post or comment to the community.&lt;/p&gt;

&lt;p&gt;Let’s give our button a neutral label: "&lt;strong&gt;upvote&lt;/strong&gt;." If a post or comment presents an idea, upvoting means you agree — regardless of emotions. If it simply states an issue, upvoting means you’re helping to raise awareness.&lt;/p&gt;

&lt;p&gt;It’s simple and unambiguous.&lt;/p&gt;

&lt;p&gt;The only obstacle is that we’ve spent 20 years using the thumbs-up icon to represent a “like”, but we don’t yet have a universally accepted symbol for “upvote.” Here are a few options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤝 Handshake&lt;/li&gt;
&lt;li&gt;⬆️ Up arrow&lt;/li&gt;
&lt;li&gt;✅ Check mark&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s examine them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The handshake icon 🤝 is too complex. At 16×16px, it turns into a colorful blob. It’s also hard to recognize on small screens.&lt;/li&gt;
&lt;li&gt;An up-arrow icon ⬆️, when placed in the utility bar beneath a post (next to buttons like "reply," "go up one level," or "open in a new window") can easily be mistaken for a navigation element.&lt;/li&gt;
&lt;li&gt;That leaves the &lt;strong&gt;check mark&lt;/strong&gt; icon ✅, and that’s actually a good thing. It’s intuitive. Everyone understands voting. And if a check mark appears under a comment, its meaning is immediately clear.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The new version of &lt;a href="https://latis.cc" rel="noopener noreferrer"&gt;latis.cc&lt;/a&gt; replaced the “like” button with an upvote, and that’s the right move:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnmcwuzdv75x50s0nqce7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnmcwuzdv75x50s0nqce7.png" alt="Image description" width="484" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What do &lt;em&gt;you&lt;/em&gt; think — should other platforms make this shift?&lt;/p&gt;

</description>
      <category>ui</category>
      <category>web</category>
      <category>socialmedia</category>
    </item>
    <item>
      <title>Argentum programming language</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Thu, 08 Feb 2024 16:57:20 +0000</pubDate>
      <link>https://dev.to/karol11/argentum-programming-language-5509</link>
      <guid>https://dev.to/karol11/argentum-programming-language-5509</guid>
      <description>&lt;h2&gt;
  
  
  Bold statements
&lt;/h2&gt;

&lt;p&gt;A year ago I started developing Argentum - a new programming language that is safe, scalable, fast and tiny.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is memory safe, type safe, null-safe, array-index safe and so on. It is &lt;em&gt;safe&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;It automates memory management, so you will never deallocate objects manually.&lt;/li&gt;
&lt;li&gt;Unlike Rust and Swift it guarantees &lt;em&gt;absence&lt;/em&gt; of memory leaks and doesn't force you to use unsafe hacks.&lt;/li&gt;
&lt;li&gt;Unlike Java, Go, JS and Python, it doesn't use &lt;em&gt;garbage collector&lt;/em&gt;, so no sudden pauses and overheads.&lt;/li&gt;
&lt;li&gt;It has precise predictable object disposal moments so objects can control any resources, not just memory.&lt;/li&gt;
&lt;li&gt;It's compiled to machine code, producing tiny executables (with LLVM).&lt;/li&gt;
&lt;li&gt;It has &lt;em&gt;multithreading&lt;/em&gt; without deadlocks and data races.&lt;/li&gt;
&lt;li&gt;It is simple and expressive.&lt;/li&gt;
&lt;li&gt;And also it's crazy fast and memory-effective (I repeat myself).&lt;/li&gt;
&lt;li&gt;And its interop with C is mostly a pass-through.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ag language home: &lt;a href="https://aglang.org" rel="noopener noreferrer"&gt;https://aglang.org&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Status
&lt;/h2&gt;

&lt;p&gt;It's still in a prototyping phase. Syntax will definitely change and lots of features will be added in the future, but it's worth looking at right now.&lt;/p&gt;

&lt;p&gt;Nowadays Ag runs on and builds executables for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x86-64 Windows,&lt;/li&gt;
&lt;li&gt;x86-64 Linux,&lt;/li&gt;
&lt;li&gt;ARM64 Linux.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is integrated with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CURL&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;li&gt;SDL (window, image, ttf)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Give it a try
&lt;/h2&gt;

&lt;p&gt;This week I made a Web Playground for Argentum.&lt;br&gt;
Now it's possible to try it online without installing anything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqandftvller38e4ys1lm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqandftvller38e4ys1lm.jpg" alt="Argentum playground screenshot" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All details and a playground link: &lt;a href="https://aglang.org/playground/" rel="noopener noreferrer"&gt;https://aglang.org/playground/&lt;/a&gt;&lt;br&gt;
Happy hacking! :-)&lt;/p&gt;

</description>
      <category>programming</category>
      <category>language</category>
    </item>
    <item>
      <title>Managing Object Lifetimes Why it led to a new programming language "Argentum"</title>
      <dc:creator>Andrey S Kalmatskiy</dc:creator>
      <pubDate>Tue, 01 Aug 2023 17:52:42 +0000</pubDate>
      <link>https://dev.to/karol11/managing-object-lifetimes-why-it-led-to-a-new-programming-language-argentum-5h0n</link>
      <guid>https://dev.to/karol11/managing-object-lifetimes-why-it-led-to-a-new-programming-language-argentum-5h0n</guid>
      <description>&lt;p&gt;At the core of any modern programming language there lies a certain reference model, describing the data structures that applications will operate on. It defines how objects refer to each other, when an object can be deleted, and when and how an object can be modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Status quo
&lt;/h2&gt;

&lt;p&gt;Most modern programming languages are built on one of three reference models:&lt;/p&gt;

&lt;p&gt;The first category includes languages with manual memory management. Examples include C, C++, and Zig. In these languages, objects are manually allocated and deallocated, and pointers are simple memory addresses with no additional obligations.&lt;/p&gt;

&lt;p&gt;The second category includes languages with reference counting. These languages include Objective-C, Swift, partially Rust, C++ when using smart pointers, and some others. These languages allow for some level of automation in removing unnecessary objects. However, this automation comes at a cost. In a multithreaded environment, reference counters must be atomic, which can be expensive. Additionally, reference counting cannot handle all types of garbage. When object A refers to object B, and object B refers back to object A, such a circular reference cannot be removed by reference counting. Languages like Rust and Swift introduce additional non-owning references to address the issue of circular references, but this affects the complexity of object model and syntax.&lt;/p&gt;

&lt;p&gt;The third category encompasses most of the modern programming languages with automatic garbage collection, such as Java, JavaScript, Kotlin, Python, Lua, and more. In these languages, unnecessary objects are automatically removed, but there is a catch. The garbage collector consumes a significant amount of memory and processor time. It activates at random moments, causing the main program to pause. Sometimes this pause can be extensive, halting the program's execution entirely, while other times, it might be partial. There is no such thing as a garbage collector without pauses at all. And the only algorithm that scans the entire memory and halts the application for the entire duration of its operation can guarantee the collection of all garbage. In real-life scenarios, such garbage collectors are not used anymore due to their inefficiency. In modern systems, some garbage objects may not be removed at all.&lt;/p&gt;

&lt;p&gt;Indeed, the definition of unnecessary objects requires clarification. In GUI applications, if you remove a control element from a form that is subscribed to a timer event, it cannot be simply deleted because there is a reference to this object somewhere in the timer manager. As a result, the garbage collector will not consider such an object as garbage.&lt;/p&gt;

&lt;p&gt;As mentioned before, each of the three reference models has its drawbacks. In the first case, we face memory safety issues and memory leaks. In the second case, we encounter slow performance in a multithreaded environment and leaks due to circular references. In the third case, we experience sporadic program pauses, high memory and processor consumption, and the need for manual breaking of some references when an object is no longer needed. Additionally, reference counting and garbage collection systems do not allow for managing the lifetimes of other resources, such as open file descriptors, window identifiers, processes, fonts, and so on. These methods are designed solely for memory management.&lt;br&gt;
In essence, problems exist, and each of the current solutions have their flaws.&lt;/p&gt;
&lt;h2&gt;
  
  
  Proposal
&lt;/h2&gt;

&lt;p&gt;Let's try to build a reference model free from the aforementioned drawbacks. First, we need to gather requirements and examine how objects are actually used in programs, what programmers expect from object hierarchies, and how we can simplify and automate their work without sacrificing performance.&lt;/p&gt;

&lt;p&gt;Our industry has accumulated rich experience in designing data models. It can be said that this experience is generalized in the Universal Modeling Language (UML). UML introduces three types of relationships between objects: association, composition, and aggregation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Association&lt;/strong&gt;: This relationship occurs when one object knows about another, and can interact with it but without implying ownership.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composition&lt;/strong&gt;: This relationship occurs when one object exclusively owns another object. For example, a wheel belongs to a car, and it can only exist in one car at a time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregation&lt;/strong&gt;: This relationship involves shared ownership. For instance, when many people share the name "Andrew."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's break this down with more concrete examples:&lt;/p&gt;

&lt;p&gt;Database owns its tables, views, enumerations, and stored procedures. A table owns its records, column metadata, and indexes. A record owns its fields. In this case, all these relationships represent composition.&lt;/p&gt;

&lt;p&gt;Another example is a user interface form owning its controls, and a UI list owning its elements. A document owns its style tables, which, in turn, own page elements, and text blocks own paragraphs, which then own characters. Again, these relationships represent composition.&lt;/p&gt;

&lt;p&gt;Composition always forms a tree-like structure where each object has exactly one owner, and an object exists only as long as its owner references it. We always know when an object should be deleted, so we need no garbage collector nor reference counting for such references.&lt;/p&gt;

&lt;p&gt;Examples of association:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paragraphs of some document reference styles in the document's style sheets.&lt;/li&gt;
&lt;li&gt;Records in one database table referencing records in another table (assuming we have an advanced relational database where such relationships are encoded using a special data type, rather than foreign keys).&lt;/li&gt;
&lt;li&gt;GUI form's control elements linked in a tab traversal chain.&lt;/li&gt;
&lt;li&gt;Controls on a form referencing data models, which in turn reference controls in some reactive application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these associations are maintained by non-owning pointers. They do not prevent object deletion, but they must handle the deletion to ensure memory safety. The language should detect attempts to access objects through such references without checking for object loss.&lt;/p&gt;

&lt;p&gt;Aggregation is a bit tricky. The industry's best practices suggest that aggregation should generally be limited to immutable objects. Indeed, if an object has multiple owners from different hierarchies, modifying it can lead to bitter consequences in various unexpected parts of the program. There are even radical suggestions to completely exclude the use of aggregation, see &lt;a href="https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers" rel="noopener noreferrer"&gt;Google's coding style guidelines&lt;/a&gt;. Though aggregation can be valuable and appropriate in certain scenarios, for instance, the flyweight design pattern relies on aggregation. Another example, in Java, strings are immutable, allowing multiple objects to reference the same string safely.  Additionally, aggregates can be useful in a multithreaded environment where immutable objects can be safely shared between threads.&lt;/p&gt;

&lt;p&gt;It is interesting that a hierarchy of immutable objects linked by aggregating references cannot contain cycles. Each immutable object starts its life as mutable since it needs to be filled with data before being "frozen" and made immutable. As we have already seen, immutable objects cannot have cycles. Therefore, cycles in properly organized object hierarchies can only occur through non-owning associative references. While owning composition references always form a tree, and aggregating references form a directed acyclic graph (DAG). None of these structures require a garbage collector BTW.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Side Note: In other words, the main problem with existing reference models is that they allow the creation of data structures that contradict best practices of our industry and, as a consequence, lead to numerous issues with memory safety and memory leaks. Languages that use these models then struggle heroically with the consequences of their architecture without addressing the root causes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we design a programming language that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declaratively supports UML references,&lt;/li&gt;
&lt;li&gt;Automatically generates all operations on objects (copying, destruction, passing between threads, etc.) based on these declarations,&lt;/li&gt;
&lt;li&gt;Enforces the rules of using these references at compile time (one owner, immutability, checking for object loss, etc.),&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...then such a language will provide both memory safety and absence of memory leaks, eliminate garbage collector overheads, and significantly simplify the programmer's life. As objects will be deleted at predictable times, this will allow attaching resource management to the objects lifetimes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;In the experimental programming language Argentum (&lt;a href="https://aglang.org" rel="noopener noreferrer"&gt;https://aglang.org&lt;/a&gt;), the idea of UML references is implemented as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A class field marked with &lt;code&gt;"&amp;amp;"&lt;/code&gt; represents a non-owning reference (association).&lt;/li&gt;
&lt;li&gt;A field marked with &lt;code&gt;"*"&lt;/code&gt; represents a shared reference to an immutable object (aggregation).&lt;/li&gt;
&lt;li&gt;All other reference fields represent composition (such a field is the sole owner of a mutable object).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Scene&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// The `elements` field holds the `Array` object, that holds&lt;/span&gt;
   &lt;span class="c1"&gt;// a number of SceneItems. It's composition&lt;/span&gt;
   &lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SceneItem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="c1"&gt;// The 'focused' field references some `SceneItem`. No ownership&lt;/span&gt;
   &lt;span class="c1"&gt;// It's association&lt;/span&gt;
   &lt;span class="n"&gt;focused&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;SceneItem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;SceneItem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Style&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;SceneItem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Inheritance&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Composition: the string belongs to label&lt;/span&gt;

    &lt;span class="c1"&gt;// The `style` field references an immutable instance of `Style`&lt;/span&gt;
    &lt;span class="c1"&gt;// Its immutability allows to share it among multiple parents&lt;/span&gt;
    &lt;span class="c1"&gt;// It's aggregation&lt;/span&gt;
    &lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting class hierarchy:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3evyxi7qn9fdkb8u2go.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3evyxi7qn9fdkb8u2go.png" alt="Class diagram" width="555" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example (continued) object creation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Make a `Scene` instance and store it in a variable.&lt;/span&gt;
&lt;span class="c1"&gt;// `root` is a composite reference (with single ownership)&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Make a `Style` instance; fill it using a number of initialization methods;&lt;/span&gt;
&lt;span class="c1"&gt;// freeze it, making it immutable with the help of *-operator.&lt;/span&gt;
&lt;span class="c1"&gt;// and store it in a `normal` variable that  is an aggregation reference&lt;/span&gt;
&lt;span class="c1"&gt;// (So this `Style` instance is shareable)&lt;/span&gt;
&lt;span class="n"&gt;normal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Style&lt;/span&gt;&lt;span class="nf"&gt;.font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.weight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// Make a Label instance, initialize its fields and store it in a `scene.elements` collection&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.elements&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="nf"&gt;.at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.setStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Make a non-owning association link from `scene` to `Label`&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.focused&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.elements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resulting objects and interconnection hierarchy:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcloch10ioypvd05ahuox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcloch10ioypvd05ahuox.png" alt="Object connection diagram" width="754" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The constructed data structure provides several important integrity guarantees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.elements&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.elements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="c1"&gt;// Compilation error: the object Label can have only one owner.&lt;/span&gt;

&lt;span class="n"&gt;normal&lt;/span&gt;&lt;span class="py"&gt;.weight&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Compilation error: `normal` is an immutable object.&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.focused&lt;/span&gt;&lt;span class="nf"&gt;.hide&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Compilation error: there is no check-for and handling-of a lost `focused` reference.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But Argentum not only watches over the programmer (and slaps their wrists), it also helps.&lt;br&gt;
Let's try to fix the above compilation errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @-operator makes deep copies.&lt;/span&gt;
&lt;span class="c1"&gt;// Here we add a copy of the label to the scene.&lt;/span&gt;
&lt;span class="c1"&gt;// This copy references the copy of the text, but shares the same Style instance.&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.elements&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.elements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Make a mutable copy of the Style instance,&lt;/span&gt;
&lt;span class="c1"&gt;// modify its `weight`,&lt;/span&gt;
&lt;span class="c1"&gt;// freese this copy (make it immutable-shareable)&lt;/span&gt;
&lt;span class="c1"&gt;// and store it back to the variable `normal`.&lt;/span&gt;
&lt;span class="n"&gt;normal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.weight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Check if associative link pointes to the object and protect if from being deleted&lt;/span&gt;
&lt;span class="c1"&gt;// if it is not empty, call its method.&lt;/span&gt;
&lt;span class="c1"&gt;// after that remove the protection.&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="py"&gt;.focused&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="nf"&gt;.hide&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// if root.focused exists, hide _it_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All operations for copying, freezing, thawing, deletion, passing between threads, etc., are performed automatically. The compiler constructs these operations using objects fields' association-composition-aggregation declarations.&lt;br&gt;
For example the following construction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;newScene&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...makes the full deep copy of &lt;code&gt;Scene&lt;/code&gt; with correct topology of internal interconnections:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62ngg2b23ztnxy7tvv7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62ngg2b23ztnxy7tvv7a.png" alt="Automatically generated copy of the scene subtree with the preservation of the topology of internal references." width="754" height="712"&gt;&lt;/a&gt;&lt;br&gt;
Automatically generated copy of the scene subtree with the preservation of the topology of internal references.&lt;/p&gt;

&lt;p&gt;This operation follows well defined rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All sub-objects by composition references, that should have a single owner, are copied cascading.&lt;/li&gt;
&lt;li&gt;Objects that are marked as shared with aggregation references (e.g., Style) are not copied, but shared.&lt;/li&gt;
&lt;li&gt;In the copied scene, the 'focused' field correctly references the copy of the label, because copy operation distinguishes internal and external references:

&lt;ul&gt;
&lt;li&gt;All references to the objects that are not affected by this copy operation, point to the original.&lt;/li&gt;
&lt;li&gt;All internal references point to the copied instance preserving the topology of the original data structure.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Why Argentum automates operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It ensures memory safety&lt;/li&gt;
&lt;li&gt;It ensures absence of memory leaks (making the garbage collector unnecessary).&lt;/li&gt;
&lt;li&gt;It guarantees timely object deletion, enabling automatic management of resources other than RAM through RAII, like automatically closing files, sockets, handles, etc.&lt;/li&gt;
&lt;li&gt;It ensures the absence of corruptions in the logical structure of the object model.&lt;/li&gt;
&lt;li&gt;It relieves the programmer from the routine manual implementation of these operations.&lt;/li&gt;
&lt;li&gt;It makes the data structures and code virtual-memory-friendly. Because garbage doesn't pile up and is never evicted from RAM but instead disposed of in a timely manner.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Interim Results
&lt;/h2&gt;

&lt;p&gt;The Argentum language is built on a new, but already familiar UML reference model that is free from the limitations and drawbacks of garbage-collected, reference-counted, and manually memory-managed systems. As of today, the language includes: parameterized classes and interfaces, multithreading, control structures based on optional data types, fast type casts, very fast interface method calls, modularity and FFI. It ensures memory safety, type safety, absence of memory leaks, races, and deadlocks. It utilizes LLVM for code generation and produces stand-alone executable applications.&lt;/p&gt;

&lt;p&gt;Argentum is an experimental language. Much remains to be done: numerous code generation optimizations, bug fixes, test coverage, stack unwinding, improved debugger support, syntactic sugar, etc., but it is rapidly evolving, and the listed improvements are in the near future.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The project's homepage: &lt;a href="https://aglang.org" rel="noopener noreferrer"&gt;https://aglang.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The Windows demo can be found here &lt;a href="https://github.com/karol11/argentum/releases" rel="noopener noreferrer"&gt;github.com/karol11/argentum/releases&lt;/a&gt;: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next article I'm going to cover the semantics of operations on association-composition-aggregation (ACA-pointers) and their implementation in Argentum.&lt;/p&gt;

&lt;p&gt;Any questions and suggestions are warmly welcomed.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
