<?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: Dixon Osure</title>
    <description>The latest articles on DEV Community by Dixon Osure (@dixon-o).</description>
    <link>https://dev.to/dixon-o</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3723034%2F48763c04-d712-4ddb-b25b-fba7feaee8dd.png</url>
      <title>DEV Community: Dixon Osure</title>
      <link>https://dev.to/dixon-o</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dixon-o"/>
    <language>en</language>
    <item>
      <title>Discovering JavaScript Functions Through the Lens of Go</title>
      <dc:creator>Dixon Osure</dc:creator>
      <pubDate>Wed, 13 May 2026 23:30:55 +0000</pubDate>
      <link>https://dev.to/dixon-o/discovering-javascript-functions-through-the-lens-of-go-9ak</link>
      <guid>https://dev.to/dixon-o/discovering-javascript-functions-through-the-lens-of-go-9ak</guid>
      <description>&lt;p&gt;I recently started learning JavaScript, and I didn't come in blind. I had Go in my head — how it structures things, what it cares about, what it refuses to let you do. And honestly, that made learning JS a strange experience. Not hard, just... revealing.&lt;/p&gt;

&lt;p&gt;Every time JS did something different from Go, I found myself asking &lt;em&gt;why&lt;/em&gt;. Why does it work that way? What problem is JS solving that Go solves differently? I started learning two things at once — JavaScript, and a deeper appreciation of choices Go made that I'd taken for granted.&lt;/p&gt;

&lt;p&gt;This is that journey, through functions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Go Wants to Know Everything Upfront. JS Doesn't.
&lt;/h2&gt;

&lt;p&gt;The very first thing I noticed: Go demands you declare your types. Every parameter, every return value — the compiler needs to know.&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="kt"&gt;string&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;"Hello, "&lt;/span&gt; &lt;span class="o"&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;JavaScript has no such requirement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&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;At first I kept thinking — but what &lt;em&gt;type&lt;/em&gt; is &lt;code&gt;name&lt;/code&gt;? What if someone passes a number? And the answer is: JavaScript doesn't stop them. It'll just run, coerce the value, and do its best. &lt;code&gt;greet(42)&lt;/code&gt; gives you &lt;code&gt;"Hello, 42"&lt;/code&gt; without complaint.&lt;/p&gt;

&lt;p&gt;This isn't sloppiness — it's a deliberate tradeoff. JS was built to be flexible and forgiving, especially in a browser environment where you don't control the input. Go was built for systems where you really need to know what's going into each function. Two different problems, two different philosophies.&lt;/p&gt;

&lt;p&gt;The practical consequence: JavaScript errors tend to show up at &lt;em&gt;runtime&lt;/em&gt;, not compile time. You lose the safety net Go's compiler gives you, but you gain a kind of freedom to move fast and figure things out as you go.&lt;/p&gt;




&lt;h2&gt;
  
  
  JS Solves the "Sensible Default" Problem Natively
&lt;/h2&gt;

&lt;p&gt;In Go, there's no such thing as a default parameter value. If you want a fallback, you handle it yourself:&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="kt"&gt;string&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;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"stranger"&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;"Hello, "&lt;/span&gt; &lt;span class="o"&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;The first time I saw JavaScript's version of this, I genuinely paused:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stranger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;         &lt;span class="c1"&gt;// "Hello, stranger"&lt;/span&gt;
&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// "Hello, Alice"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default lives right in the signature. It's part of the function's contract — readable, visible, impossible to miss.&lt;/p&gt;

&lt;p&gt;What I found interesting is that Go's approach isn't just a missing feature — it reflects a philosophy. Go wants function signatures to be unambiguous. A function either gets a value or it doesn't; you deal with it explicitly. JavaScript's approach says: let the function itself handle graceful fallbacks so the caller doesn't have to think about it.&lt;/p&gt;

&lt;p&gt;Neither is wrong. They're just solving the same problem with different priorities.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Each Language Handles Errors — This One Really Made Me Think
&lt;/h2&gt;

&lt;p&gt;This was the biggest conceptual shift for me, and it changed how I understood both languages.&lt;/p&gt;

&lt;p&gt;In Go, errors are just values. A function that can fail returns two things — the result and an error — and you check both:&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;divide&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="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float64&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;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&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="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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every function call that can fail makes that failure visible and forces you to deal with it on the spot. You can't accidentally ignore an error.&lt;/p&gt;

&lt;p&gt;JavaScript takes a completely different approach — errors are &lt;em&gt;thrown&lt;/em&gt; and &lt;em&gt;caught&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cannot divide by zero&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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;What struck me is how this changes the &lt;em&gt;shape&lt;/em&gt; of the code. In Go, error handling is part of the normal flow. In JavaScript, the structure is separated into &lt;code&gt;try&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt; blocks. The function itself returns just one thing; errors travel on a different channel entirely.&lt;/p&gt;

&lt;p&gt;The risk with JavaScript's model is that it's easy to forget the &lt;code&gt;try/catch&lt;/code&gt;. An unhandled thrown error can bubble all the way up and crash your program in a place far removed from where the problem happened. Go makes that much harder to do by accident.&lt;/p&gt;

