<?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: Ezeana Micheal</title>
    <description>The latest articles on DEV Community by Ezeana Micheal (@ezeanamichael).</description>
    <link>https://dev.to/ezeanamichael</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%2F795718%2F32ca5ddb-abe1-44e1-9391-85534fc496af.jpg</url>
      <title>DEV Community: Ezeana Micheal</title>
      <link>https://dev.to/ezeanamichael</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ezeanamichael"/>
    <language>en</language>
    <item>
      <title>The Bilingual Developer: Python and Go, The Error Handling Paradigm</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Sat, 27 Jun 2026 06:38:35 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-the-error-handling-paradigm-2c6o</link>
      <guid>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-the-error-handling-paradigm-2c6o</guid>
      <description>&lt;p&gt;In the previous article, we explored how functions allow us to package logic into reusable blocks. However, a crucial question remains: what happens when that logic goes wrong?&lt;/p&gt;

&lt;p&gt;Building applications is not just about writing code for the "happy path," the scenario where everything works perfectly. In reality, &lt;strong&gt;our programs interact with the messy, unpredictable outside world&lt;/strong&gt;. Files we try to open might be missing. Network connections might timeout. Databases might be overloaded. Disk drives might fill up mid-write.&lt;/p&gt;

&lt;p&gt;If we ignore these possibilities, our applications will crash spectacularly, leaving users frustrated and data corrupted.&lt;/p&gt;

&lt;p&gt;Therefore, a programming language must provide a clear, disciplined way to predict, handle, and recover from failures. This is where Python and Go diverge in one of the most profound ways possible. They represent two completely different schools of thought on how to manage errors. Python embraces the &lt;strong&gt;Exception Model&lt;/strong&gt;, using structured "try/catch" blocks to intercept errors thrown from anywhere. Go rejects exceptions in favor of &lt;strong&gt;Errors as Values&lt;/strong&gt;, &lt;strong&gt;forcing developers to handle errors immediately and explicitly by checking return values&lt;/strong&gt;. Furthermore, when it comes to cleaning up resources (like closing files or releasing network connections), Python offers the elegant with statement (Context Managers), while Go provides the powerful and unique defer keyword.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Python Way: The Exception Model
&lt;/h2&gt;

&lt;p&gt;Python operates on a philosophy known as &lt;strong&gt;EAFP&lt;/strong&gt;, which stands for &lt;em&gt;"Easier to Ask for Forgiveness than Permission."&lt;/em&gt; This is a distinctly optimistic approach. In Python, you write the code you &lt;em&gt;expect&lt;/em&gt; to work, and if something bad happens, the program "raises" (or throws) an exception that interrupts the normal flow of execution.&lt;/p&gt;

&lt;p&gt;Think of an exception like a &lt;strong&gt;fire alarm&lt;/strong&gt;. When everything is fine, the alarm is silent, and your program runs smoothly. But when a fire starts (an error occurs), the alarm blares. If you have a fire suppression system (except block) ready, you can contain and handle the fire. If you don't, the fire spreads up the chain of command until the whole building (the program) burns down and crashes.&lt;/p&gt;

&lt;h3&gt;
  
  
  The try / except / else / finally Structure
&lt;/h3&gt;

&lt;p&gt;Python provides a layered structure to manage exceptions. The try block contains the code that might fail. The except block catches specific errors. The else block runs only if no errors occurred, and the finally block runs &lt;em&gt;regardless&lt;/em&gt; of what happened—it is the cleanup crew.&lt;/p&gt;

&lt;p&gt;Consider this example where we ask a user for a number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter a number: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# This might raise a ValueError  
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;     &lt;span class="c1"&gt;# This might raise a ZeroDivisionError  
&lt;/span&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Oops! That wasn&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t a valid number.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ZeroDivisionError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You can&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t divide by zero!&lt;/span&gt;&lt;span class="sh"&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The calculation succeeded! Result: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Thanks for using the calculator.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the user types "five", the ValueError is caught, and the program prints a friendly message instead of crashing. Crucially, the finally block always executes, ensuring that no matter what happens, we can close a file or log the attempt.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Nature of Python Exceptions
&lt;/h3&gt;

&lt;p&gt;One of the defining characteristics of Python's model is that exceptions &lt;strong&gt;bubble up&lt;/strong&gt;. If you don't catch an exception in the function where it occurs, &lt;strong&gt;it automatically propagates up to the function that called it, then up to the next, and so on, until it either finds a matching except block or terminates the entire process.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This allows developers to write very clean, readable "happy path" code. &lt;strong&gt;The error-handling logic is neatly separated from the business logic.&lt;/strong&gt; However, this convenience has a dark side. It is entirely possible to write Python code that "swallows" exceptions by catching a &lt;strong&gt;generic Exception and doing nothing&lt;/strong&gt;, or &lt;strong&gt;to forget to handle an edge case entirely&lt;/strong&gt;, leading to unexpected production crashes. Python trusts the developer to be disciplined, but it does not enforce that discipline at the language level.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Go Way: Errors as Values
&lt;/h2&gt;

&lt;p&gt;If Python's philosophy is optimistic and permissive, Go's philosophy is &lt;strong&gt;stoic, pragmatic, and hyper-vigilant&lt;/strong&gt;. Go explicitly rejects the exception model (with the exception of panic, which is reserved for catastrophic, unrecoverable events). Instead, Go treats errors as &lt;strong&gt;first-class values&lt;/strong&gt;—just like strings, integers, or booleans.&lt;/p&gt;

&lt;p&gt;In Go, if a function can fail, it returns an error as part of its standard return signature. &lt;strong&gt;The burden of checking for that error falls squarely on the caller&lt;/strong&gt;. There is no implicit bubbling up of exceptions; the error is just a piece of data passed from one function to another.&lt;/p&gt;

&lt;p&gt;Think of it like a pilot going through a pre-flight checklist. At every single step: checking fuel, checking the flaps, checking the radar, the pilot looks at the instrument panel and asks: "Is everything okay?" If at any point the dial reads "Error," the pilot must stop and address it immediately before moving to the next step.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Ubiquitous if err != nil
&lt;/h3&gt;

&lt;p&gt;The idiomatic pattern in Go is so ingrained that it has become a meme in the developer community. It looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;  
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  
    &lt;span class="s"&gt;"errors"&lt;/span&gt;  
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;  
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&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="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cannot divide by zero"&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="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Handled error:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Output: Handled error: cannot divide by zero  &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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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;Notice the pattern: result, err := divide(...). Immediately following that line is an if statement checking if err != nil.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This design forces the developer to confront the possibility of failure at the exact moment it occurs&lt;/strong&gt;. You cannot ignore the error, because the compiler won't stop you from ignoring it, but the language syntax encourages you to handle it right there.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Beauty of Verbosity
&lt;/h3&gt;

&lt;p&gt;Many new developers look at Go's if err != nil blocks and complain about verbosity(which I personally enjoy it). A simple 5-line function might have 3 lines dedicated to error handling.&lt;/p&gt;

&lt;p&gt;However, this verbosity is an intentional feature, not a bug. By making error handling explicit and visibly "in your face," &lt;strong&gt;Go ensures that the state of the program is always known.&lt;/strong&gt; When you read Go code, &lt;strong&gt;you can trace the exact path the data takes.&lt;/strong&gt; You can see exactly where a function might exit early due to a failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This eliminates the surprise element found in Python&lt;/strong&gt;. In Go, you never have to guess if an underlying library is going to throw a random exception 12 layers deep. The language is brutally honest: every possible failure is declared in the function signature, and every caller is forced to deal with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup and Resource Management: with vs. defer
&lt;/h2&gt;

&lt;p&gt;Handling errors is only half the battle. Often, when an error occurs, we have to gracefully clean up the mess. For example, if you open a file, you must close it. If you lock a mutex, you must unlock it. If a network connection is established, it must be gracefully terminated. Both Python and Go offer sophisticated tools for resource cleanup, but they operate on entirely different scopes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python’s Context Managers (with statement)
&lt;/h3&gt;

&lt;p&gt;Python manages resources through the with statement, which leverages the concept of &lt;strong&gt;Context Managers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A context manager is an object that defines two magic methods: &lt;strong&gt;enter&lt;/strong&gt; (executed at the start of the block) and &lt;strong&gt;exit&lt;/strong&gt; (executed when the block finishes, even if an exception occurred).&lt;/p&gt;

&lt;p&gt;Consider the classic example of reading a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# The file is automatically closed when the 'with' block ends  
# The file is guaranteed to be closed here, regardless of exceptions in file.read()  
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The with statement brilliantly bundles &lt;em&gt;acquisition&lt;/em&gt; and &lt;em&gt;release&lt;/em&gt; into a single, readable line. The &lt;strong&gt;exit&lt;/strong&gt; method handles the cleanup, ensuring the file pointer is closed, database connections are committed, or locks are released the moment you leave the indented block.&lt;/p&gt;

&lt;p&gt;The beauty here is &lt;strong&gt;scope control&lt;/strong&gt;. The resource exists only within the boundaries of the with block. This makes Python code highly readable and safe, as long as the developer remembers to use the context manager rather than manually opening and closing files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go’s Deferred Functions (defer keyword)
&lt;/h3&gt;

&lt;p&gt;Go does not have a built-in with statement. Instead, it introduces a deceptively simple yet incredibly powerful keyword: defer.&lt;/p&gt;

&lt;p&gt;When you prefix a function call with defer, Go schedules that function to run &lt;strong&gt;just before the surrounding function returns&lt;/strong&gt;. It doesn't matter whether the function returns normally, hits a return statement early, or encounters a panic and crashes—the defered call will always execute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Defer ensures this runs when the function exits,   &lt;/span&gt;
    &lt;span class="c"&gt;// regardless of what happens below.  &lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 

    &lt;span class="c"&gt;// Perform some operations on the file...  &lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="c"&gt;// Even if we return an error here, file.Close() still runs!  &lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="c"&gt;// If we reach the end, file.Close() still runs!  &lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that defer file.Close() is written immediately after the file is successfully opened. This keeps the resource management right next to the resource allocation, making it easy for developers to see the pairing.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Power of Stacked defer
&lt;/h4&gt;

&lt;p&gt;Go allows you to defer &lt;em&gt;multiple&lt;/em&gt; functions. When you do this, they execute in &lt;strong&gt;Last In, First Out (LIFO)&lt;/strong&gt; order—essentially a stack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Third"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Runs last  &lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Second"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Runs second  &lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"First"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Runs first  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Output:  &lt;/span&gt;
&lt;span class="c"&gt;// First  &lt;/span&gt;
&lt;span class="c"&gt;// Second  &lt;/span&gt;
&lt;span class="c"&gt;// Third  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is exceptionally useful when dealing with complex resources like nested locks or database transactions. If you acquire a read lock, then a write lock, defer ensures they are released in the correct reverse order, preventing deadlocks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Philosophical Head-to-Head
&lt;/h2&gt;

