<?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: Dimitrii Lyomin</title>
    <description>The latest articles on DEV Community by Dimitrii Lyomin (@lemind).</description>
    <link>https://dev.to/lemind</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2057058%2Fa74a5b31-2eaf-4418-86f6-83e29172935a.jpg</url>
      <title>DEV Community: Dimitrii Lyomin</title>
      <link>https://dev.to/lemind</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lemind"/>
    <language>en</language>
    <item>
      <title>Grounding doesn't guarantee a warranted conclusion. A model can satisfy every "cite real evidence" rule and still hallucinate a diagnosis from someone simply saying "I don't know." Here's the three-line fix, and the part I still can't prove generalizes.</title>
      <dc:creator>Dimitrii Lyomin</dc:creator>
      <pubDate>Wed, 17 Jun 2026 08:46:59 +0000</pubDate>
      <link>https://dev.to/lemind/grounding-doesnt-guarantee-a-warranted-conclusion-a-model-can-satisfy-every-cite-real-evidence-2592</link>
      <guid>https://dev.to/lemind/grounding-doesnt-guarantee-a-warranted-conclusion-a-model-can-satisfy-every-cite-real-evidence-2592</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/lemind/my-bias-detector-found-cherry-picking-in-the-answer-no-info-9hf" class="crayons-story__hidden-navigation-link"&gt;My Bias Detector Found "Cherry-Picking" in the Answer "No Info"&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/lemind" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F2057058%2Fa74a5b31-2eaf-4418-86f6-83e29172935a.jpg" alt="lemind profile" class="crayons-avatar__image" width="555" height="570"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/lemind" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Dimitrii Lyomin
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Dimitrii Lyomin
                
              
              &lt;div id="story-author-preview-content-3906996" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/lemind" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2057058%2Fa74a5b31-2eaf-4418-86f6-83e29172935a.jpg" class="crayons-avatar__image" alt="" width="555" height="570"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Dimitrii Lyomin&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/lemind/my-bias-detector-found-cherry-picking-in-the-answer-no-info-9hf" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 17&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/lemind/my-bias-detector-found-cherry-picking-in-the-answer-no-info-9hf" id="article-link-3906996"&gt;
          My Bias Detector Found "Cherry-Picking" in the Answer "No Info"
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/llm"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;llm&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/promptengineering"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;promptengineering&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/machinelearning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;machinelearning&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/lemind/my-bias-detector-found-cherry-picking-in-the-answer-no-info-9hf#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>llm</category>
      <category>nlp</category>
      <category>rag</category>
    </item>
    <item>
      <title>My Bias Detector Found "Cherry-Picking" in the Answer "No Info"</title>
      <dc:creator>Dimitrii Lyomin</dc:creator>
      <pubDate>Wed, 17 Jun 2026 08:24:07 +0000</pubDate>
      <link>https://dev.to/lemind/my-bias-detector-found-cherry-picking-in-the-answer-no-info-9hf</link>
      <guid>https://dev.to/lemind/my-bias-detector-found-cherry-picking-in-the-answer-no-info-9hf</guid>
      <description>&lt;p&gt;A few months ago I started a small pet project called Biassemble: feed it a personal story, ask a few follow-up questions, and have it flag possible cognitive biases in how the person reasoned about what happened.&lt;br&gt;
Nothing groundbreaking. I'd been working as a frontend engineer for a while and wanted hands-on time with LLM systems — structured outputs, evaluation, the stuff everyone now files under "LLM engineering." Biassemble was an excuse to learn by building, not a startup idea. I wasn't sure I wanted to move into AI work full time. I just wanted a project that would force me to find out.&lt;br&gt;
It found out for me — just not the way I expected.&lt;/p&gt;
&lt;h2&gt;
  
  
  The story that broke everything
&lt;/h2&gt;

&lt;p&gt;One of my early test stories looked like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anna opened the door at 8:00 AM. She poured coffee into a blue mug. The mug held 350 milliliters. She drank it black. At 8:15 AM, she walked to the bus stop. The bus arrived at 8:22 AM. She sat in the third row by the window. The bus traveled for 17 minutes. Anna exited at Main Street and walked 240 meters to her office. She arrived at 8:42 AM. Her desk had a computer, a notebook, and one pen. The pen was black. She started typing at 8:43 AM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No opinions, no decisions, no emotional content — just a sequence of facts.&lt;br&gt;
For this story, the system generated four follow-up questions about my own interpretations of Anna's morning. Every answer I gave was the same: no info. There was nothing to interpret. I hadn't drawn any conclusions about Anna, her coffee, or her commute.&lt;/p&gt;