&lt;p&gt;But I came to see the beauty in JavaScript's model too — especially for deeply nested async code, where passing errors as return values would get messy fast. Exceptions let errors escape cleanly without having to be explicitly threaded through every layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Functions as Values — JS Leans Into This Much Harder Than Go
&lt;/h2&gt;

&lt;p&gt;Both Go and JavaScript treat functions as first-class values. You can assign them to variables, pass them around, return them from other functions. I knew this from 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="n"&gt;double&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&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;n&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But JavaScript doesn't just allow this — the whole language is &lt;em&gt;built&lt;/em&gt; around it. Arrays have built-in methods that take functions as arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&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="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&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="c1"&gt;// [2, 4, 6, 8, 10]&lt;/span&gt;
&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [2, 4]&lt;/span&gt;
&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coming from Go, this was eye-opening. Go has no built-in &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;filter&lt;/code&gt; — you write loops. JavaScript treats these as fundamental operations on collections, built right into the language.&lt;/p&gt;

&lt;p&gt;And those little &lt;code&gt;n =&amp;gt; n * 2&lt;/code&gt; things? Those are &lt;strong&gt;arrow functions&lt;/strong&gt; — JavaScript's shorthand for inline functions. You'll see them everywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// These all do the same thing:&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&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="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&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="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&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="c1"&gt;// parentheses optional for single param&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go has anonymous function literals, but JavaScript went further — arrow functions exist partly for brevity, and partly to solve a specific problem with how &lt;code&gt;this&lt;/code&gt; works (more on that below).&lt;/p&gt;




&lt;h2&gt;
  
  
  Closures Are the Same Idea, But JS Uses Them More Aggressively
&lt;/h2&gt;

&lt;p&gt;Closures — functions that remember the environment they were created in — work the same way in both languages:&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;makeCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;func&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="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;return&lt;/span&gt; &lt;span class="k"&gt;func&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="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;makeCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeCounter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nf"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Identical concept. But JavaScript leans on closures much more heavily than Go does — partly because JS doesn't have Go's explicit struct-based encapsulation, so closures often &lt;em&gt;are&lt;/em&gt; the encapsulation. Private state in JavaScript is frequently just a variable in a closure that nobody outside can touch.&lt;/p&gt;

&lt;p&gt;One thing I learned the hard way: JavaScript also has &lt;code&gt;var&lt;/code&gt; (older style), and &lt;code&gt;var&lt;/code&gt; does &lt;em&gt;not&lt;/em&gt; behave like &lt;code&gt;:=&lt;/code&gt; in Go. &lt;code&gt;var&lt;/code&gt; ignores block scope — a loop variable declared with &lt;code&gt;var&lt;/code&gt; is the same variable across all iterations of the loop, which causes bizarre closure bugs. Always use &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;const&lt;/code&gt;. Treat &lt;code&gt;var&lt;/code&gt; like it doesn't exist.&lt;/p&gt;




&lt;h2&gt;
  
  
  The &lt;code&gt;this&lt;/code&gt; Problem — Nothing Like It in Go
&lt;/h2&gt;

&lt;p&gt;In Go, methods have explicit receivers. You always know exactly what a method is operating on:&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Area&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;float64&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;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pi&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Radius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Radius&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript uses &lt;code&gt;this&lt;/code&gt; instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;area&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radius&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That works fine when you call &lt;code&gt;c.area()&lt;/code&gt; directly. But JavaScript's &lt;code&gt;this&lt;/code&gt; is dynamic — it changes depending on &lt;em&gt;how&lt;/em&gt; the function is called, not where it was defined. The moment you pass a method as a callback, &lt;code&gt;this&lt;/code&gt; can become something unexpected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Circle&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="c1"&gt;// This breaks — `this` is no longer the circle inside the callback&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;area&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// This works — arrow function captures `this` from the surrounding scope&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was the most genuinely confusing thing I encountered coming from Go. In Go, the receiver is explicit and never changes. In JavaScript, &lt;code&gt;this&lt;/code&gt; shifts depending on call context, and you have to know the rules to avoid getting burned.&lt;/p&gt;

&lt;p&gt;Arrow functions were invented partly to solve this — they don't have their own &lt;code&gt;this&lt;/code&gt;, they inherit it from wherever they were created. That's why you'll see arrow functions used as callbacks so often in JavaScript codebases.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Go Taught Me About JavaScript
&lt;/h2&gt;

&lt;p&gt;Going through all this, something clicked for me: Go and JavaScript aren't just different syntax for the same ideas. They reflect genuinely different beliefs about what a programming language should optimize for.&lt;/p&gt;

&lt;p&gt;Go optimizes for &lt;em&gt;clarity and correctness&lt;/em&gt; — types, explicit errors, predictable receivers. JavaScript optimizes for &lt;em&gt;flexibility and expressiveness&lt;/em&gt; — dynamic types, exceptions that escape cleanly, &lt;code&gt;this&lt;/code&gt; that adapts to context, functions that compose in powerful ways.&lt;/p&gt;