&lt;p&gt;Let's boil down the key differences to understand the mindsets behind each language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python's Philosophy: "You are a responsible adult."
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Errors&lt;/strong&gt;: Exceptions are for exceptional, unexpected cases. We trust you to handle them with try/except, but if you miss one, the interpreter will tell you.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup&lt;/strong&gt;: We provide elegant, block-level tools (with) to ensure resources are cleaned up as soon as you logically leave the context.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result&lt;/strong&gt;: Code is compact, readable, and fast to write. The main logic isn't cluttered with constant checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Go's Philosophy: "Murphy's Law is absolute."
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Errors&lt;/strong&gt;: Errors are just data. They are not exceptional; they are an expected part of every operation. You must check each one explicitly.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup&lt;/strong&gt;: We provide function-level tools (defer). The scope is the entire function, ensuring cleanup happens no matter how complex the logic gets.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result&lt;/strong&gt;: Code is verbose, bulletproof, and explicit. There is no magic. You can trace exactly what happens at every single line of execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The error handling paradigm of a language reveals its soul.&lt;/p&gt;

&lt;p&gt;When you code in Python, you write in a trusting environment*&lt;em&gt;. You focus on solving the problem&lt;/em&gt;&lt;em&gt;, knowing that if something goes wrong, an exception will give you a very clear stack trace to debug it. It is forgiving, which accelerates prototyping and iteration. **The with statement adds a layer of syntactic sugar that makes resource management almost pleasurable.&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;When you code in Go*&lt;em&gt;, you write in a defensive environment.&lt;/em&gt;* You are constantly asking, "What if this fails?" You check err != nil religiously. It feels pedantic at first, but over time, it cultivates a profound sense of reliability. By using defer, you ensure that your cleanup is tied to the lifetime of the function, making it incredibly hard to leak resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Python developer moving to Go might initially feel frustrated by the verbosity.&lt;/strong&gt; But the truth is, &lt;strong&gt;Go forces you to be honest about the fragility of the systems you are building.&lt;/strong&gt; In distributed systems, where network calls fail constantly, the "just let it crash" or "ask for forgiveness" model can be dangerous. Go's explicit model, combined with defer, builds software that is designed to withstand the chaos of the real world.&lt;/p&gt;

&lt;p&gt;Mastering both paradigms gives you the wisdom to choose the right tool for the job. For a quick script, Python's exceptions are a lifesaver. For a critical backend server that must run for years without downtime, Go's rigorous error values and cleanup mechanisms are the gold standard.  &lt;/p&gt;

</description>
      <category>python</category>
      <category>go</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Day I Confused Task Queues with Message Brokers And Built the Wrong Thing</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Sat, 27 Jun 2026 06:35:44 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-day-i-confused-task-queues-with-message-brokers-and-built-the-wrong-thing-1igm</link>
      <guid>https://dev.to/ezeanamichael/the-day-i-confused-task-queues-with-message-brokers-and-built-the-wrong-thing-1igm</guid>
      <description>&lt;p&gt;In my journey as a backend developer, I had already spent time working with APIs, databases, authentication flows, and background processing. I understood the basic idea that not everything should occur within a request-response cycle, especially when dealing with expensive operations such as sending emails, processing files, or generating reports. Offloading work to the background felt like a solved problem to me.&lt;/p&gt;

&lt;p&gt;That confidence was exactly what led me into confusion.&lt;br&gt;&lt;br&gt;
When I first encountered message brokers and task queues, they looked like different names for the same idea. Both involved queues, both involved workers, and both involved asynchronous processing. In my head, the distinction didn’t seem important, so I treated them interchangeably and assumed that choosing one over the other was just a matter of preference or framework availability.&lt;/p&gt;

&lt;p&gt;The real issue was that I had not yet understood the difference in intent between communication and execution. What I thought was a simple design choice actually turned into an architectural mistake that affected how I structured an entire system.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How I Misunderstood the Problem&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At the time, I was building systems where the backend had to handle multiple heavy operations. A user could upload files, request reports, or trigger processes that should not block the main API response. Naturally, I reached for a queue-based solution because it is the standard answer for background work.&lt;/p&gt;

&lt;p&gt;However, instead of asking what role the system needed to play, I focused on what tool could make things asynchronous. That small shift in thinking created the confusion. I assumed that anything that gets delayed or processed later should automatically go into a queue, without distinguishing whether I was dealing with a job that must be &lt;strong&gt;executed&lt;/strong&gt; or an &lt;strong&gt;event&lt;/strong&gt; that other services should react to.&lt;/p&gt;

&lt;p&gt;This is where I started building the wrong abstraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Where Task Queues Actually Fit&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;task queue&lt;/strong&gt; exists primarily to assign &lt;strong&gt;work that must be completed&lt;/strong&gt;. It is not concerned with broadcasting information, but with ensuring that a specific job gets executed &lt;strong&gt;reliably by a worker&lt;/strong&gt;. In this model, the system is aware that something needs to be done, and it delegates that responsibility to a background process that will eventually complete it.&lt;/p&gt;

&lt;p&gt;For example, generating a PDF report or resizing an image fits naturally into this category. The system issues a clear instruction, and a worker picks it up, executes it, and reports completion. The emphasis is on reliability, retries, scheduling, and tracking the state of a job from pending to completed or failed.&lt;/p&gt;

&lt;p&gt;In this world, tools like Celery or BullMQ make sense because they are designed around the idea of jobs, not just messages. They treat work as something that must be done, not just something that has been announced.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Where Message Brokers Actually Fit&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Message brokers&lt;/strong&gt; serve a different purpose entirely. Instead of focusing on work execution, &lt;strong&gt;they focus on system communication&lt;/strong&gt;. A message is not necessarily a task that must be completed by one worker, &lt;strong&gt;but rather an event that other systems might be interested in&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, when a user places an order in an e-commerce system, the order service does not need to directly know what happens next. Instead, it emits an event like “Order Created,” and &lt;strong&gt;different services subscribe to that event based on their own responsibilities&lt;/strong&gt;. The &lt;strong&gt;payment service may initiate billing&lt;/strong&gt;, the &lt;strong&gt;inventory service may adjust stock levels&lt;/strong&gt;, and the &lt;strong&gt;notification service may send a confirmation message&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The key idea here is decoupling. The producer of the message does not care who consumes it or how many consumers exist. It simply announces that something happened, and the rest of the system reacts independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Mistake That Caused Confusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The mistake I made was designing everything as if it were a task system. I treated every background operation as a job that needed to be executed by a worker. &lt;strong&gt;That meant I ended up forcing event-driven communication into a task-oriented model&lt;/strong&gt;, which created unnecessary coupling and made the system harder to extend.&lt;/p&gt;

&lt;p&gt;At the same time, &lt;strong&gt;I ignored the fact that some operations were not “tasks” at all,&lt;/strong&gt; but events that should naturally be consumed by multiple services. This led to a situation where &lt;strong&gt;my system became rigid&lt;/strong&gt;, because everything was structured around a single execution mindset instead of a flexible communication model.&lt;/p&gt;

&lt;p&gt;The more I added features, the more obvious the flaw became. Services that should have been independent started depending on a central queue, and what should have been a loosely connected system slowly became tightly coupled.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What I Learned from the Experience&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The turning point came when I realized that the real distinction is not about tools, but about intent. &lt;strong&gt;A task queue exists to execute work&lt;/strong&gt;, while &lt;strong&gt;a message broker exists to distribute information&lt;/strong&gt;. One is about responsibility, the other is about awareness.&lt;/p&gt;

&lt;p&gt;Once I understood that, my design approach changed. Instead of asking which queue system to use, I started asking &lt;strong&gt;what kind of relationship existed between components in the system&lt;/strong&gt;. If one service needed another service to perform a specific job, I used a task queue. If one service simply needed to inform others that something had happened, I used a message broker.&lt;/p&gt;

&lt;p&gt;This separation made the architecture cleaner, easier to scale, and much easier to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Final Reflection&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Looking back, the mistake was not technical. It was conceptual. I was solving the right problem in the wrong mental model, and that is often where most architectural failures begin. Tools like queues, brokers, and workers are powerful, but they only work well when the underlying intent is correctly understood.&lt;/p&gt;

&lt;p&gt;The lesson that stayed with me is simple. Before choosing infrastructure, understand whether you are assigning work or sharing information. Everything else becomes much clearer after that. What kind of mistakes have you made? You can comment below.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>backend</category>
      <category>python</category>
    </item>
    <item>
      <title>The Bilingual Developer: Python and Go Core Functions</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Fri, 19 Jun 2026 18:32:56 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-core-functions-3045</link>
      <guid>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-core-functions-3045</guid>
      <description>&lt;h1&gt;
  
  
  The Bilingual Developer: Python and Go Core Functions
&lt;/h1&gt;

&lt;p&gt;So far in our journey, we have explored the building blocks of programming:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to store data using variables,
&lt;/li&gt;
&lt;li&gt;How to guide the flow of execution using conditional statements, and
&lt;/li&gt;
&lt;li&gt;How to repeat actions efficiently using loops.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These tools are enough to write simple scripts that can process data or automate mundane tasks.&lt;/p&gt;

&lt;p&gt;However, as you start to write larger, more ambitious applications, a new and significant challenge emerges. Imagine you are building an e-commerce platform. You will need the logic for calculating prices based on complex discount rules, validating user credentials against a database, sending transactional emails, and even securely processing credit card payments.&lt;/p&gt;

&lt;p&gt;If you try to cram all of this functionality into one massive, linear/sequential file, the code quickly descends into what developers affectionately refer to as "spaghetti code." The logic becomes intertwined, variables conflict with each other, and making a single change to a pricing rule might unexpectedly break the email system. Tracking down a single bug in a 10,000-line file becomes a detective's nightmare, and collaborating with other developers becomes nearly impossible.&lt;/p&gt;

&lt;p&gt;This is precisely where &lt;strong&gt;functions&lt;/strong&gt; come into play. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Functions?
&lt;/h2&gt;

&lt;p&gt;A function allows us to encapsulate a specific piece of logic into an independent, reusable, and named block of code. We can define the logic once and then "call" it whenever we need that specific behavior.&lt;/p&gt;

&lt;p&gt;Think of a function like a specialized machine on an assembly line. You place raw materials at the entrance (these are the &lt;strong&gt;inputs&lt;/strong&gt; or parameters). The gears and motors inside turn and process those materials (this is the internal &lt;strong&gt;processing&lt;/strong&gt;). Finally, a finished product rolls out at the end (this is the &lt;strong&gt;return value&lt;/strong&gt;). &lt;/p&gt;

&lt;p&gt;For example, consider a calculator function: the input would be the numbers and the operation (e.g., 5 + 10), the processing would be the internal addition logic, and the output would be the answer (15). This separation between the "how" (the internal mechanics) and the "what" (the input/output) is what makes functions so powerful.&lt;/p&gt;

&lt;p&gt;Both Python and Go rely heavily on functions, but once again, the way they define, structure, and treat these functions showcases a fundamental difference in the philosophies of the two languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Function?
&lt;/h2&gt;

&lt;p&gt;At its core, a function is a reusable block of code designed to perform a single, specific task. Think of it as a verb in your program; it acts.&lt;br&gt;&lt;br&gt;
Instead of writing the same code repeatedly, like manually printing a welcome message for each user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome Michael&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome Sarah&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome David&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create a function named welcome_user() and simply reuse that one-liner over and over again.&lt;/p&gt;