&lt;p&gt;The original prompt's instruction was almost verbatim: "Detect at least one bias from the catalog." On a story like Anna's, that instruction meant the system was always going to return something — whether or not there was anything to find.&lt;/p&gt;
&lt;h2&gt;
  
  
  The first fix: ask for help, add grounding
&lt;/h2&gt;

&lt;p&gt;I asked an LLM what was wrong. The suggestion was reasonable: add a structured reasoning trace, and require every bias to cite grounded evidence from the story or answers. That became prompt version 1.0.0 — a story analysis step, ranked interpretations, bias hypotheses, an evidence-mapping step, and a &lt;code&gt;noBiasDetected&lt;/code&gt; flag for when nothing applies.&lt;/p&gt;

&lt;p&gt;All of it lives inside a single structured object the prompt calls &lt;code&gt;reasoningTrace&lt;/code&gt; — story analysis, interpretations, bias hypotheses, and evidence mapping, generated alongside the user-facing assessment.&lt;/p&gt;

&lt;p&gt;On paper, this should have fixed the Anna problem. No grounded evidence, no bias.&lt;br&gt;
Here's what it actually returned, run on the Anna story with all four follow-up answers as "no info":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cherry-Picking — The user consistently responded "no info" to questions requiring interpretation or subjective analysis, suggesting a selective presentation of information that focuses only on stated facts and avoids deeper inference. This pattern across multiple questions indicates a deliberate omission of interpretive data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I read that twice. The evidence requirement was technically satisfied — I really had answered "no info" four times, verbatim, exactly as cited. The system hadn't invented a quote. It had taken a real one and built a diagnosis out of it: declining to speculate was itself evidence of a reasoning error.&lt;br&gt;
&lt;strong&gt;Grounding made the citations honest. It didn't make the conclusions warranted.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Telling the system what doesn't count
&lt;/h2&gt;

&lt;p&gt;The fix here wasn't more grounding — it was defining what grounding means.&lt;br&gt;
Version 1.1.0 added an explicit list of things that are not, by themselves, evidence of bias: factual descriptions, neutral observations, uncertainty, and specifically — saying "I don't know," saying "no info," refusing to speculate.&lt;br&gt;
It added a Step 0: before generating any interpretations, decide whether the story contains psychological material at all — beliefs, judgments, predictions, decisions. If not, stop there.&lt;br&gt;
It added confidence gating: hypotheses below 0.60 confidence stay in the internal reasoning trace and never reach the user.&lt;br&gt;
And it added one line that ended up doing more work than anything else: false positives are worse than false negatives. If evidence is weak, ambiguous, or insufficient, prefer &lt;code&gt;noBiasDetected = true&lt;/code&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%2Fnn3args0vixcj4q4nkxd.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%2Fnn3args0vixcj4q4nkxd.png" alt="Diagram comparing pipeline v1.0.0 and v1.1.0: v1.0.0 is story, reasoning trace, output. v1.1.0 adds a Step 0 sufficiency check before reasoning, an evidence-exclusion rule for " width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;v1.1.0 keeps the same three-stage shape as v1.0.0 but adds three gates: a sufficiency check at the start, an evidence-exclusion rule in the middle, and a confidence threshold before output.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Run on the same story, same "no info" answers, version 1.1.0 returned an empty bias assessment. The reflection prompt acknowledged that the engagement had been descriptive rather than interpretive — and stopped there.&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%2Fn8zarcwlkha9ixw874wb.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%2Fn8zarcwlkha9ixw874wb.png" alt="Diagram showing the same four " width="800" height="367"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Same four "no info" answers, two prompt versions, opposite conclusions — v1.0.0 calls it Cherry-Picking, v1.1.0 calls it no bias.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The two outputs are reasoning about the exact same input. The difference isn't whether evidence exists. It's whether "I don't know" counts as evidence of something — and somebody has to decide that explicitly, because the model won't decide it on its own.&lt;/p&gt;

&lt;p&gt;The actual diff between the two prompt versions&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  What I haven't built yet
&lt;/h2&gt;

&lt;p&gt;At this point I started planning a small set of metrics — &lt;code&gt;evidence_grounded_rate&lt;/code&gt;, a &lt;code&gt;false_positive_rate&lt;/code&gt;, a corpus of deliberately boring "no bias" stories to run systematically against the pipeline.&lt;br&gt;
I haven't built any of it. And the way I caught the Cherry-Picking problem is exactly why that matters: I ran one story by hand and read the output carefully. That doesn't scale, and it doesn't tell me whether v1.1.0 has its own version of the same hole somewhere I haven't thought to test. Maybe a different phrasing of "I don't know" slips through. Maybe a story with one ambiguous detail and three "no info" answers behaves differently than four.&lt;br&gt;
Right now, "it works" means "it worked on this story, this time." That's an honest description of where the project is — and it's also the whole argument for why the next step isn't a new feature, it's a way of finding out whether the fix generalizes at all.&lt;/p&gt;