&lt;p&gt;Neither got it wrong. They made different bets.&lt;/p&gt;

&lt;p&gt;Knowing Go made me a more thoughtful JavaScript learner, because I kept asking &lt;em&gt;why&lt;/em&gt; instead of just accepting the syntax. And every time I found an answer, I understood both languages a little better.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions" rel="noopener noreferrer"&gt;MDN – Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://javascript.info" rel="noopener noreferrer"&gt;javascript.info&lt;/a&gt; — the best free JS learning resource I've found&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions" rel="noopener noreferrer"&gt;MDN – Arrow Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/getify/You-Dont-Know-JS" rel="noopener noreferrer"&gt;You Don't Know JS&lt;/a&gt; — for when you want to go deep on how JS actually works
Good luck. JS is a rabbit hole, but it's a fascinating one. 🙂&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Mastering Go Testing: From Basics to Subtests in 3 Minutes</title>
      <dc:creator>Dixon Osure</dc:creator>
      <pubDate>Wed, 11 Feb 2026 20:54:43 +0000</pubDate>
      <link>https://dev.to/dixon-o/mastering-go-testing-from-basics-to-subtests-in-3-minutes-1lni</link>
      <guid>https://dev.to/dixon-o/mastering-go-testing-from-basics-to-subtests-in-3-minutes-1lni</guid>
      <description>&lt;p&gt;Testing in Go is a breath of fresh air. There is no need to learn complicated frameworks or configure assertion libraries. The standard library is all you need.&lt;/p&gt;

&lt;p&gt;In this 3-minute guide, we'll help you upgrade your testing skills from "hello world" to professional grade table-driven tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 1: The Basic Test&lt;/strong&gt;&lt;br&gt;
In Go, tests live in files ending with &lt;code&gt;_test.go&lt;/code&gt;. A test is just a function that starts with &lt;code&gt;Test&lt;/code&gt; and takes a &lt;code&gt;*testing.T&lt;/code&gt;.&lt;br&gt;
Here is a simple test for an &lt;code&gt;Add&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5

    if result != expected {
        t.Errorf("Add(2, 3) = %d; want %d", result, expected)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't use assertions like &lt;code&gt;assert.Equal&lt;/code&gt;. We just use &lt;code&gt;if&lt;/code&gt; statements and &lt;code&gt;t.Errorf&lt;/code&gt; to report failures. Simple!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 2: Table-Driven Tests&lt;/strong&gt;&lt;br&gt;
What if we want to test &lt;code&gt;Add(0, 0)&lt;/code&gt;, &lt;code&gt;Add(-1, 1)&lt;/code&gt;, and &lt;code&gt;Add(100, 200)&lt;/code&gt;? Copy-pasting the test above is tedious and error-prone.&lt;br&gt;
This is where &lt;strong&gt;Table-Driven Tests&lt;/strong&gt; come in. This is the idiomatic way to write tests in Go. We define our test cases in a slice of structs (the "table"), then simply loop over them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TestAdd(t *testing.T) {
    tests := []struct {
        a, b     int
        expected int
    }{
        {2, 3, 5},
        {0, 0, 0},
        {-1, 1, 0},
    }

    for _, tt := range tests {
        result := Add(tt.a, tt.b)
        if result != tt.expected {
            t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, adding a new test case is just adding one line to the slice. Clean, right?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 3: Subtests with&lt;/strong&gt; &lt;code&gt;t.Run&lt;/code&gt;&lt;br&gt;
The table-driven approach is great, but what if one case fails? It can be difficult to identify which case failed out of a sea of log messages. What if we want to run just one particular case?&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Subtests&lt;/strong&gt; come in. We'll use &lt;code&gt;t.Run&lt;/code&gt; to define a separate test function for each case:&lt;br&gt;
First, let's add a name field to our struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TestAdd(t *testing.T) {
    tests := []struct {
        name     string // New!
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"zeros", 0, 0, 0},
        {"negative", -1, 1, 0},
    }

    for _, tt := range tests {
        // t.Run creates a subtest
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("got %d, want %d", result, tt.expected)
            }
        })
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why is this better?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Better Output/Easier Debugging&lt;/strong&gt;: The failed test has a clear name: &lt;em&gt;TestAdd/positive_numbers&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granular Control&lt;/strong&gt;: You can run individual subtests from the command line.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go test -run TestAdd/zeros

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt;: And you can even run subtests in parallel with &lt;code&gt;t.Parallel()&lt;/code&gt; inside a loop!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br&gt;
We started with a simple function and ended up with a scalable, professional testing pattern with only a few lines of code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basics&lt;/strong&gt;: Use &lt;code&gt;t.Errorf&lt;/code&gt; to fail tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table-Driven&lt;/strong&gt;: Use &lt;code&gt;[]struct&lt;/code&gt; to organize data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subtests&lt;/strong&gt;: Use &lt;code&gt;t.Run&lt;/code&gt; for better reporting and control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy testing! &lt;/p&gt;

</description>
      <category>go</category>
      <category>testing</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