&lt;p&gt;This simple abstraction provides benefits to software development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoiding Repetition (DRY Principle)&lt;/strong&gt;: Standing for &lt;em&gt;Don't Repeat Yourself&lt;/em&gt;, this is a core tenet of software engineering. If you need to change the welcome message from "Welcome" to "Greetings", you only need to change the code inside the function once, rather than searching through hundreds of files.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Organization&lt;/strong&gt;: Functions allow you to break a massive, monolithic program into small, digestible, logical modules. You can group related tasks together (e.g., putting all user authentication logic into a single file of functions).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Debugging&lt;/strong&gt;: When a bug occurs, functions help isolate the problem. If the pricing calculation is wrong, you know exactly which function to inspect without sifting through irrelevant code for user validation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable Components&lt;/strong&gt;: Once you write a function, you can use it in different parts of your application, or even copy it into a completely different project, saving precious development time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Anatomy of Function Definition
&lt;/h2&gt;

&lt;p&gt;The very first difference we encounter between Python and Go is the syntax required to &lt;em&gt;declare&lt;/em&gt; a function to the compiler or interpreter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python: Using def
&lt;/h3&gt;

&lt;p&gt;Python prides itself on readability, and its function definition syntax is an excellent example. It uses the straightforward keyword def, which is an abbreviation for "define."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello Developer&lt;/span&gt;&lt;span class="sh"&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 execute this function, you simply call it by its name followed by parentheses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello Developer  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can notice how Python's structure almost reads like plain English: &lt;em&gt;Define a function called greet.&lt;/em&gt; Furthermore, Python does not use brackets to define the scope of the function. Instead, it strictly relies on &lt;strong&gt;indentation&lt;/strong&gt;(as we have seen in loops and conditions too). The indented block of code directly underneath the def statement is what belongs to the function. This forces clean, uniform formatting across all Python code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go: Using func
&lt;/h3&gt;

&lt;p&gt;Go takes a slightly more terse, brace-oriented approach. It uses the keyword func to declare a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello Developer"&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;Calling the function is syntactically similar to Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello Developer  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the structural differences are immediately apparent. Go uses curly braces { } to define the beginning and end of the function's logic, much like C, Java, or JavaScript. Additionally, Go is strict about syntax; the opening curly brace &lt;strong&gt;must&lt;/strong&gt; be on the same line as the function declaration, otherwise, the compiler will throw an error. While Python relies on the developer to maintain consistent whitespace, Go offloads that structural enforcement to the compiler using braces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing Information: Functions With Parameters
&lt;/h2&gt;

&lt;p&gt;Most functions are not meant to do the exact same thing every single time. They need dynamic information to work with. For instance, instead of creating a function that always prints "Hello Michael", we want a function that works for anyone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python Parameters
&lt;/h3&gt;

&lt;p&gt;Python allows you to define parameters inside the parentheses. Because Python is dynamically typed, you just provide the variable name without specifying what &lt;em&gt;kind&lt;/em&gt; of data it is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you call this function, you pass the value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Michael&lt;/span&gt;&lt;span class="sh"&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;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello Michael  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python's approach emphasizes flexibility. You can pass a string, an integer, or even a list into that name parameter. While this is convenient, it means the interpreter will only realize you passed a wrong type (like a number that breaks the print formatting) when the code is actually running. Although in newer versions of python you can specify a type hint to specify datatype, see more below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go Parameters
&lt;/h3&gt;

&lt;p&gt;Go, on the other hand, requires explicit type declarations. When defining the function, you must tell the compiler exactly what data type the name parameter is expected to hold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&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;name&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 name string part is mandatory. It tells Go: &lt;em&gt;"This function expects a single argument called 'name', and it must strictly be a string."&lt;/em&gt; Calling the function remains the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Michael"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This requirement ensures that the Go compiler knows exactly how much memory to allocate for the variable and prevents you from accidentally passing an integer to a function that expects text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Function Signatures
&lt;/h2&gt;

&lt;p&gt;In computer science, a &lt;strong&gt;function signature&lt;/strong&gt; acts as the "contract" of a function. It defines the function's name, the types and order of its parameters, and the types of values it returns. This is where Python and Go fundamentally diverge.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python: Optional Type Hints
&lt;/h3&gt;

&lt;p&gt;Python operates on dynamic typing. By default, Python does not care about the data types, so a signature is simply the name and parameter list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interpreter figures out what a and b are only when the function runs.&lt;br&gt;&lt;br&gt;
However, Python 3 introduced "Type Hints" to add optional clarity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&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;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we communicate our intention: a and b should be integers, and the output should be an integer. This is fantastic for documentation and helps IDEs catch potential issues. &lt;strong&gt;Crucially, however, Python does not enforce these hints&lt;/strong&gt;. You could still write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the context, this might run perfectly fine (it would concatenate the strings) or crash. The responsibility lies entirely with the developer and third-party tools like mypy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go: Mandatory Types
&lt;/h3&gt;

&lt;p&gt;Go is a statically typed language. Types are not optional; they are part of the language's DNA. The function signature is explicitly defined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&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 signature is rigid and unmistakable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inputs&lt;/strong&gt;: a (int) and b (int).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output&lt;/strong&gt;: int.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Go compiler rigorously checks these type definitions during the &lt;em&gt;compilation phase&lt;/em&gt;, which happens before the code ever runs. This is known as compile-time safety. Consequently, if you try to compile add("Hello", "World"), the compiler will halt and refuse to build the executable, throwing a type mismatch error instantly.&lt;/p&gt;

&lt;p&gt;This difference highlights the core philosophies: Python acts like a flexible workshop where you can modify things quickly with few restrictions, while Go acts like a precision engineering lab where everything must be measured and declared upfront to prevent catastrophic failures later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Returning Data
&lt;/h2&gt;

&lt;p&gt;Most functions are designed not just to perform an action but to compute a result and hand it back to the part of the program that called them. For example, a calculator function isn't helpful if it just calculates internally and throws the answer away; it must return the answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python: Returning Values
&lt;/h3&gt;

&lt;p&gt;Python uses the return keyword to send data back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Output: 15  
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While Python appears to support returning multiple values, it actually does so using a trick. When you write return "Michael", 25, Python is internally creating a tuple and returning that single container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_info&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Michael&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;user_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# This is tuple unpacking  
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function didn't natively return two separate things; it returned one tuple, and Python gracefully unpacked it into two variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go: Native Multiple Return Values
&lt;/h3&gt;

&lt;p&gt;Go has native support for returning multiple distinct values directly from the function, without wrapping them in a container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;userInfo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&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="s"&gt;"Michael"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;userInfo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="c"&gt;// name is now "Michael", age is now 25  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The (string, int) part of the signature explicitly declares that this function will produce two separate values. This is a language-level feature, not a trick.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Multiple Returns Are a Game-Changer in Go
&lt;/h2&gt;

&lt;p&gt;The native support for multiple return values isn't just a syntactic convenience; it fundamentally shapes how Go handles errors.&lt;/p&gt;

&lt;p&gt;In many other languages (including Python), errors are often handled using try/except blocks. These exceptions can be thrown deep inside a function and caught elsewhere, potentially leading to situations where a developer forgets to catch an error entirely, causing the program to crash unpredictably.&lt;/p&gt;

&lt;p&gt;Go takes a radically different approach. It discourages exceptions in favor of explicit error handling. The most idiomatic pattern in Go is to return &lt;strong&gt;two values&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The actual result (if successful).
&lt;/li&gt;
&lt;li&gt;An error value (if something went wrong).
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&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="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cannot divide by zero"&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="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="c"&gt;// nil means "no error"  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you call this function, you are forced to immediately acknowledge both the result and the possibility of an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Oops:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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;This pattern appears everywhere in Go. It forces the developer to confront the possibility of failure right at the point of execution, leading to more robust, predictable software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python vs. Go: The Underlying Philosophies
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Python's Angle:&lt;/strong&gt; Python focuses on developer velocity and flexibility. It uses def, treats types as optional enhancements, and allows functions to accept a variety of data without strict declarations. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go's Angle:&lt;/strong&gt; Go focuses on clarity, maintainability, and safety. It uses func, mandates types, and ensures that the inputs and outputs of every function are crystal clear to both the developer and the compiler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;Mastering functions is an exciting leap in the programming journey. It marks the transition from writing small, disposable scripts to architecting real, maintainable applications. Functions allow you to take complex, tangled logic and break it down into small, reusable pieces.&lt;/p&gt;

&lt;p&gt;A Python developer moving to Go might initially feel constrained, asking, &lt;em&gt;"Why do I have to write all these types and explicitly handle every error?"&lt;/em&gt;     &lt;/p&gt;

&lt;p&gt;I felt this way before, and honestly, its worth it. This constraint is a feature, not a bug. Go pushes you to clearly articulate how data moves through your program, ensuring you understand the flow of information thoroughly before the code even runs. Learning to appreciate this enforced clarity doesn't just make you better at Go; it fundamentally sharpens your discipline as a developer. It trains you to think critically about data flow and architecture, a skill that is invaluable regardless of which language you ultimately choose to write your applications in.&lt;/p&gt;

&lt;p&gt;Thanks for reaching the end of my article, like, comment and share, lets keep-on our journey dual-learning.  &lt;/p&gt;

</description>
      <category>python</category>
      <category>go</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why Go's Goroutines Made Concurrency Finally Click for Me</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Fri, 19 Jun 2026 18:12:27 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/why-gos-goroutines-made-concurrency-finally-click-for-me-n9e</link>
      <guid>https://dev.to/ezeanamichael/why-gos-goroutines-made-concurrency-finally-click-for-me-n9e</guid>
      <description>&lt;p&gt;I’ve been writing Python for a long time, and like many developers in that space, I got used to a certain way of thinking about concurrency: async/await, event loops, and carefully managing when things pause and resume. It worked well but sometimes it felt like I was always negotiating with the runtime instead of just expressing what I actually want: “run these things at the same time.”&lt;br&gt;&lt;br&gt;
Then I started studying Go (programming language), and specifically goroutines.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Python Mental Model: Concurrency as Coordination
&lt;/h2&gt;

&lt;p&gt;In Python, especially with asyncio, concurrency often feels like structured waiting. With Python (programming language), you typically deal with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An event loop
&lt;/li&gt;
&lt;li&gt;async functions
&lt;/li&gt;
&lt;li&gt;await points that explicitly yield control
&lt;/li&gt;
&lt;li&gt;Tasks that must cooperate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t just “run things at the same time.” You define where they can pause.&lt;br&gt;&lt;br&gt;
That design is nice, especially for I/O-heavy workloads. But mentally, there’s always overhead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where do I await?
&lt;/li&gt;
&lt;li&gt;Am I blocking the loop?
&lt;/li&gt;
&lt;li&gt;Why isn’t this coroutine running?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even when you understand it, concurrency still feels like something you carefully orchestrate.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enter Goroutines: Concurrency as a Default State
&lt;/h2&gt;