&lt;p&gt;There's a more uncomfortable possibility, too. Maybe v1.1.0 didn't fix anything general. Maybe it just learned this particular story — four "no info" answers about Anna's coffee — and a slightly different "I don't know" trips it right back into Cherry-Picking. I don't have the evaluation corpus to rule that out yet. That's not a hedge; it's the actual state of the project.&lt;/p&gt;

&lt;p&gt;A prompt rule isn't the only way to catch this — a cheap classifier or simple rule‑based precheck that detects “no info”‑style non‑answers before the reasoning stage could have done the job too. I didn’t add a rule‑based precheck because I didn’t want to force users to answer follow‑ups; preserving the option to say “I don’t know” was an intentional design choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I didn't expect
&lt;/h2&gt;

&lt;p&gt;I started this thinking I was building a bias detector. What I actually built, one failure at a time, was a small lesson in why "I don't know" is hard for a reasoning system to handle — and not for the reason I assumed.&lt;br&gt;
I expected the hard part to be telling the model not to find biases when there's nothing there. That part turned out to be almost easy — add a flag, add a "this isn't evidence" list, done.&lt;br&gt;
The hard part was realizing the model could satisfy every grounding requirement I'd written and still produce a confident, well-cited, completely unwarranted conclusion — by treating my own refusal to speculate as a fact about me worth diagnosing.&lt;br&gt;
The most useful change in this project wasn't the reasoning trace, and it wasn't the evidence requirement. It was the explicit, written-down rule that some answers — "I don't know," "no info," "not sure" — don't mean anything, and the system has to be told that, because by default it will find a way to mean something out of anything you give it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://frontend-topaz-eight-10.vercel.app/" rel="noopener noreferrer"&gt;live&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/lemind/biassemble" rel="noopener noreferrer"&gt;main repo&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/lemind/biassemble-core" rel="noopener noreferrer"&gt;core repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>promptengineering</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Demonstrating Bias and Mitigation in a Simple Clinical ML Pipeline</title>
      <dc:creator>Dimitrii Lyomin</dc:creator>
      <pubDate>Thu, 18 Dec 2025 12:26:53 +0000</pubDate>
      <link>https://dev.to/lemind/demonstrating-bias-and-mitigation-in-a-simple-clinical-ml-pipeline-3pc3</link>
      <guid>https://dev.to/lemind/demonstrating-bias-and-mitigation-in-a-simple-clinical-ml-pipeline-3pc3</guid>
      <description>&lt;h2&gt;
  
  
  A Minimal Case Study of Bias in Clinical Machine Learning
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/lemind/clinical-ml-bias-demo" rel="noopener noreferrer"&gt;https://github.com/lemind/clinical-ml-bias-demo&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Background
&lt;/h3&gt;

&lt;p&gt;This project was done as part of a university course on &lt;strong&gt;machine learning in clinical settings&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The course focused on bias and fairness in ML, clinical risk, interpretability, and the limits of technical mitigation in real-world systems.&lt;/p&gt;

&lt;p&gt;One of the key inspirations was &lt;strong&gt;Ntoutsi et al. (2020), “Bias in Data-Driven AI Systems”&lt;/strong&gt;[1], which emphasizes that bias can appear at all stages of an ML pipeline and that mitigation is usually partial and involves trade-offs.&lt;/p&gt;

&lt;p&gt;The goal of this project was &lt;strong&gt;not to build a strong predictive model&lt;/strong&gt;, but to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;demonstrate bias,&lt;/li&gt;
&lt;li&gt;measure it explicitly,&lt;/li&gt;
&lt;li&gt;and apply a simple mitigation strategy.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Problem Setup
&lt;/h3&gt;

&lt;p&gt;We simulate a basic clinical prediction task using &lt;strong&gt;synthetic data&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Features: age, sex, severity score&lt;/li&gt;
&lt;li&gt;Target: binary clinical outcome&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sex is treated as a &lt;strong&gt;protected attribute&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Bias is intentionally introduced so that female patients are more likely to be missed by the model.&lt;/p&gt;

&lt;p&gt;This setup reflects real clinical scenarios where historical or systemic biases are encoded in data.&lt;/p&gt;




