<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - software-design</title>
    <link>https://emresahin.net/tags/software-design/</link>
    <description>Posts in the software-design tag</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/tags/software-design/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>bits 14</title>
      <published>2025-03-12T10:51:28+00:00</published>
      <updated>2025-03-12T10:51:28+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Wed, 12 Mar 2025 10:51:28 +0000</pubDate>
      <link>https://emresahin.net/bits-14/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-14/</guid>
      <description>There are three key points highlighted in How to Build Good Software : Reusing good software is easy; it is what allows you to build good things quickly; Software is limited not by the amount of resources put into building it, but by how complex it can get before it breaks down; and The main valu...</description>
      <category>project-management</category>
      <category>engineering</category>
      <category>software</category>
      <category>knowledge accumulation</category>
      <category>organizations</category>
      <category>software-design</category>
      <content:encoded><![CDATA[<p>There are three key points highlighted in <a href="https://knowledge.csc.gov.sg/ethos-issue-21/how-to-build-good-software/">How to Build Good Software</a>:</p>
<blockquote>
<ul>
<li>Reusing good software is easy; it is what allows you to build good things quickly;</li>
<li>Software is limited not by the amount of resources put into building it, but by how complex it can get before it breaks down; and</li>
<li>The main value in software is not the code produced, but the knowledge accumulated by the people who produced it.</li>
</ul>
</blockquote>
<p>These points lead me to view software development as more of a social profession than a purely technical one. Good software is a reflection of healthy interactions within an organization. When communication is difficult, it becomes much harder to accumulate knowledge about organizational needs, manage complexity, and effectively reuse software components.</p>]]></content:encoded>
    </item>
    <item>
      <title>Software architecture as a tree</title>
      <published>2022-05-12T04:33:08+00:00</published>
      <updated>2022-05-12T04:33:08+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Thu, 12 May 2022 04:33:08 +0000</pubDate>
      <link>https://emresahin.net/Execution-and-memory-as-a-tree/</link>
      <guid isPermaLink="true">https://emresahin.net/Execution-and-memory-as-a-tree/</guid>
      <description>In Rust, there are several ways to manage memory. Memory has two regions: One is called the stack . Each new scope (between { and } ) adds variables to the stack. Variables on the stack are allocated at once when a new scope is introduced, and they are freed when the scope ends. This brings speed...</description>
      <category>Software Architecture</category>
      <category>Memory Management</category>
      <category>Rust</category>
      <category>Memory Management</category>
      <category>Stack</category>
      <category>Heap</category>
      <category>Tree</category>
      <category>Concurrency</category>
      <category>Software Design</category>
      <content:encoded><![CDATA[<p>In Rust, there are several ways to manage memory. Memory has two regions:
One is called the <em>stack</em>. Each new scope (between <code>{</code> and <code>}</code>) adds variables to
the stack. Variables on the stack are allocated at once when a new scope is
introduced, and they are freed when the scope ends. This brings speed.
Variables on the stack are also allocated contiguously, so they are <em>more
compatible</em> with the principle of locality.</p>
<pre><code>{
  var1
  var2
  {
    var3
    var4
  }
}
</code></pre>
<p>The inner scope variables can’t be accessed by the outer scope, but outer
scope variables can be accessed by the inner scope. When we are in the inner
scope, the stack contains both scopes’ variables. Stack-based memory
management can be called table d’hôte. It’s faster and simpler.</p>
<p>However, in order to allocate them at once, variable sizes must be known
beforehand. If the compiler doesn’t know the size of an array, it can’t
allocate the array on the stack. We need another method to use these <em>indefinite</em>
variables.</p>
<p>The other way of obtaining memory is using the <em>heap</em>. The heap is independent of
the scope. You can allocate and fill it when you need with a size determined
at runtime, share it with other scopes, and free it à la carte. Rust
provides several different ways to manage memory on the heap.</p>
<p>In my experience, making the program flow as scoped as possible without cross-cutting
memory management is a good sign. Ideally, a program should have a tree-like
flow of execution, and the number of heap allocations is minimized in this
case. However, most modern software systems are not designed this way, and
memory management is not considered during the requirements phase. When you
leave this to a garbage collector, even if it does its best, memory management often
remains haphazard.</p>
<p>Ideally, when you run the program, it should call a series of functions that
branch into further sub-functions:</p>
<pre class="mermaid">
flowchart LR

  main---&gt;fn1
  main---&gt;fn2
  main---&gt;fn3
  main---&gt;fn4
  fn1---&gt;fn1.1
  fn1---&gt;fn1.2
  fn1---&gt;fn1.3
  fn1---&gt;fn1.4
  fn2---&gt;fn2.1
  fn2---&gt;fn2.2
  fn2---&gt;fn2.3
  fn2---&gt;fn2.4

  fn1.1--&gt;fn1.1.1
  fn1.1--&gt;fn1.1.2
  fn1.1--&gt;fn1.1.3
  fn1.1--&gt;fn1.1.4
  fn1.1--&gt;fn1.1.5


</pre>

<p>If we adhere to this principle, building concurrent software becomes a lot
easier, too. If the functionality and memory of <code>fn1.1.1</code> and <code>fn2</code> are
completely separate, these can be run in parallel. Hence, our aim in
<em>software architecture</em> must be looking for ways to represent the problem at
hand as a tree structure, both physically (for memory) and temporally
(for execution).</p>]]></content:encoded>
    </item>
  </channel>
</rss>