&lt;p&gt;Then I met goroutines. A goroutine is deceptively simple:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go doSomething()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That’s it, no need for an async keyword, event loop management or even explicit suspension points. The runtime handles scheduling. You don’t coordinate concurrency, you declare it.&lt;br&gt;&lt;br&gt;
At first, this feels almost too simple. But that’s the shift: Go already made the hard decisions for you.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Mental Shift: From Await Points to Independent Workers
&lt;/h2&gt;

&lt;p&gt;To illustrate, Python async feels like a single chef multitasking in one kitchen. Go feels like hiring multiple cooks.&lt;br&gt;&lt;br&gt;
In Python:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One worker switches tasks
&lt;/li&gt;
&lt;li&gt;You define pause points
&lt;/li&gt;
&lt;li&gt;Everything shares a single execution flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each goroutine is a worker
&lt;/li&gt;
&lt;li&gt;Tasks run independently
&lt;/li&gt;
&lt;li&gt;You just assign work and move on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That difference is why goroutines clicked: they match how systems feel in real life, not how we simulate them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Async vs Go: Pros and Cons
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Python Async (async/await)
&lt;/h3&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very explicit control over execution flow
&lt;/li&gt;
&lt;li&gt;Excellent for structured I/O concurrency (web servers, APIs)
&lt;/li&gt;
&lt;li&gt;Easier debugging in some cases (you can trace await chains)
&lt;/li&gt;
&lt;li&gt;Fine-grained control over when tasks yield&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires careful mental tracking of the event loop
&lt;/li&gt;
&lt;li&gt;“Async all the way down” problem (one blocking call breaks everything)
&lt;/li&gt;
&lt;li&gt;More boilerplate and discipline required
&lt;/li&gt;
&lt;li&gt;Easy to accidentally mix sync + async and create issues
&lt;/li&gt;
&lt;li&gt;Concurrency feels manual rather than natural&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Go Goroutines
&lt;/h3&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extremely simple syntax (go function())
&lt;/li&gt;
&lt;li&gt;Concurrency feels natural and lightweight
&lt;/li&gt;
&lt;li&gt;Runtime handles scheduling automatically
&lt;/li&gt;
&lt;li&gt;Scales easily to thousands/millions of goroutines
&lt;/li&gt;
&lt;li&gt;Cleaner mental model for independent tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less explicit control over scheduling
&lt;/li&gt;
&lt;li&gt;Can accidentally create race conditions if not careful
&lt;/li&gt;
&lt;li&gt;Requires channels or sync primitives for safe communication
&lt;/li&gt;
&lt;li&gt;Debugging concurrency issues can feel more opaque
&lt;/li&gt;
&lt;li&gt;“Too easy to start tasks” can lead to uncontrolled goroutine growth&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Channels Made It Even Clearer
&lt;/h2&gt;

&lt;p&gt;Goroutines alone are powerful, but channels complete the picture. Instead of shared memory and locks, Go encourages communication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;  
&lt;span class="p"&gt;}()&lt;/span&gt;  
&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is simple:&lt;br&gt;&lt;br&gt;
Don’t share memory. Communicate instead. That forces a clean mental model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who sends data?
&lt;/li&gt;
&lt;li&gt;Who receives it?
&lt;/li&gt;
&lt;li&gt;What flows through the system?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why It Clicked After Python Async
&lt;/h2&gt;

&lt;p&gt;Ironically, I don’t think goroutines would’ve made sense to me without first struggling through Python async.&lt;br&gt;&lt;br&gt;
Python taught me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Concurrency is not parallelism
&lt;/li&gt;
&lt;li&gt;Blocking matters
&lt;/li&gt;
&lt;li&gt;Coordination is hard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go removed the ceremony and exposed the core idea: Concurrency is just structuring multiple flows of work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Control vs Trust
&lt;/h2&gt;

&lt;p&gt;Python async gives you control, so you decide when things pause. Go gives you trust, the runtime handles scheduling.&lt;br&gt;&lt;br&gt;
That shift is subtle but powerful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python: “I will manage concurrency carefully”
&lt;/li&gt;
&lt;li&gt;Go: “I will describe work and let the system handle it”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first, trust feels risky. But it’s also what makes Go feel effortless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Learning Go didn’t just give me a new tool, it changed how I think about concurrent systems. I still use Python and appreciate async/await, but I see it more clearly: it’s structured concurrency with explicit control. And in Go, I stop thinking about pauses . I just think: Start this. Let it run. Communicate when needed. That’s what finally made concurrency click. Its been a pretty fun journey, Let me know your thoughts, Like, Share and Comment what you think.  &lt;/p&gt;

</description>
      <category>python</category>
      <category>go</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>The Bilingual Developer: Python and Go Looping &amp; Iteration</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Fri, 12 Jun 2026 18:13:42 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-looping-iteration-cgl</link>
      <guid>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-looping-iteration-cgl</guid>
      <description>&lt;p&gt;In the last article, I wrote about how programs make decisions using conditionals. We went through how a program can make a decision, choosing one path over another based on whether a condition is true or false.&lt;/p&gt;

&lt;p&gt;But what if we need to perform the same action multiple times? Let's say you have a list of about 1,000 users and want to email each of them. You wouldn't write the email-sending code 1,000 times. Instead, you would write it once and have the program repeat it for each user. This is where looping comes in.&lt;/p&gt;

&lt;p&gt;Looping allows a program to repeatedly execute a block of code until a condition is met or until all items in a collection have been processed. It's one of the most powerful concepts in programming because it helps us automate repetitive tasks and work with large amounts of data efficiently. Whether you're building a web application, analyzing data, processing files, or developing APIs, you'll find loops everywhere. Let's see how Python and Go approach this concept.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Iteration
&lt;/h2&gt;

&lt;p&gt;Iteration simply means moving through a collection of data one item at a time. For example, if you have:&lt;br&gt;&lt;br&gt;
students = ["John", "Sarah", "David"]&lt;br&gt;&lt;br&gt;
Iteration means accessing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;John
&lt;/li&gt;
&lt;li&gt;Sarah
&lt;/li&gt;
&lt;li&gt;David&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;one after another. Loops are the mechanism that makes iteration possible. We will now consider some types of loops, first the for loop.&lt;/p&gt;

&lt;p&gt;The For Loop&lt;/p&gt;

&lt;p&gt;A for loop is used when you want to repeat something a specific number of times or go through a collection of items. &lt;/p&gt;
&lt;h2&gt;
  
  
  Python's Approach: for item in sequence
&lt;/h2&gt;

&lt;p&gt;Python's for loop is designed around iteration. Instead of asking you to manage counters manually, Python allows you to directly loop through a sequence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sarah&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;David&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you read that aloud, it almost sounds like English: “For each student in students, print the student.” That's one of the reasons Python is often praised for readability. Python also provides the range() function when you want to repeat something a specific number of times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0  
1  
2  
3  
4  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can note that Python focuses less on how the loop works internally and more on what you're trying to accomplish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go's Approach: The Universal for Keyword
&lt;/h2&gt;

&lt;p&gt;Instead of providing separate loop structures for different situations, Go uses a single keyword: for. This one keyword handles almost every looping scenario.&lt;br&gt;&lt;br&gt;
A traditional Go for loop looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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;This structure contains three parts: initialization; condition; post-action&lt;br&gt;&lt;br&gt;
In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;i := 0 initializes the counter
&lt;/li&gt;
&lt;li&gt;i &amp;lt; 5 determines how long the loop runs (in this case limiting to 5)
&lt;/li&gt;
&lt;li&gt;i++ updates the counter by 1 after each iteration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When iterating over collections, Go uses the range keyword.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Sarah"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"David"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;student&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;Unlike Python, Go exposes both the position and the value by default.&lt;br&gt;&lt;br&gt;
This reflects Go's preference for being explicit about what's happening during execution.&lt;/p&gt;
&lt;h2&gt;
  
  
  The While Loop
&lt;/h2&gt;

&lt;p&gt;Not every situation involves iterating through a collection. Sometimes you want code to keep running as long as a condition remains true.&lt;br&gt;&lt;br&gt;
For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep asking for a password until the user enters the correct one.
&lt;/li&gt;
&lt;li&gt;Continue processing requests while the server is running.
&lt;/li&gt;
&lt;li&gt;Retry an operation until it succeeds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where while loops become useful.&lt;/p&gt;
&lt;h2&gt;
  
  
  Python's Explicit while Loop
&lt;/h2&gt;

&lt;p&gt;Python provides a dedicated keyword for this purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;  
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic is straightforward, It continues running this block while the condition remains true and each time the loop runs, the condition is checked again So once the condition becomes false, the loop stops.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go's Approach: Using for as a While Loop
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Go does not have a while keyword.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Instead, Go reuses its universal for loop. To create while-loop behavior, you simply remove the initialization and post-action sections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;  
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Infinite Loops
&lt;/h2&gt;

&lt;p&gt;Sometimes a loop is intended to run forever until something inside it stops execution.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Running...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running..."&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;You'll often see these in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web servers
&lt;/li&gt;
&lt;li&gt;Background workers
&lt;/li&gt;
&lt;li&gt;Event listeners
&lt;/li&gt;
&lt;li&gt;Real-time systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Breaking and Continuing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To understand breaking and continuing, we should understand that not every loop should run to completion. Sometimes we want to stop a loop early or skip a particular iteration. This is where break and continue become useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using break
&lt;/h2&gt;

&lt;p&gt;The break statement immediately terminates the loop.&lt;br&gt;&lt;br&gt;
Python example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
        &lt;span class="k"&gt;break&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0  
1  
2  
3  
4  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The moment the value reaches 5, the loop stops completely. Go works the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;break&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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;Again, execution stops as soon as the break statement is reached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using continue
&lt;/h2&gt;

&lt;p&gt;The continue statement is slightly different. Instead of stopping the loop, it skips the current iteration and moves to the next one.&lt;br&gt;&lt;br&gt;
Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&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="k"&gt;continue&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0  
1  
3  
4  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that 2 is skipped. Go behaves the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;continue&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&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 current iteration is skipped, but the loop itself continues running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python's Angle vs Go's Angle
&lt;/h2&gt;

&lt;p&gt;Looking at loops gives us another glimpse into the philosophy of both languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Python's Angle&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Python is designed to make iteration feel natural.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;for item in sequence
&lt;/li&gt;
&lt;li&gt;Dedicated while keyword
&lt;/li&gt;
&lt;li&gt;Readable syntax
&lt;/li&gt;
&lt;li&gt;Focus on expressing intent clearly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Python often hides implementation details so you can focus on solving the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Go's Angle&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Go prefers consistency over having many specialized constructs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One loop keyword (for)
&lt;/li&gt;
&lt;li&gt;Multiple looping styles using the same structure
&lt;/li&gt;
&lt;li&gt;Explicit control over loop behavior
&lt;/li&gt;
&lt;li&gt;Less language complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go's mindset is:&lt;br&gt;&lt;br&gt;
Learn one loop mechanism and use it everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;Looping is one of the fast ways programs get work done in programming. Without loops, applications would struggle to process lists, handle user input, analyze data, or automate repetitive tasks. Python gives you specialized, highly readable constructs for iteration. Go gives you a single, versatile tool that can adapt to different situations.Both approaches are effective.&lt;/p&gt;