&lt;h3&gt;
  
  
  Method
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Tools
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Python
&lt;/li&gt;
&lt;li&gt;NumPy, Pandas
&lt;/li&gt;
&lt;li&gt;scikit-learn
&lt;/li&gt;
&lt;li&gt;Logistic Regression (interpretable baseline)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Steps
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Generate biased synthetic clinical data
&lt;/li&gt;
&lt;li&gt;Train a logistic regression model
&lt;/li&gt;
&lt;li&gt;Evaluate performance by subgroup
&lt;/li&gt;
&lt;li&gt;Measure &lt;strong&gt;False Negative Rate (FNR)&lt;/strong&gt; per group
&lt;/li&gt;
&lt;li&gt;Apply post-processing mitigation
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;False negatives were chosen as the primary metric due to their clinical relevance.&lt;/p&gt;




&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Baseline (default threshold = 0.5)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Overall accuracy:&lt;/strong&gt; 0.593
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False Negative Rate (male):&lt;/strong&gt; 0.468
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False Negative Rate (female):&lt;/strong&gt; 0.925
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model misses most positive cases for female patients, despite acceptable overall accuracy.&lt;/p&gt;

&lt;h4&gt;
  
  
  After mitigation (group-specific threshold)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;False Negative Rate (male):&lt;/strong&gt; 0.468
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False Negative Rate (female):&lt;/strong&gt; 0.094
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The disparity is substantially reduced without retraining the model.&lt;/p&gt;




&lt;h3&gt;
  
  
  Interpretation
&lt;/h3&gt;

&lt;p&gt;Mitigation was applied &lt;strong&gt;at decision time&lt;/strong&gt;, not during training.&lt;br&gt;&lt;br&gt;
A more sensitive threshold was used for the disadvantaged group.&lt;/p&gt;

&lt;p&gt;This improves recall for female patients but implicitly increases false positives, illustrating a real clinical trade-off.&lt;/p&gt;

&lt;p&gt;The outcome aligns with the arguments of Ntoutsi et al. (2020):&lt;br&gt;&lt;br&gt;
bias mitigation redistributes errors rather than eliminating them.&lt;/p&gt;




&lt;h3&gt;
  
  
  Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Synthetic data lacks real clinical complexity
&lt;/li&gt;
&lt;li&gt;Only one protected attribute was considered
&lt;/li&gt;
&lt;li&gt;Thresholds were manually chosen
&lt;/li&gt;
&lt;li&gt;Not all fairness metrics were evaluated
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite this, the example effectively demonstrates key concepts from the course.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This project shows that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bias can exist even in simple, interpretable models
&lt;/li&gt;
&lt;li&gt;overall accuracy can hide clinically important disparities
&lt;/li&gt;
&lt;li&gt;mitigation strategies reduce harm but introduce trade-offs
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bias in clinical ML is not purely a modeling issue, but a &lt;strong&gt;system-level problem&lt;/strong&gt;, consistent with current research.&lt;/p&gt;




&lt;p&gt;[1] - Ntoutsi, E., Fafalios, P., Gadiraju, U., Iosifidis, V., Nejdl, W., Vidal, M.-E., Ruggieri, S., Turini, F., Papadopoulos, S., Krasanakis, E., Kompatsiaris, I., Kinder-Kurlanda, K., Wagner, C., Karimi, F., Fernandez, M., Alani, H., Berendt, B., Kruegel, T., Heinze, C., Broelemann, K., Kasneci, G., Tiropanis, T., &amp;amp; Staab, S. (2020). Bias in data-driven artificial intelligence systems—An introductory survey. Wiley Interdisciplinary Reviews: Data Mining and Knowledge Discovery, 10(3), e1356. &lt;a href="https://doi.org/10.1002/widm.1356" rel="noopener noreferrer"&gt;https://doi.org/10.1002/widm.1356&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>bias</category>
      <category>machinelearning</category>
      <category>healthcare</category>
    </item>
    <item>
      <title>Suspense and Fiber: The Intricate Machinery Behind React's Rendering Elegance</title>
      <dc:creator>Dimitrii Lyomin</dc:creator>
      <pubDate>Mon, 16 Sep 2024 09:43:36 +0000</pubDate>
      <link>https://dev.to/lemind/suspense-and-fiber-the-intricate-machinery-behind-reacts-rendering-elegance-j8f</link>
      <guid>https://dev.to/lemind/suspense-and-fiber-the-intricate-machinery-behind-reacts-rendering-elegance-j8f</guid>
      <description>&lt;p&gt;React Fiber, the heart of React's concurrent rendering, enables the framework to break down tasks into smaller units and prioritize more important tasks, allowing for smoother and more responsive user interfaces. When paired with &lt;strong&gt;Suspense&lt;/strong&gt;, it allows React to "suspend" rendering, displaying a &lt;code&gt;fallback&lt;/code&gt; UI while waiting for tasks like data fetching or computations to finish.&lt;/p&gt;

&lt;p&gt;A Fiber is a JavaScript object that represents a unit of work in React. It holds important information about a component during the rendering process:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All the code in that article is pseudo. You can find real files links in the end of the article&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="c1"&gt;// The type of fiber (e.g., HostComponent, FunctionComponent)&lt;/span&gt;
  &lt;span class="nx"&gt;stateNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// The actual DOM node or instance for class components&lt;/span&gt;
  &lt;span class="nx"&gt;memoizedProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Props used during the last render&lt;/span&gt;
  &lt;span class="nx"&gt;memoizedState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// State used during the last render&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Parent fiber&lt;/span&gt;
  &lt;span class="nx"&gt;sibling&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;            &lt;span class="c1"&gt;// Next sibling fiber&lt;/span&gt;
  &lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// First child fiber&lt;/span&gt;
  &lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// Link to the previous fiber (for reconciling updates)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;fiber tree&lt;/strong&gt; allows React to efficiently traverse the component tree, perform rendering work, and track updates, state, and DOM mutations.&lt;/p&gt;

&lt;p&gt;Let's build a simple app consisting of Header, Content, and Footer components. To highlight how Fiber works, we’ll make Header perform a heavy computation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Content&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Suspense&lt;/span&gt;&lt;span class="err"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Simulating heavy computation&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;heavy&lt;/span&gt; &lt;span class="nx"&gt;computation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;This&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="nx"&gt;area&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;footer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/footer&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How it starts? The &lt;code&gt;render&lt;/code&gt; function is responsible for starting the initial rendering process in React. It takes a root component (like &lt;code&gt;App&lt;/code&gt;) and creates the initial fiber tree for React to work on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HostRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// Root fiber tag&lt;/span&gt;
    &lt;span class="na"&gt;stateNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// Reference to the DOM container&lt;/span&gt;
    &lt;span class="na"&gt;child&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// Initial child will be added here&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a new work-in-progress fiber for our App component&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createFiberFromElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;rootFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;appFiber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Start the rendering process&lt;/span&gt;
  &lt;span class="nf"&gt;scheduleWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootFiber&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;Then work scheduling take into an action. &lt;code&gt;scheduleWork&lt;/code&gt; is responsible for starting the work loop and processing the fiber tree. It determines when to start processing work, often using &lt;code&gt;workLoop&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scheduleWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootFiber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;nextUnitOfWork&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rootFiber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Set the root fiber as the starting point&lt;/span&gt;
  &lt;span class="nf"&gt;requestIdleCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workLoop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Begin processing fibers when the browser is idle&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the root fiber is set as the &lt;code&gt;nextUnitOfWork&lt;/code&gt;, and React schedules the &lt;code&gt;workLoop&lt;/code&gt; function to process it. React uses &lt;code&gt;requestIdleCallback&lt;/code&gt; to wait until the browser is idle before starting the work, which is essential for non-blocking rendering.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, &lt;code&gt;workLoop&lt;/code&gt; and &lt;code&gt;performUnitOfWork&lt;/code&gt; handle the actual processing of fibers. This is &lt;strong&gt;Reconciliation Phase&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;workLoop&lt;/code&gt; processes each fiber by calling &lt;code&gt;performUnitOfWork&lt;/code&gt; until all tasks are complete or the browser needs to prioritize other tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;workLoop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextUnitOfWork&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;shouldYield&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;nextUnitOfWork&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;performUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Perform work for the next fiber&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;nextUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Commit all completed work to the DOM&lt;/span&gt;
    &lt;span class="nf"&gt;commitRoot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Yield control and schedule the next chunk of work&lt;/span&gt;
    &lt;span class="nf"&gt;requestIdleCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workLoop&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;&lt;code&gt;performUnitOfWork&lt;/code&gt; processes individual fibers, checking for &lt;code&gt;Suspense&lt;/code&gt; boundaries, starting rendering tasks, and managing updates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;performUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// If there's more work to do, return the next unit&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Otherwise, complete the work and move to the next sibling or parent&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sibling&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sibling&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sibling&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sibling&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;SuspenseComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suspenseState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Suspended&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Render fallback UI if data is not ready&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suspenseState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Resolved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Render actual content once data resolves&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&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;span class="c1"&gt;// Continue rendering for other fibers&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After completing all the units of work, &lt;code&gt;commitRoot&lt;/code&gt; is responsible for committing the fiber tree to the DOM, including handling Suspense fallback UI. This is &lt;strong&gt;Commit Phase&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;commitRoot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rootFiber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;SuspenseComponent&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suspenseState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Suspended&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Commit fallback UI if Suspense is active&lt;/span&gt;
      &lt;span class="nf"&gt;updateDOM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stateNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Commit normal content&lt;/span&gt;
      &lt;span class="nf"&gt;updateDOM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;memoizedProps&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// If the fiber has a passive effect (i.e., useEffect), schedule it&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;effectTag&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Passive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Function to schedule the useEffect hooks to run after the DOM updates and browser paint&lt;/span&gt;
      &lt;span class="nf"&gt;scheduleEffectHooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;fiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Move to the next fiber in the tree&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;blockquote&gt;