&lt;p&gt;The real skill as a bilingual developer isn't memorizing syntax, but it's understanding the underlying concept. Once you understand what a loop is trying to achieve, switching between Python and Go becomes much easier. The syntax may change, but the logic remains exactly the same: repeat a task until you're done. Thanks for reading this article, hit the like and comment what you think, thanks.  &lt;/p&gt;

</description>
      <category>python</category>
      <category>go</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Rewrote Our REST API in GraphQL, Here's When It's Worth It</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Tue, 09 Jun 2026 09:55:34 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/i-rewrote-our-rest-api-in-graphql-heres-when-its-worth-it-nkf</link>
      <guid>https://dev.to/ezeanamichael/i-rewrote-our-rest-api-in-graphql-heres-when-its-worth-it-nkf</guid>
      <description>&lt;p&gt;For most of my development career, REST was my only way of building APIs. It was what I learned first, and it stayed with me. I used it in different applications, including business applications, GIS platforms, dashboards, and e-commerce systems. REST felt natural because it was structured around resources, and the HTTP protocol made everything predictable.&lt;/p&gt;

&lt;p&gt;I never really had a strong reason to explore GraphQL. It always felt like something that introduced extra level complexity and uncertainty without a clear benefit in a real production environment. That changed when I decided to rebuild part of an existing REST API using GraphQL, not as a replacement, but as an experiment to understand where it actually fits.&lt;/p&gt;

&lt;h2&gt;
  
  
  How REST Structures Systems
&lt;/h2&gt;

&lt;p&gt;REST works by exposing resources through endpoints. In an e-commerce system, this typically looks like a clear separation of concerns across entities.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GET /products/100&lt;br&gt;&lt;br&gt;
GET /products/100/reviews&lt;br&gt;&lt;br&gt;
GET /products/100/related&lt;br&gt;&lt;br&gt;
GET /sellers/20&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each endpoint returns a specific dataset, and the frontend is responsible for combining them.&lt;/p&gt;

&lt;p&gt;A simple product response might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wireless Headphones"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"seller_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then another request is required to fetch the seller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tech Store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"rating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.7&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure works well because it is simple, explicit, and easy to debug. REST aligns strongly with business workflows where operations are clearly defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where REST Starts to Show Limits
&lt;/h2&gt;

&lt;p&gt;The challenge appears when frontend screens become more data-heavy. A single page in a modern application is rarely powered by a single endpoint. For a product page in an e-commerce system, the frontend may need product details, seller information, reviews, inventory, and related products.&lt;/p&gt;

&lt;p&gt;With REST, this often becomes multiple sequential or parallel requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /products/100  
GET /sellers/20  
GET /products/100/reviews  
GET /inventory/100  
GET /products/100/related
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend is forced to merge these responses into one coherent view. On fast networks, this is manageable. On slower networks or mobile devices, it introduces latency and complexity in state management.&lt;/p&gt;

&lt;h2&gt;
  
  
  How GraphQL Changes the Model
&lt;/h2&gt;

&lt;p&gt;GraphQL shifts the responsibility from multiple endpoints to a single query system. So Instead of the server deciding what each endpoint returns, the client defines exactly what it needs.&lt;/p&gt;

&lt;p&gt;A GraphQL query for the same product page might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;seller&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;relatedProducts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response comes back in a single structured payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="nl"&gt;"product"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wireless Headphones"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="nl"&gt;"seller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tech Store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="nl"&gt;"rating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.7&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="nl"&gt;"reviews"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
          &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
          &lt;/span&gt;&lt;span class="nl"&gt;"comment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Very good quality"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
          &lt;/span&gt;&lt;span class="nl"&gt;"rating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="nl"&gt;"inventory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="nl"&gt;"warehouse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Lagos Hub"&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="nl"&gt;"relatedProducts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bluetooth Speaker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
          &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of multiple requests, everything is resolved in one round trip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backend Structure Comparison
&lt;/h2&gt;

&lt;p&gt;A REST controller typically looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/products/&amp;lt;int:id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&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;get_product_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/products/&amp;lt;int:id&amp;gt;/reviews&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_reviews&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&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;get_reviews_by_product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In GraphQL, the structure shifts to types and resolvers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
    &lt;span class="n"&gt;seller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Seller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;reviews&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Review&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  
    &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;graphene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resolve_product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&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;fetch_product_with_relations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important difference lies in how data relationships are modeled. REST separates concerns by endpoint. GraphQL models relationships directly inside the type system.&lt;/p&gt;

&lt;h2&gt;
  
  
  GIS Example Where GraphQL Becomes More Obvious
&lt;/h2&gt;

&lt;p&gt;In GIS and land management systems, data is naturally relational. A single land parcel is connected to many entities.&lt;/p&gt;

&lt;p&gt;With REST, this might require multiple endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /lands/100  
GET /owners/25  
GET /surveys/10  
GET /documents?land_id=100  
GET /transactions?land_id=100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With GraphQL, the same structure becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="n"&gt;land&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="n"&gt;parcelNumber&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;survey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;surveyor&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="n"&gt;transactions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="w"&gt;  
      &lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response mirrors the real-world relationship between entities instead of forcing the frontend to assemble it manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where GraphQL Does Not Replace REST
&lt;/h2&gt;

&lt;p&gt;GraphQL is not designed for business operations. It is not ideal for workflows that involve state changes, validations, and side effects.&lt;/p&gt;

&lt;p&gt;Actions like the following still fit REST better:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;POST /orders&lt;br&gt;&lt;br&gt;
POST /login&lt;br&gt;&lt;br&gt;
POST /payments&lt;br&gt;&lt;br&gt;
POST /upload-document&lt;br&gt;&lt;br&gt;
POST /approve-transaction&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These operations represent business intent rather than data retrieval. REST communicates that intent more clearly through HTTP semantics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protocol and Architectural Difference
&lt;/h2&gt;

&lt;p&gt;REST is built directly on HTTP methods and resource-based URLs. Each endpoint represents a specific resource or operation, and caching is naturally supported at the HTTP layer.&lt;/p&gt;

&lt;p&gt;GraphQL typically exposes a single endpoint:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;POST /graphql&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The complexity moves into the query layer. This flexibility allows precise data fetching but introduces challenges in caching, monitoring, and query optimization.&lt;/p&gt;

&lt;h2&gt;
  
  
  When GraphQL Is Worth It
&lt;/h2&gt;

&lt;p&gt;GraphQL becomes valuable in systems where data is highly connected and frontend requirements change frequently. This includes dashboards, analytics platforms, GIS systems, social applications, and mobile apps that require aggregated data from multiple sources.&lt;/p&gt;

&lt;p&gt;REST remains stronger in systems that are workflow-driven, transactional, and action-oriented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally,
&lt;/h2&gt;

&lt;p&gt;After working with both approaches, the conclusion is not that one replaces the other. It is that they solve different categories of problems. REST is better suited for business operations and system workflows. GraphQL is better suited for flexible data retrieval in highly relational systems.In most real-world architectures, the right answer is not choosing one over the other, but understanding where each one fits and combining them intentionally. &lt;/p&gt;

&lt;p&gt;What’s your opinion? Let me know in the comments below, give a good read, like and share.&lt;/p&gt;

</description>
      <category>restapi</category>
      <category>graphql</category>
      <category>backenddevelopment</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Bilingual Developer: Python and Go Conditionals</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Fri, 05 Jun 2026 16:09:06 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-conditionals-12h5</link>
      <guid>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-conditionals-12h5</guid>
      <description>&lt;p&gt;So far, we've talked about how data is stored in memory and the different data types available in Python and Go. Storing data is only part of programming. At some point, our programs need to make decisions.&lt;/p&gt;

&lt;p&gt;When thinking about real-world applications, you can think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should a user be allowed to log in?
&lt;/li&gt;
&lt;li&gt;Is a student eligible for admission?
&lt;/li&gt;
&lt;li&gt;Has a customer completed payment?
&lt;/li&gt;
&lt;li&gt;Should an email notification be sent?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all these situations, the program needs to decide what action to take based on certain conditions. This is where &lt;strong&gt;conditionals&lt;/strong&gt; come in. Conditionals allow a program to make decisions based on whether a condition is true or false.&lt;/p&gt;

&lt;p&gt;Although Python and Go solve the same problem, they approach conditionals in slightly different ways. In this article, we’ll explore both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Syntax Shift: How Python and Go Define Code Blocks
&lt;/h2&gt;

&lt;p&gt;One of the first things you'll notice when writing conditionals in Python and Go is that they define code blocks differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;In Python, Indentation Matters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Python uses a combination of colons (:) and indentation to indicate which code belongs to a condition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;  
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are an adult&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The condition ends with a colon (:).
&lt;/li&gt;
&lt;li&gt;The code inside the condition is indented.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The indentation is not optional.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;  
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are an adult&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces an error because Python relies on indentation to understand the structure of your program. Python's philosophy here is simple:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code should be readable and visually organized.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By forcing indentation, Python ensures that developers write code in a consistent format.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;In Go, Curly Braces Define Structure&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Go takes a different route. Instead of indentation, it uses curly braces {} to define blocks of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;  
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You are an adult"&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 braces tell Go exactly where the conditional block starts and ends. Even if you change the spacing or indentation, Go still understands the structure because the braces define it. One important thing to note is that Go does not require parentheses around conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Adult"&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;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Adult"&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;While the second style is common in some languages, Go intentionally keeps the syntax cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;If/Else Chains&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A single condition is useful, but real applications often need multiple possible outcomes.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A score above 70 is an A.
&lt;/li&gt;
&lt;li&gt;A score above 60 is a B.
&lt;/li&gt;
&lt;li&gt;A score above 50 is a C.
&lt;/li&gt;
&lt;li&gt;Anything lower is a fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where if/else chains become useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Python's elif&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Python introduces the elif keyword, which stands for "else if."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;  
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade C&lt;/span&gt;&lt;span class="sh"&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fail&lt;/span&gt;&lt;span class="sh"&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 program checks each condition from top to bottom. As soon as one condition evaluates to True, Python executes that block and skips the rest. This keeps the code concise and easy to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Go's else if&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go achieves the same thing using else if.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;75&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Grade A"&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="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Grade B"&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="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Grade C"&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fail"&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;Functionally, this behaves exactly like Python's elif. The main difference is syntax. Python creates a special keyword (elif). Go combines two existing keywords (else if).&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Quick Comparison&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;Python&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;if&lt;/td&gt;
&lt;td&gt;if&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;elif&lt;/td&gt;
&lt;td&gt;else if&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;else&lt;/td&gt;
&lt;td&gt;else&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses indentation&lt;/td&gt;
&lt;td&gt;Uses braces&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Pattern Matching and Multi-Way Decisions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes an application needs to compare a value against many possible options. Imagine you're building a system that handles user roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Admin
&lt;/li&gt;
&lt;li&gt;Staff
&lt;/li&gt;
&lt;li&gt;Student
&lt;/li&gt;
&lt;li&gt;Guest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using multiple if statements can become messy. Both Python and Go provide a cleaner solution, but they do it differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Python's match/case&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Starting from Python 3.10, Python introduced match/case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Admin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  
&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Admin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Full access&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Staff&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Limited access&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Student&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Student access&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Guest access&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of match as saying:&lt;/p&gt;