&lt;p&gt;During the commit phase, React invokes &lt;code&gt;scheduleEffectHooks&lt;/code&gt; for any fiber that has side effects (like &lt;code&gt;useEffect&lt;/code&gt;). These hooks are deferred until after the DOM updates and browser paints to avoid blocking the rendering process. This allows React to perform non-blocking updates while ensuring that side-effects are executed in a timely manner once the UI is stable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we explored the inner workings of React's Fiber architecture and how Suspense interacts with it to enhance the rendering process. We learned how React breaks down rendering tasks into smaller units, prioritizes important tasks, and defers less critical updates to keep the user interface smooth and responsive.&lt;/p&gt;

&lt;p&gt;We gained a clear understanding of the fiber tree structure, the work scheduling process, and how reconciliation and commit phases work to update the DOM efficiently. We also explored how Suspense integrates within this architecture, displaying fallback content while awaiting data or heavy computations.&lt;/p&gt;

&lt;p&gt;If you have any feedback or thoughts on the article—whether parts are unclear or could be improved—I’d be glad to hear them. Your insights will help refine and enhance the content for everyone.&lt;/p&gt;

&lt;p&gt;Sources and original implementations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/faq-internals.html#what-is-react-fiber" rel="noopener noreferrer"&gt;React Fiber Overview:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/concurrent-mode-suspense.html" rel="noopener noreferrer"&gt;React Suspense:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberWorkLoop.new.js" rel="noopener noreferrer"&gt;Current Implementation of &lt;code&gt;performUnitOfWork&lt;/code&gt;:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberBeginWork.new.js" rel="noopener noreferrer"&gt;Current Implementation of &lt;code&gt;beginWork&lt;/code&gt;: &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberCommitWork.new.js" rel="noopener noreferrer"&gt;Current Implementation of &lt;code&gt;commitRoot&lt;/code&gt;: &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberWorkLoop.new.js" rel="noopener noreferrer"&gt;Current Implementation of &lt;code&gt;scheduleWork&lt;/code&gt; and &lt;code&gt;workLoop&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>render</category>
      <category>fiber</category>
    </item>
    <item>
      <title>Merge Sort Demystified: A Beginner's Guide to Divide and Conquer Sorting</title>
      <dc:creator>Dimitrii Lyomin</dc:creator>
      <pubDate>Thu, 12 Sep 2024 10:14:19 +0000</pubDate>
      <link>https://dev.to/lemind/merge-sort-demystified-a-beginners-guide-to-divide-and-conquer-sorting-42p0</link>
      <guid>https://dev.to/lemind/merge-sort-demystified-a-beginners-guide-to-divide-and-conquer-sorting-42p0</guid>
      <description>&lt;p&gt;Merge Sort was introduced by John von Neumann in 1945, primarily to improve the efficiency of sorting large datasets. Von Neumann's algorithm aimed to provide a consistent and predictable sorting process using the divide and conquer method. This strategy allows Merge Sort to handle both small and large datasets effectively, guaranteeing a stable sort with a time complexity of &lt;strong&gt;O(n log n)&lt;/strong&gt; in all cases.&lt;/p&gt;

&lt;p&gt;Merge Sort employs the &lt;strong&gt;divide and conquer&lt;/strong&gt; approach, which splits the array into smaller subarrays, recursively sorts them, and then merges the sorted arrays back together. This approach breaks the problem into manageable chunks, sorting each chunk individually and combining them efficiently. As a result, the algorithm performs well even on large datasets by dividing the sorting workload.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recursion is a process where a function calls itself to solve a smaller version of the same problem. It keeps breaking the problem down until it reaches a point where the problem is simple enough to solve directly, which is called the &lt;strong&gt;base case&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Below is an implementation of Merge Sort in JavaScript, showing how the array is recursively split and merged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mergeSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mergeSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&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;mid&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mergeSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&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;lt;&lt;/span&gt; &lt;span class="nx"&gt;right&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;right&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;To better understand how Merge Sort works, let's walk through the process using the array: &lt;code&gt;[38, 27, 43, 3, 9, 82, 10]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Recursive Division (&lt;code&gt;mergeSort&lt;/code&gt; function)&lt;/strong&gt;&lt;br&gt;
The array is recursively split into smaller subarrays until each subarray has only one element. This happens through the following lines in the &lt;code&gt;mergeSort&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mergeSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That stops our recursion.&lt;/p&gt;