&lt;p&gt;"Compare this value against several patterns and execute the matching block."&lt;/p&gt;

&lt;p&gt;The underscore (_) acts as a default case. One reason match/case is powerful is that it can do more than simple value comparisons.&lt;/p&gt;

&lt;p&gt;It can match:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Values
&lt;/li&gt;
&lt;li&gt;Lists
&lt;/li&gt;
&lt;li&gt;Tuples
&lt;/li&gt;
&lt;li&gt;Object structures
&lt;/li&gt;
&lt;li&gt;Complex patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it much more powerful than traditional switch statements found in many languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Go's switch Statement&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go uses switch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Admin"&lt;/span&gt;  
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"Admin"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Full access"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"Staff"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Limited access"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"Student"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Student access"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Guest access"&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;At first glance, this looks similar to Python's match/case. However, Go's switch statement has a few interesting capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Switch Without an Expression&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One unique feature of Go is that a switch can be used without directly switching on a variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;75&lt;/span&gt;  
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Grade A"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Grade B"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fail"&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;This behaves almost like an organized replacement for a long if/else if chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Multiple Values in a Case&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go also allows multiple matching values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Saturday"&lt;/span&gt;  
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"Saturday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Sunday"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Weekend"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Weekday"&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;This can make decision logic much cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion: Python's Angle vs Go's Angle&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Python's Angle&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Python focuses on readability and expressiveness.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Indentation clearly shows structure.
&lt;/li&gt;
&lt;li&gt;elif makes multi-condition chains easy to read.
&lt;/li&gt;
&lt;li&gt;match/case supports powerful pattern matching.
&lt;/li&gt;
&lt;li&gt;The language tries to make decision logic feel natural and close to plain English.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Go's Angle&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Go focuses on simplicity and predictability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Curly braces explicitly define blocks.
&lt;/li&gt;
&lt;li&gt;else if keeps the language small by reusing existing keywords.
&lt;/li&gt;
&lt;li&gt;The switch is versatile enough to replace many if/else chains.
&lt;/li&gt;
&lt;li&gt;The language avoids adding too many specialized features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading. Hope you learned something new. Read, like and comment, thanks.&lt;/p&gt;

</description>
      <category>python</category>
      <category>go</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>7 REST API Mistakes I Made as a Junior Developer</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Tue, 02 Jun 2026 16:27:15 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/7-rest-api-mistakes-i-made-as-a-junior-developer-3b4i</link>
      <guid>https://dev.to/ezeanamichael/7-rest-api-mistakes-i-made-as-a-junior-developer-3b4i</guid>
      <description>&lt;p&gt;REST APIs are one way applications exchange information, especially between the client and server sides of modern systems. APIs are created on the server and consumed by web, mobile, or desktop clients.&lt;/p&gt;

&lt;p&gt;When I started my career as a junior developer, I built several APIs that worked, but I learned lessons through experience. My APIs were not always designed with scalability, maintainability, or even best practices in mind. As I gained more experience, I discovered some mistakes that I repeatedly made and learned how to correct them.&lt;/p&gt;

&lt;p&gt;Here are seven REST API mistakes I made as a junior developer and the lessons I learned from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Not Versioning My APIs Early&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One of the biggest mistakes I made was launching APIs without versioning them from the start. At first, this seemed fine because there was only one client consuming the API. However, as the requirements changed, introducing breaking changes became difficult because existing clients depended on the old structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Learned is this:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Always version your APIs from day one, even if you don't think you'll need multiple versions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;/api/v1/users
&lt;/li&gt;
&lt;li&gt;/api/v1/orders
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Versioning helps to give you the flexibility to evolve your API without breaking existing consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Overloading GET Endpoints&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I used to create GET endpoints that returned every piece of information about a resource, including large nested objects and related records. This often resulted in slow responses and unnecessary data transfer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Learned is this:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Not every endpoint needs to return full details. It's perfectly acceptable to have(For Example):&lt;/p&gt;

&lt;p&gt;GET /users&lt;/p&gt;

&lt;p&gt;To return a summarized view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john@example.com"&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then use:&lt;/p&gt;

&lt;p&gt;GET /users/1&lt;/p&gt;

&lt;p&gt;To return complete information about the user. This approach improves performance and reduces payload sizes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. Exposing My Database Structure Directly&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Early in my career, I mapped database tables directly to API responses. As a result, clients became tightly coupled to the database design.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"tbl_user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"tbl_user_fname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What I Learned is this:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An API should represent business resources, not database tables. A cleaner response would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us the freedom to modify our database without affecting API consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Not Implementing Pagination Early&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One mistake I made was returning entire datasets from the API. This worked fine during development when there were only a few records, but it quickly became a performance issue as the application grew.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Learned is this:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Large datasets should be paginated from the beginning. Instead of:&lt;/p&gt;

&lt;p&gt;GET /users&lt;/p&gt;

&lt;p&gt;Returning thousands of records, use pagination:&lt;/p&gt;

&lt;p&gt;GET /users?page=1&amp;amp;limit=20&lt;/p&gt;

&lt;p&gt;Pagination improves performance, reduces bandwidth usage, and provides a better experience for API consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5. Not Thinking About Authentication and Authorization Early&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As a junior developer, I focused heavily on making endpoints work and sometimes overlooked who should be allowed to access them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Learned is this:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authentication and authorization should be part of the API design process from the start.&lt;/p&gt;

&lt;p&gt;Ask questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who can access this endpoint?
&lt;/li&gt;
&lt;li&gt;Should this action require login?
&lt;/li&gt;
&lt;li&gt;Are there admin-only operations?
&lt;/li&gt;
&lt;li&gt;What happens if an unauthorized user makes a request?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementing proper access control early helps prevent security issues during development and future refactoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6. Not Standardizing Error Responses&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In some projects, every endpoint returned errors differently. One endpoint might return a message, another might return a list of errors, while another might return a completely different structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Learned is this:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Error responses should follow a consistent format throughout the API.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"User not found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USER_NOT_FOUND"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A standardized error structure makes debugging easier and allows frontend developers to handle errors consistently across the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;7. Skipping Documentation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As a junior developer, I often assumed that my API endpoints were self-explanatory. They weren't. Even I sometimes forgot how certain endpoints worked after a few weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Learned is this:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Good documentation saves time for both API consumers(Frontend developers and others) and future maintainers.&lt;/p&gt;

&lt;p&gt;Document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Endpoint URLs
&lt;/li&gt;
&lt;li&gt;Request methods
&lt;/li&gt;
&lt;li&gt;Request parameters
&lt;/li&gt;
&lt;li&gt;Authentication requirements
&lt;/li&gt;
&lt;li&gt;Response examples
&lt;/li&gt;
&lt;li&gt;Error responses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clear documentation reduces misunderstandings and speeds up integration efforts.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Building APIs that simply work is relatively easy. Building APIs that are maintainable, scalable, and pleasant for other developers to consume requires more thought and experience.&lt;/p&gt;

&lt;p&gt;Looking back, these mistakes taught me valuable lessons about API design. Today, whenever I create a new REST API, I focus on versioning early, keeping responses consistent, using proper HTTP methods, avoiding database leakage, and designing endpoints with long-term maintainability in mind.&lt;/p&gt;

&lt;p&gt;The best API designs are often the simplest ones: predictable, well-documented, and easy for other developers to understand. Thanks for going through my article. Please leave a like and comment. Thanks.&lt;/p&gt;

</description>
      <category>restapi</category>
      <category>backenddevelopment</category>
      <category>webdev</category>
      <category>developer</category>
    </item>
    <item>
      <title>The Bilingual Developer: Python and Go Primitive Data Types</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Fri, 29 May 2026 15:50:56 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-primitive-data-types-4c5f</link>
      <guid>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-primitive-data-types-4c5f</guid>
      <description>&lt;p&gt;As discussed in the previous article on the variables about the need of programming languages to store information. This article will be about how the different data is stored. Let’s slow it down a bit and really think about it. If storage is where data lives… then data types are basically &lt;em&gt;how that data is shaped inside memory.&lt;/em&gt; And depending on the language you’re using, that “shape” changes a lot. Primitive data types are the most basic building blocks used to represent values inside a program.&lt;/p&gt;

&lt;p&gt;When learning both Python and Go, understanding their primitive data types is one of the fastest ways to understand the design philosophy behind each language.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Understanding Primitive Data Types&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Primitive data types are the simplest forms of data a programming language can handle directly. They represent single values such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text
&lt;/li&gt;
&lt;li&gt;Numbers
&lt;/li&gt;
&lt;li&gt;Boolean values (true or false)
&lt;/li&gt;
&lt;li&gt;Fixed constant values&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Text and Characters&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Strings in Python&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In Python, text is represented using the &lt;code&gt;str&lt;/code&gt; data type. A string, simply put, is a sequence of characters enclosed in quotation marks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Michael&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello World&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python treats strings as Unicode by default, meaning they can store characters from different languages and symbols.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;emoji&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;😊&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  
&lt;span class="n"&gt;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Python&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of Python’s strengths is how simple string manipulation feels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;first_word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Go&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  
&lt;span class="n"&gt;last_word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Python&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;full_word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_word&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;last_word&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full_word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Go Python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python does not have a separate character (&lt;code&gt;char&lt;/code&gt;) data type. A single character is simply considered a string of length one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;class 'str'&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design keeps the language simpler because developers only need to think about one text type instead of multiple character-based types.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Strings and Runes in Go&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go also uses strings for textual data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Michael"&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;But Go handles characters differently from Python.&lt;/p&gt;

&lt;p&gt;In Go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A string represents a sequence of bytes.
&lt;/li&gt;
&lt;li&gt;A rune represents a single Unicode character.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A rune is actually an alias for &lt;code&gt;int32&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;var letter rune = 'A'&lt;/p&gt;

&lt;p&gt;Notice something important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strings use double quotes &lt;code&gt;" "&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Runes use single quotes &lt;code&gt;' '&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This distinction is very important in Go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt; &lt;span class="kt"&gt;rune&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'G'&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;character&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;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;71
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output is numeric because Go stores runes internally using Unicode code points.&lt;/p&gt;

&lt;p&gt;To print the actual character:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%cn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go’s approach gives developers more control over memory and encoding behavior, especially for systems programming and high-performance applications.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Numbers&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Numbers are another core primitive data type.&lt;/p&gt;

&lt;p&gt;Both Python and Go support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integers
&lt;/li&gt;
&lt;li&gt;Floating-point numbers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Integers and Floats in Python&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Python makes numeric programming simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;  
&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;19.99&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python automatically determines the type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;class 'int'&amp;gt;  
&amp;lt;class 'float'&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One important feature of Python is that integers can grow very large automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;big_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;999999999999999999999999999999&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python dynamically allocates memory for large integers behind the scenes.&lt;/p&gt;