&lt;p&gt;Here’s how the recursive division unfolds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial Call&lt;/strong&gt;: &lt;code&gt;mergeSort([38, 27, 43, 3, 9, 82, 10])&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;The array is split at the midpoint:
&lt;code&gt;[38, 27, 43]&lt;/code&gt; and &lt;code&gt;[3, 9, 82, 10]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;First Half:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mergeSort([38, 27, 43])&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Split at the midpoint: &lt;code&gt;[38]&lt;/code&gt; and &lt;code&gt;[27, 43]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;mergeSort([27, 43])&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Split into &lt;code&gt;[27]&lt;/code&gt; and &lt;code&gt;[43]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Subarrays &lt;code&gt;[38]&lt;/code&gt;, &lt;code&gt;[27]&lt;/code&gt;, and &lt;code&gt;[43]&lt;/code&gt; are now individual elements and ready to be merged.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Second Half:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mergeSort([3, 9, 82, 10])&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Split at the midpoint: &lt;code&gt;[3, 9]&lt;/code&gt; and &lt;code&gt;[82, 10]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;mergeSort([3, 9])&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Split into &lt;code&gt;[3]&lt;/code&gt; and &lt;code&gt;[9]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;mergeSort([82, 10])&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Split into &lt;code&gt;[82]&lt;/code&gt; and &lt;code&gt;[10]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Subarrays &lt;code&gt;[3]&lt;/code&gt;, &lt;code&gt;[9]&lt;/code&gt;, &lt;code&gt;[82]&lt;/code&gt;, and &lt;code&gt;[10]&lt;/code&gt; are now ready to be merged.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Merging the Sorted Subarrays (&lt;code&gt;merge&lt;/code&gt; function)&lt;/strong&gt;&lt;br&gt;
Now, we start merging the subarrays back together in sorted order using the merge function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&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;lt;&lt;/span&gt; &lt;span class="nx"&gt;right&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;right&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;Here’s how the merging process works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First Merge (from the base cases):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Merge &lt;code&gt;[27]&lt;/code&gt; and &lt;code&gt;[43]&lt;/code&gt; → Result is &lt;code&gt;[27, 43]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Merge &lt;code&gt;[38]&lt;/code&gt; with &lt;code&gt;[27, 43]&lt;/code&gt; → Result is &lt;code&gt;[27, 38, 43]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, the left half of the array is fully merged: &lt;code&gt;[27, 38, 43]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second Merge (from the base cases):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Merge &lt;code&gt;[3]&lt;/code&gt; and &lt;code&gt;[9]&lt;/code&gt; → Result is &lt;code&gt;[3, 9]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Merge &lt;code&gt;[82]&lt;/code&gt; and &lt;code&gt;[10]&lt;/code&gt; → Result is &lt;code&gt;[10, 82]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Merge &lt;code&gt;[3, 9]&lt;/code&gt; with &lt;code&gt;[10, 82]&lt;/code&gt; → Result is &lt;code&gt;[3, 9, 10, 82]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, the right half is fully merged: &lt;code&gt;[3, 9, 10, 82]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Final Merge&lt;/strong&gt;&lt;br&gt;
Finally, the two halves &lt;code&gt;[27, 38, 43]&lt;/code&gt; and &lt;code&gt;[3, 9, 10, 82]&lt;/code&gt; are merged using the &lt;code&gt;merge&lt;/code&gt; function:&lt;/p&gt;