&lt;p&gt;This flexibility is convenient because developers rarely worry about integer overflow or memory size during basic programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Integers and Floats in Go&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go is stricter and more explicit.&lt;/p&gt;

&lt;p&gt;var age int = 25&lt;br&gt;&lt;br&gt;
var price float64 = 19.99&lt;/p&gt;

&lt;p&gt;Go supports multiple integer sizes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;int8&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;int16&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;int32&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;int64&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And floating-point types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;float32&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;float64&lt;/code&gt;&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 go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;smallNumber&lt;/span&gt; &lt;span class="kt"&gt;int8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;  
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;largeNumber&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;9000000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This explicit sizing is important because each type uses a specific amount of memory.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;int8&lt;/td&gt;
&lt;td&gt;8 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int16&lt;/td&gt;
&lt;td&gt;16 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;32 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int64&lt;/td&gt;
&lt;td&gt;64 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Go forces developers to think more carefully about memory usage and performance.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;  
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;

&lt;span class="c"&gt;// This causes an error  &lt;/span&gt;
&lt;span class="c"&gt;// fmt.Println(x + y)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go does not automatically mix different integer sizes. Developers must explicitly convert types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This strictness reduces accidental bugs and improves predictability in large systems.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Booleans&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Booleans represent logical truth values.&lt;/p&gt;

&lt;p&gt;They are heavily used in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conditions
&lt;/li&gt;
&lt;li&gt;Comparisons
&lt;/li&gt;
&lt;li&gt;Decision-making statements&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Booleans in Python&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Python uses:&lt;/p&gt;

&lt;p&gt;True and False&lt;/p&gt;

&lt;p&gt;Notice the capitalization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;is_logged_in&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;  
&lt;span class="n"&gt;is_admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;  
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python’s boolean system is highly flexible because many values can behave as truthy or falsy.&lt;/p&gt;

&lt;p&gt;Examples of falsy values:&lt;/p&gt;

&lt;p&gt;0&lt;br&gt;&lt;br&gt;
None&lt;br&gt;&lt;br&gt;
""&lt;br&gt;&lt;br&gt;
[]&lt;br&gt;&lt;br&gt;
False&lt;/p&gt;

&lt;p&gt;Everything else is generally considered truthy.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Booleans in Go&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go also supports boolean values, but with stricter rules(as usual).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isLoggedIn&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;  
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isAdmin&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the lowercase keywords:&lt;/p&gt;

&lt;p&gt;true and false&lt;/p&gt;

&lt;p&gt;Go does not allow non-boolean values in conditional statements.&lt;/p&gt;

&lt;p&gt;This is invalid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python allows similar truthy checks, but Go requires an actual boolean expression.&lt;/p&gt;

&lt;p&gt;Correct Go example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design improves clarity and reduces ambiguity.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Constants&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Constants are values that should never change during program execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Constants in Python&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Python does not have a true constant keyword. Instead, developers follow a naming convention using uppercase variable names.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.14159&lt;/span&gt;  
&lt;span class="n"&gt;MAX_USERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, Python does not enforce immutability.&lt;/p&gt;

&lt;p&gt;PI = 10&lt;/p&gt;

&lt;p&gt;This still works. The uppercase naming style simply communicates intent to other developers. Python relies heavily on developer discipline and readability conventions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Constants in Go&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Go provides an actual &lt;code&gt;const&lt;/code&gt; keyword.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3.14159&lt;/span&gt;  
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MaxUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once declared, constants cannot be modified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;

&lt;span class="c"&gt;// Error  &lt;/span&gt;
&lt;span class="c"&gt;// Age = 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This enforcement makes programs safer and more predictable. Go constants can also exist without explicitly specifying a type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"GoLang"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler determines the appropriate type automatically.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;In Python, primitive types are designed to feel natural and easy to use. Developers can move quickly without worrying much about memory sizes or strict typing rules.&lt;/p&gt;

&lt;p&gt;In Go, primitive types are more structured and explicit. Developers are expected to think carefully about memory, type safety, and predictability.&lt;/p&gt;

&lt;p&gt;Comment , Share and Like, thanks for reading.&lt;/p&gt;

</description>
      <category>python</category>
      <category>go</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>The N+1 Query That Killed Our Database, And How I Fixed It</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Mon, 25 May 2026 17:39:38 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-n1-query-that-killed-our-database-and-how-i-fixed-it-2al5</link>
      <guid>https://dev.to/ezeanamichael/the-n1-query-that-killed-our-database-and-how-i-fixed-it-2al5</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Everything Worked…But Not Well&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;APIs are affected by the way data is retrieved from the database, and that's something that affected a recent teammate and me during development. In our regular development process, during review and maintenance, the APIs worked, responses came back well, no visible errors. But during this process, we noticed that things started to slow down. Endpoints that used to respond fast suddenly began taking longer, CPU usage on the database increased, and retrieval speed became terrible under load.&lt;/p&gt;

&lt;p&gt;At first, we thought:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maybe the server wasn't powerful enough
&lt;/li&gt;
&lt;li&gt;Maybe network latency was the issue
&lt;/li&gt;
&lt;li&gt;Maybe too many requests were hitting the API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the real issue was hiding inside our database queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Actually Is The N+1 Query Problem?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The N+1 query problem is one of the most common performance issues in backend development, especially when working with relational databases and ORMs(as I, a fan of Django, do). I’m gonna explain this more in SQL terms using retrieval speed and database load.&lt;/p&gt;

&lt;p&gt;The problem happens when your application performs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 query to retrieve parent records
&lt;/li&gt;
&lt;li&gt;Then N extra queries to retrieve related child records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of making one optimized query, the application keeps asking the database more questions repeatedly. This increases the query count, read time, database load, and the API response time. 1 issue, several systems affected.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Simple Example&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's say we have 2 tables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users
&lt;/li&gt;
&lt;li&gt;Orders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We first retrieve all users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM users;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine there are 100 users. Then, for every user retrieved, another query runs to fetch their orders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM orders WHERE user_id = 1;  
SELECT * FROM orders WHERE user_id = 2;  
SELECT * FROM orders WHERE user_id = 3;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it keeps going. So instead of 1 query, you now have 101 queries. That extra load destroys retrieval speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why This Problem Is Dangerous&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The dangerous part is that during development, you might not even notice it. If your database only has just about 5 users and 10 orders, Everything still feels fast.&lt;/p&gt;

&lt;p&gt;But once production data grows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hundreds of users
&lt;/li&gt;
&lt;li&gt;Thousands of records
&lt;/li&gt;
&lt;li&gt;More API requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The database starts struggling badly. This is why some APIs feel fast during testing but start to  slow down after deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Mistake We Made&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The issue wasnt obvious at first because the code itself looked completely normal. We had an endpoint that needed to return users alongside their related orders.&lt;/p&gt;

&lt;p&gt;Something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User information
&lt;/li&gt;
&lt;li&gt;Their recent orders
&lt;/li&gt;
&lt;li&gt;Order counts
&lt;/li&gt;
&lt;li&gt;Related details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The endpoint worked perfectly during development. But internally, Django was fetching related records separately for every user being serialized. Which meant the API kept hitting the database repeatedly behind the scenes.&lt;/p&gt;

&lt;p&gt;The code looked clean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users = User.objects.all()

serializer = UserSerializer(users, many=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in the serializer, related order data was being accessed for every single user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserSerializer(serializers.ModelSerializer):

    orders = OrderSerializer(many=True)

    class Meta:

        model = User

        fields = ['id', 'name', 'orders']

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the real problem started. When Django tried to serialize the response, it kept querying orders separately per user. So if there were 500 users, the system would do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 query to retrieve users
&lt;/li&gt;
&lt;li&gt;Hundreds of additional queries to retrieve orders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the N+1 query problem. The scary part is that nothing looked wrong from the surface. The endpoint returned the correct data and no errors, just slow performance. And as traffic increased, the database load became worse. It was slow because the application kept repeatedly asking for related data instead of retrieving it efficiently.&lt;/p&gt;

&lt;p&gt;The fix was adding query optimization directly to the queryset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users = User.objects.prefetch_related('orders')

serializer = UserSerializer(users, many=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single optimization drastically reduced the number of database hits. Instead of querying orders repeatedly for every user, Django retrieved them efficiently in bulk. Same endpoint and response, much better performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding &lt;code&gt;select_related()&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One major fix for this problem in Django is:&lt;/p&gt;

&lt;p&gt;select_related()&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select_related()&lt;/code&gt; is used for relationships like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ForeignKey
&lt;/li&gt;
&lt;li&gt;OneToOneField&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What it basically does is perform a SQL JOIN and retrieve related data in a single query. Instead of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users = User.objects.all()

for user in users:  
    print(user.profile.phone)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which may generate multiple queries…&lt;/p&gt;

&lt;p&gt;You do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users = User.objects.select_related('profile')  
for user in users:  
    print(user.profile.phone)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Django joins the tables together and retrieves everything at once.&lt;/p&gt;

&lt;p&gt;So instead of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 query for users
&lt;/li&gt;
&lt;li&gt;Multiple queries for profiles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You now get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 optimized query&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Much faster and cleaner.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding &lt;code&gt;prefetch_related()&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Another optimization is:&lt;/p&gt;

&lt;p&gt;prefetch_related()&lt;/p&gt;

&lt;p&gt;This is used mostly for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ManyToMany relationships
&lt;/li&gt;
&lt;li&gt;Reverse ForeignKey relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike &lt;code&gt;select_related()&lt;/code&gt;, this does not use SQL JOINs directly. Instead, Django performs separate queries but combines the results efficiently in memory.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users = User.objects.prefetch_related('orders')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Django may run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM users;  
SELECT * FROM orders WHERE user_id IN (1,2,3,4...);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM orders WHERE user_id = 1;  
SELECT * FROM orders WHERE user_id = 2;  
SELECT * FROM orders WHERE user_id = 3;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is far more efficient. So rather than hundreds of queries, you may only have two.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Difference Between &lt;code&gt;select_related()&lt;/code&gt; And &lt;code&gt;prefetch_related()&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;select_related()&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses SQL JOINs
&lt;/li&gt;
&lt;li&gt;Best for ForeignKey and OneToOne relationships
&lt;/li&gt;
&lt;li&gt;Retrieves related data in a single query&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;prefetch_related()&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses multiple optimized queries
&lt;/li&gt;
&lt;li&gt;Combines data in Python memory
&lt;/li&gt;
&lt;li&gt;Best for ManyToMany and reverse relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both solve the same problem differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Result&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After fixing the queries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Response times dropped massively
&lt;/li&gt;
&lt;li&gt;Database load reduced
&lt;/li&gt;
&lt;li&gt;API became stable again
&lt;/li&gt;
&lt;li&gt;Retrieval speed improved significantly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The funny thing is that we didnt upgrade the server. We didnt increase RAM. We didnt change infrastructure. We simply reduced unnecessary queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What This Experience Taught Me&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One thing this experience taught me is that backend performance is not always about server power. Sometimes your database is suffering simply because of how you are querying it. A badly written retrieval pattern can quietly destroy performance even when your infrastructure is good. Now whenever I build endpoints, I dont just ask “Does this work?” I also ask “How many queries is this generating behind the scenes?” Because sometimes the biggest backend problem is not the logic. Its the retrieval pattern hiding underneath it. Let me know what you think, thanks for reading, like, share, comment and follow for more. &lt;/p&gt;

</description>
      <category>database</category>
      <category>python</category>
      <category>django</category>
      <category>sql</category>
    </item>
    <item>
      <title>How I Cut API Response Time from 2s to &lt;100ms with Redis Caching</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Fri, 22 May 2026 15:09:42 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/how-i-cut-api-response-time-from-2s-to-100ms-with-redis-caching-4h6a</link>
      <guid>https://dev.to/ezeanamichael/how-i-cut-api-response-time-from-2s-to-100ms-with-redis-caching-4h6a</guid>
      <description>&lt;p&gt;Early in my software development years, I had the opportunity to work with a company where I learned backend development. I worked on a system where I was responsible for building the APIs without senior guidance, just documentation, experimentation, and a lot of self-learning.&lt;br&gt;&lt;br&gt;
When learning to design DB models and RESTful APIs. That was it for me, connect everything and let it out via the get request, let it in via the post request, patch things up with the patch request, and delete via the delete request. &lt;/p&gt;

&lt;p&gt;Basic crud operations, and I was fine with that, back then. Eventually, I decided to explore the site myself, and damn, it was slow.&lt;br&gt;&lt;br&gt;
Every interaction came with a noticeable delay. So I stopped assuming things were fine and tested the APIs properly. Using Postman, I measured response times. Most endpoints were taking over 5 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Problem&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every request was hitting the database directly, even when requesting the same data repeatedly.&lt;br&gt;&lt;br&gt;
The system wasn’t slow because the database was bad.&lt;br&gt;&lt;br&gt;
 It was slow because it was doing the same work over and over again.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Changed?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I did some research, investigations, and found something powerful. Caching, and utilizing redis for it. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is Caching?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Caching stores frequently accessed data in memory (Redis uses RAM), allowing much faster retrieval compared to querying a database repeatedly. It reduces database load, instead of hitting the database every time it hits the cache instead and returns the result. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Types of Caching (and Why Redis Fits Here)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Not all caching works the same way. In my case, I implemented &lt;strong&gt;application-level caching with Redis&lt;/strong&gt;, but it helps to understand where it sits in the bigger picture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Application-Level Caching&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This is what I used. The application stores frequently accessed data in a fast in-memory store like Redis.&lt;/p&gt;

&lt;p&gt;Instead of always asking the database:&lt;/p&gt;

&lt;p&gt;API → Database → Response&lt;/p&gt;

&lt;p&gt;We first check:&lt;/p&gt;

&lt;p&gt;API → Redis → Database (only if needed)&lt;/p&gt;

&lt;p&gt;This is the most common approach in backend systems because it gives full control over what gets cached and when it gets updated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Database Caching&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Some databases internally cache query results or use external layers to store repeated query outputs.&lt;/p&gt;

&lt;p&gt;This reduces repeated expensive queries, but it is less flexible compared to Redis-based caching where you control the logic directly inside your API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Distributed Caching&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This is when caching is shared across multiple servers using systems like Redis Cluster or Memcached.&lt;/p&gt;

&lt;p&gt;It becomes important when your application is no longer running on a single server, but across multiple services or microservices.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Therefore,&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before:&lt;br&gt;&lt;br&gt;
Client → API → DB (every request)&lt;/p&gt;

&lt;p&gt;After:&lt;br&gt;&lt;br&gt;
Client → API → Redis → DB (only on cache miss)&lt;/p&gt;

&lt;p&gt;Instead of querying the database every time, the API now checks Redis first. If the data exists, it returns immediately. If not, it fetches from the database, stores the result in Redis, and returns it.&lt;/p&gt;

&lt;p&gt;Here was my initial API response time without caching, &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%2F5op2j9888e3i4dypjgop.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%2F5op2j9888e3i4dypjgop.png" alt="Postman image showing response time of over 5 seconds" width="795" height="25"&gt;&lt;/a&gt;&lt;br&gt;
Here was my API response time afterwards.  &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%2Fwpyb4v6t1pfdk00uwps1.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%2Fwpyb4v6t1pfdk00uwps1.png" alt="Postman image showing response time of less that 200ms" width="783" height="23"&gt;&lt;/a&gt; &lt;br&gt;
I implemented 2 main strategies.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Key-value Caching.
&lt;/li&gt;
&lt;li&gt;Cache invalidation via Write.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my API I implemented key value caching for every get request i.e (get /books/ and get /books/:id)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Eliminating First-Request Slowness (Cache Warm-Up)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One downside of caching is the initial delay when the cache is empty.&lt;br&gt;&lt;br&gt;
How did I solve that? a script. &lt;/p&gt;

&lt;p&gt;I added a cache warm-up script that runs on deployment and preloads frequently accessed data into Redis. That way, the system starts “warm,” and users don’t experience the initial latency.&lt;/p&gt;

&lt;p&gt;At that point, the only time the system feels slow is immediately after cache invalidation.&lt;/p&gt;

&lt;p&gt;But having a cache isn't all good if not invalidated well, because write data comes in too, through post , patch, put. So a cache invalidation strategy was needed. &lt;/p&gt;

&lt;p&gt;I chose cache invalidation via Write for 2 reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data will be refreshed once a put, patch, post or delete request comes in, and
&lt;/li&gt;
&lt;li&gt;Data is not often changed regularly, the data stays for a while because of the type of application we’re dealing with so giving it a time to live and time to die feels too much. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Trade-offs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Every system has tradeoffs as there is no perfect system. The following were the tradeoffs of my decision.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First request after invalidation is slower
&lt;/li&gt;
&lt;li&gt;Cache keys must be managed carefully
&lt;/li&gt;
&lt;li&gt;Slight increase in system complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the system is now significantly faster and more efficient.&lt;/p&gt;

&lt;p&gt;PS: &lt;em&gt;There are several optimization techniques in backend development, this article is just about caching.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Thanks for reading, what do you think about the approach? Read, like and comment. &lt;/p&gt;

</description>
      <category>redis</category>
      <category>backend</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Bilingual Developer: Python and Go Variables</title>
      <dc:creator>Ezeana Micheal</dc:creator>
      <pubDate>Fri, 22 May 2026 14:59:35 +0000</pubDate>
      <link>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-variables-57mm</link>
      <guid>https://dev.to/ezeanamichael/the-bilingual-developer-python-and-go-variables-57mm</guid>
      <description>&lt;p&gt;At the heart of programming is a simple idea:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input -&amp;gt; Processing -&amp;gt; Output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But between input and processing lies something more important, &lt;strong&gt;storage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before a computer can do anything useful with data, it must first store it somewhere. That “somewhere” is memory. And in programming, the way we interact with memory starts with one core concept:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Programming is just a way of communicating with a computer, telling it what to store, how to transform it, and what to return.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore how two very different languages, &lt;strong&gt;Python and Go&lt;/strong&gt;, handle the same idea: variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Variables: The First Mental Model&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A variable is simply a named storage location in memory.&lt;/p&gt;

&lt;p&gt;For example (What it does is):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“store the number 10”
&lt;/li&gt;
&lt;li&gt;“label it as x”
&lt;/li&gt;
&lt;li&gt;“retrieve it later when needed”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple concept,  but different languages implement it very differently.&lt;/p&gt;

&lt;p&gt;And that’s where Python and Go start to diverge.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Python vs Go: Two Different Philosophies&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Python and Go both allow you to store data in variables, but they were designed with different priorities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python: flexibility and speed of writing code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go: structure, safety, and predictability&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This difference shows up immediately in how variables are declared.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Dynamic vs Static Typing&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Python (Dynamic Typing)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In Python, you don’t explicitly declare the type of a variable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x=10&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%2Fjirvpxdopnyhya4y1j73.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%2Fjirvpxdopnyhya4y1j73.png" alt="Python variable image" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Python automatically figures out the datatype at runtime.&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;dynamic typing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It gives you flexibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can reuse variables freely
&lt;/li&gt;
&lt;li&gt;You don’t need to define types upfront
&lt;/li&gt;
&lt;li&gt;It speeds up development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the trade-off is that errors may only show up when the program runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Go (Static Typing)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In Go, you must define the type explicitly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;var x int = 10&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%2F4hg8qhtfezxxv61nsyku.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%2F4hg8qhtfezxxv61nsyku.png" alt="Go variable Image" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once declared, the type cannot change.&lt;/p&gt;

&lt;p&gt;So this is invalid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x = "hello" // error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called &lt;strong&gt;static typing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It forces structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Types are known before execution
&lt;/li&gt;
&lt;li&gt;Errors are caught early (at compile time)
&lt;/li&gt;
&lt;li&gt;Code is more predictable in large systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Two Ways of Declaring Variables&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Python keeps it simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x = 10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it. One way, one rule.&lt;/p&gt;

&lt;p&gt;Go gives you two main approaches:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Explicit Declaration&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;var x int = 10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;### &lt;strong&gt;Short Declaration (Walrus-style feel)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x := 10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;:=&lt;/code&gt; operator tells Go:&lt;/p&gt;

&lt;p&gt;“Infer the type automatically, but still lock it in permanently.”&lt;/p&gt;

&lt;p&gt;So Go gives you convenience — but never sacrifices structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Concept of “Nothing”&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Another major difference is how both languages handle empty or uninitialized values.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Python: &lt;code&gt;None&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In Python, “no value” is represented explicitly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x = None&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;p&gt;“This variable exists, but it currently holds nothing.”&lt;/p&gt;

&lt;p&gt;It is very explicit and readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Go: Zero Values&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Go does something different.&lt;/p&gt;

&lt;p&gt;If you declare a variable but don’t assign a value, Go automatically gives it a default:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;var x int
&lt;/li&gt;
&lt;li&gt;fmt.Println(x) // 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;None&lt;/code&gt;, Go uses &lt;strong&gt;zero values&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;int → 0
&lt;/li&gt;
&lt;li&gt;string → ""
&lt;/li&gt;
&lt;li&gt;bool → false&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design avoids uninitialized variables entirely.&lt;/p&gt;

&lt;p&gt;While python thinks: “Let me give you freedom and decide later.” Go thinks: “Let me force clarity so you don’t make mistakes later.”&lt;/p&gt;

&lt;p&gt;Even something as simple as variables reveals deep design philosophies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python prioritizes &lt;strong&gt;developer speed and flexibility&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Go prioritizes &lt;strong&gt;safety and predictability&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are correct, just optimized for different worlds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python → scripting, AI, automation, rapid development
&lt;/li&gt;
&lt;li&gt;Go → backend systems, scalability, performance-critical services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading, what do you think about this? Read, like and comment.&lt;/p&gt;

</description>
      <category>python</category>
      <category>go</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