&lt;p&gt;Compare &lt;code&gt;27&lt;/code&gt; (left[0]) and &lt;code&gt;3&lt;/code&gt; (right[0]). Since &lt;code&gt;3 &amp;lt; 27&lt;/code&gt;, add &lt;code&gt;3&lt;/code&gt; to the result.&lt;br&gt;
Compare &lt;code&gt;27&lt;/code&gt; and &lt;code&gt;9&lt;/code&gt;. Add &lt;code&gt;9&lt;/code&gt; to the result.&lt;br&gt;
Compare &lt;code&gt;27&lt;/code&gt; and &lt;code&gt;10&lt;/code&gt;. Add &lt;code&gt;10&lt;/code&gt; to the result.&lt;br&gt;
Compare &lt;code&gt;27&lt;/code&gt; and &lt;code&gt;82&lt;/code&gt;. Add &lt;code&gt;27&lt;/code&gt; to the result.&lt;br&gt;
Compare &lt;code&gt;38&lt;/code&gt; and &lt;code&gt;82&lt;/code&gt;. Add &lt;code&gt;38&lt;/code&gt; to the result.&lt;br&gt;
Compare &lt;code&gt;43&lt;/code&gt; and &lt;code&gt;82&lt;/code&gt;. Add &lt;code&gt;43&lt;/code&gt; to the result.&lt;br&gt;
Add the remaining element &lt;code&gt;82&lt;/code&gt; from the right array.&lt;br&gt;
The fully merged and sorted array is:&lt;br&gt;
&lt;code&gt;[3, 9, 10, 27, 38, 43, 82]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time Complexity:&lt;/strong&gt; Best, Average, and Worst Case: &lt;strong&gt;O(n log n)&lt;/strong&gt;&lt;br&gt;
Let's look at it closer:&lt;/p&gt;

&lt;p&gt;Dividing (O(log n)): Each time the array is split into two halves, the size of the problem is reduced. Since the array is divided in half at each step, the number of times you can do this is proportional to log n. For example, if you have 8 elements, you can divide them in half 3 times (since log₂(8) = 3).&lt;/p&gt;

&lt;p&gt;Merging (O(n)): After dividing the array, the algorithm merges the smaller arrays back together in order. Merging two sorted arrays of size n takes O(n) time because you have to compare and combine each element once.&lt;/p&gt;

&lt;p&gt;Overall Complexity (O(n log n)): Since dividing takes O(log n) steps and you merge n elements at each step, the total time complexity is the multiplication of these two: O(n log n).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity:&lt;/strong&gt; &lt;strong&gt;O(n)&lt;/strong&gt;&lt;br&gt;
Merge Sort requires extra space proportional to the size of the array because it needs temporary arrays to store the elements during the merge phase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comparison to Other Sorting Algorithms:&lt;/strong&gt;&lt;br&gt;
QuickSort: While QuickSort has an average time complexity of &lt;strong&gt;O(n log n)&lt;/strong&gt;, its worst case can be &lt;strong&gt;O(n^2)&lt;/strong&gt;. Merge Sort avoids this worst-case scenario, but QuickSort is generally faster for in-memory sorting when space is a concern.&lt;br&gt;
Bubble Sort: Much less efficient than Merge Sort, with a time complexity of &lt;strong&gt;O(n^2)&lt;/strong&gt; for average and worst-case scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real World Usage&lt;/strong&gt;&lt;br&gt;
Merge Sort is widely used for external sorting, where large datasets need to be sorted from disk, as it efficiently handles data that doesn’t fit into memory. It's also commonly implemented in parallel computing environments, where subarrays can be sorted independently, taking advantage of multi-core processing.&lt;/p&gt;

&lt;p&gt;Moreover, libraries and languages such as Python (Timsort), Java, and C++ (std::stable_sort) rely on variations of Merge Sort to ensure stability in sorting operations, making it particularly suitable for sorting objects and complex data structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Merge Sort continues to be a fundamental algorithm in both theoretical computer science and practical applications due to its stability, consistent performance, and adaptability for sorting large datasets. While other algorithms like QuickSort may perform faster in certain situations, Merge Sort’s guaranteed &lt;strong&gt;O(n log n)&lt;/strong&gt; time complexity and versatility make it invaluable for memory-constrained environments and for maintaining the order of elements with equal keys. Its role in modern programming libraries ensures it remains relevant in real-world applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Knuth, Donald E. The Art of Computer Programming, Vol. 3: Sorting and Searching. Addison-Wesley Professional, 1997, pp. 158-160.&lt;/li&gt;
&lt;li&gt;Cormen, Thomas H., et al. Introduction to Algorithms. MIT Press, 2009, Chapter 2 (Merge Sort), Chapter 5 (Algorithm Complexity), Chapter 7 (QuickSort).&lt;/li&gt;
&lt;li&gt;Silberschatz, Abraham, et al. Database System Concepts. McGraw-Hill, 2010, Chapter 13 (External Sorting).&lt;/li&gt;
&lt;li&gt;"Timsort." Python Documentation, Python Software Foundation.
Python's Timsort&lt;/li&gt;
&lt;li&gt;"Java Arrays.sort." Oracle Documentation.
Java's Arrays.sort()&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>algorithms</category>
      <category>javascript</category>
      <category>sorting</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
