<?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: ik_5</title>
    <description>The latest articles on DEV Community by ik_5 (@ik5).</description>
    <link>https://dev.to/ik5</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%2F274406%2F443d0fe1-bed4-405c-a94b-054e0b799d0d.png</url>
      <title>DEV Community: ik_5</title>
      <link>https://dev.to/ik5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ik5"/>
    <language>en</language>
    <item>
      <title>10 Things I Learned from Vibe Coding (or: How I Let an AI Agent Write My Audio Library)</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Fri, 16 Jan 2026 09:40:24 +0000</pubDate>
      <link>https://dev.to/ik5/10-things-i-learned-from-vibe-coding-or-how-i-let-an-ai-agent-write-my-audio-library-2940</link>
      <guid>https://dev.to/ik5/10-things-i-learned-from-vibe-coding-or-how-i-let-an-ai-agent-write-my-audio-library-2940</guid>
      <description>&lt;h1&gt;
  
  
  10 Things I Learned from Vibe Coding
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — The finished result is here: &lt;a href="https://github.com/ik5/audpbx" rel="noopener noreferrer"&gt;https://github.com/ik5/audpbx&lt;/a&gt;.&lt;br&gt;
I hope it helps someone else too.&lt;/p&gt;

&lt;p&gt;I recently finished a small side project and decided to handle one required feature differently than usual.&lt;/p&gt;

&lt;p&gt;The task was simple on the surface: accept an uploaded audio file in almost any format, then resample and convert it to PCM 16-bit signed, mono, 8 kHz WAV.&lt;/p&gt;

&lt;p&gt;In the telecom world this ultra-low-spec format is still the standard you must support — most class-4 and class-5 PBXs expect (or silently convert everything to) exactly G.711-compatible PCM: 8000 Hz, mono, 16-bit linear. Anything else usually gets transcoded anyway, or the call just fails.&lt;/p&gt;

&lt;p&gt;Normally I would just shell out to &lt;code&gt;ffmpeg&lt;/code&gt; and be done with it. This time I wanted &lt;strong&gt;pure native Go code&lt;/strong&gt; — no external binaries.&lt;/p&gt;

&lt;p&gt;A few years ago I wrote a tiny Go package that took raw PCM samples and wrapped them into a .wav file. That was it — no decoding, no resampling, no format conversion. When I tried to extend the idea to real resampling and multi-format input I quickly ran into trouble.&lt;/p&gt;

&lt;p&gt;After a week of one-hour evening sessions the code was still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;crashing on several inputs (bad buffer logic)&lt;/li&gt;
&lt;li&gt;producing noticeably worse audio quality than ffmpeg or Audacity (naive linear resampling)&lt;/li&gt;
&lt;li&gt;supporting only PCM .wav files (no RIFF metadata handling, no other containers)&lt;/li&gt;
&lt;li&gt;taking forever to make progress&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point I decided to see whether free non-agent AIs could help. I tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🟡 Claude&lt;/li&gt;
&lt;li&gt;🔵 Grok&lt;/li&gt;
&lt;li&gt;🟢 GitHub Copilot&lt;/li&gt;
&lt;li&gt;🟣 ChatGPT&lt;/li&gt;
&lt;li&gt;🟠 Gemini&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Copilot&lt;/strong&gt; gave by far the most useful starting point. It produced code that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read and write RIFF WAVE files&lt;/li&gt;
&lt;li&gt;decode Ogg Vorbis&lt;/li&gt;
&lt;li&gt;decode MP3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…all attempting to share roughly the same interface.&lt;/p&gt;

&lt;p&gt;Still — lots of crashes, memory corruption, infinite loops, bad buffer management, and the interface was mostly ignored in practice.&lt;/p&gt;

&lt;p&gt;I cleaned it up by hand until I reached this &lt;a href="https://github.com/ik5/audpbx/commit/235c09c511ac03492f70fb315c04c8188e512ed8" rel="noopener noreferrer"&gt;early commit&lt;/a&gt; — still very fragile, but at least the abstractions were starting to hold.&lt;/p&gt;

&lt;p&gt;On January 9th I switched to &lt;strong&gt;Claude with agent/computer-use capabilities&lt;/strong&gt; — and that made a huge difference. The rest of this post is what I learned during that second, agent-driven phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Be clear
&lt;/h3&gt;

&lt;p&gt;Modern AIs — even agents — almost never tell you “this design is wrong” or suggest a completely different approach unless you explicitly ask them to critique it.&lt;/p&gt;

&lt;p&gt;If you don’t already have a mental model of what you want (boundaries, failure modes, safety, layering), the AI will happily generate code that compiles but misses the point.&lt;/p&gt;

&lt;p&gt;Solution: start with tiny, very concrete tasks.&lt;br&gt;
Example: instead of “fix this crash”, I started asking “look at this backtrace — why do you think it crashed, and what would you change to prevent it?”.&lt;/p&gt;

&lt;p&gt;Very often the first answer was wrong (e.g. “the buffer isn’t initialized” when the real issue was missing bounds checks). I had to stop the agent many times because it was heading in a useless direction.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Always check what was offered
&lt;/h3&gt;

&lt;p&gt;Claude frequently wrote outdated or non-idiomatic Go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;interface{}&lt;/code&gt; instead of &lt;code&gt;any&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;old-style &lt;code&gt;for i := 0; i &amp;lt; n; i++&lt;/code&gt; instead of &lt;code&gt;for i := range n&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Python-like patterns shoehorned into Go&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I gradually pushed back toward better patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;package-level &lt;code&gt;var ErrXXX = errors.New("…")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;avoiding &lt;code&gt;fmt.Errorf&lt;/code&gt; when a static error value carries enough meaning (still work in progress)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good error handling in Go makes flow readability much easier later. Not every &lt;code&gt;io.EOF&lt;/code&gt; is a failure — sometimes it’s the expected way to exit a loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Test the implemented code
&lt;/h3&gt;

&lt;p&gt;The agent generated plenty of unit tests — which is nice.&lt;br&gt;
But passing unit tests only proves the cases you thought to check. It says almost nothing about real-world files or unintended usage.&lt;/p&gt;

&lt;p&gt;That’s why I created the &lt;code&gt;examples/resampler&lt;/code&gt; program early on.&lt;br&gt;
It acts as an integration test: feed it dozens of different audio formats → run them through the whole package → produce PCM 16-bit mono 8 kHz WAV → compare with ffmpeg/Audacity output when in doubt.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Don’t ask the AI to do things you already understand
&lt;/h3&gt;

&lt;p&gt;AI agents will cheerfully agree with you after you point out an obvious mistake (“You’re right, I should have…”).&lt;br&gt;
If &lt;strong&gt;you&lt;/strong&gt; already know the safer/clearer/faster way — just write it.&lt;/p&gt;

&lt;p&gt;I fixed &amp;gt;90% of the memory leaks, slice shadowing bugs, uninitialized values, and off-by-one errors myself — usually faster than waiting for another iteration.&lt;br&gt;
Only a few times was I actually wrong, and even then the agent’s version was usually over-complicated.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Write code as if a human will have to maintain it later
&lt;/h3&gt;

&lt;p&gt;Avoid “write-only” code — even when the first draft comes from an AI.&lt;br&gt;
KISS still applies. Clear names &amp;gt; clever tricks.&lt;br&gt;
Future readers (including yourself in six months) will thank you.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Demand proper unit tests and benchmarks — with modern Go idioms
&lt;/h3&gt;

&lt;p&gt;Early on the agent wrote:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;benchmarks named &lt;code&gt;TestSomething&lt;/code&gt; instead of &lt;code&gt;BenchmarkSomething&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;unit tests without the &lt;code&gt;Test&lt;/code&gt; prefix&lt;/li&gt;
&lt;li&gt;classic &lt;code&gt;for i := 0; i &amp;lt; b.N; i++&lt;/code&gt; instead of &lt;code&gt;for b.Loop() { … }&lt;/code&gt; (Go 1.24+)&lt;/li&gt;
&lt;li&gt;no &lt;code&gt;t.Parallel()&lt;/code&gt; even when it made sense&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had to keep correcting it until the generated test code followed current Go conventions.&lt;/p&gt;

&lt;p&gt;Later I started asking for tests on one specific function/file at a time with specific conventions — much better results.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Documentation inside the code
&lt;/h3&gt;

&lt;p&gt;Don’t waste comments on the obvious.&lt;br&gt;
&lt;strong&gt;Do&lt;/strong&gt; explain non-obvious decisions and magic numbers.&lt;/p&gt;

&lt;p&gt;Example: why &lt;code&gt;32768.0&lt;/code&gt;?&lt;br&gt;
If you know 16-bit signed integer range it’s obvious — but most readers won’t instantly see it. A one-line comment saves confusion later.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Write examples
&lt;/h3&gt;

&lt;p&gt;My original goal was always to expose a very simple &lt;strong&gt;high-level API&lt;/strong&gt; — ideally one or two friendly functions that “just work” for the most common case (convert anything → 8 kHz mono PCM16 WAV).&lt;/p&gt;

&lt;p&gt;At the same time I wanted clean low-level building blocks underneath so the package could be reusable in other contexts.&lt;/p&gt;

&lt;p&gt;When I asked the agent to write a collection of usage examples — not just the happy path, but showing different ways to combine the low-level pieces — I was surprised.&lt;/p&gt;

&lt;p&gt;The low-level API turned out to be much more powerful than I had realized.&lt;br&gt;
There were capabilities and combinations I had never thought about and never intended to build — yet they emerged naturally from the design and suddenly looked very useful.&lt;/p&gt;

&lt;p&gt;Seeing those examples helped me understand (and appreciate) my own library much better.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Good documentation, bad documentation, and outright lies
&lt;/h3&gt;

&lt;p&gt;My native language isn’t English, and writing clear technical docs doesn’t come naturally to me.&lt;/p&gt;

&lt;p&gt;The agent produced documentation that was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;grammatically correct&lt;/li&gt;
&lt;li&gt;properly structured&lt;/li&gt;
&lt;li&gt;better spelled and phrased than I would usually manage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also learned Go doc tricks I hadn’t known before — like using heading markers to create sections in godoc.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. “Code Monkey”
&lt;/h3&gt;

&lt;p&gt;The classic definition still fits best:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A pejorative term for programmers employed to write simple or repetitive code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s basically what a strong coding agent is — an extremely fast, very knowledgeable &lt;strong&gt;code monkey&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It can produce huge amounts of code quickly.&lt;br&gt;
It cannot take architectural responsibility.&lt;br&gt;
It won’t warn you about future maintenance pain unless you force the topic.&lt;br&gt;
If you don’t steer tightly, you get working-but-awful code.&lt;/p&gt;

&lt;p&gt;Use it like a very junior-but-fast pair programmer: you supply the thinking and the taste, it supplies the typing.&lt;/p&gt;

&lt;p&gt;And just for fun — here's the song that gave the section its name:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=qYodWEKCuGg" rel="noopener noreferrer"&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%2Fr58ge7wq30yapu2f2odw.jpg" alt="Code Monkey loves you" width="130" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Code Monkey — the unofficial anthem of every developer who’s ever pair-programmed with an AI 😄)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Happy coding — and don’t trust the robot too much. 😉&lt;/p&gt;

&lt;p&gt;Have you had similar (good or terrible) experiences vibe-coding with AI agents?&lt;br&gt;
Drop a comment — I’d love to hear your war stories!&lt;/p&gt;

</description>
      <category>go</category>
      <category>vibecoding</category>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>The Perils of Over-Engineering in Technology</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Sun, 20 Jul 2025 05:54:20 +0000</pubDate>
      <link>https://dev.to/ik5/the-perils-of-over-engineering-in-technology-23ad</link>
      <guid>https://dev.to/ik5/the-perils-of-over-engineering-in-technology-23ad</guid>
      <description>&lt;p&gt;In today’s world, technology often gravitates toward unnecessary complexity, with bloated software and intricate systems like AI dominating development. I believe we should prioritize simpler methods that empower humans, avoiding overcomplication that can lead to inefficiency, loss of control, and even economic disruption.&lt;/p&gt;

&lt;p&gt;Most of us view technology as computers or electronics, but even a chair, glasses, and the stairs we climb are technologies that aim to address human needs.&lt;/p&gt;

&lt;p&gt;Several years ago, during a hiking trip, I had a fascinating conversation with an engineer about the &lt;a href="https://en.wikipedia.org/wiki/Fax" rel="noopener noreferrer"&gt;fax (facsimile)&lt;/a&gt;. While fax machines are often mocked, their underlying technology offers a powerful lesson in designing simple, human-centered tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fax Machine: A Model of Simplicity
&lt;/h2&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%2Fu0f1iu9fp7hpz2s7w9vq.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%2Fu0f1iu9fp7hpz2s7w9vq.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Brief History
&lt;/h3&gt;

&lt;p&gt;In 1846, Alexander Bain invented a chemical device that reproduced graphical shapes via the &lt;a href="https://en.wikipedia.org/wiki/Telegraphy" rel="noopener noreferrer"&gt;telegraph&lt;/a&gt;, laying the groundwork for fax technology. By 1865, after improvements by other inventors, the first commercial telefax service connected Paris and Lyon. Nearly a century later, in 1964, Xerox introduced the modern fax machine—a device many of us love to hate, especially if you’re old enough to recall its quirks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Fax Machine Matters
&lt;/h3&gt;

&lt;p&gt;The fax machine, in both analog and digital forms, embodies simplicity. It scans a page, attaches metadata, and transmits it using basic signals like radio waves or sound to produce an identical copy elsewhere. This process doesn’t require complex systems like AI, relying instead on straightforward electrical wiring or software.&lt;/p&gt;

&lt;p&gt;Digital fax machines use a &lt;a href="https://en.wikipedia.org/wiki/Digital_signal_processor" rel="noopener noreferrer"&gt;Digital Signal Processor (DSP)&lt;/a&gt;, a microprocessor that converts analog signals to digital and vice versa. Using simple copper wires and telephony filters, it translates human-audible sounds into metadata and shapes. Software-based solutions, like &lt;a href="https://www.soft-switch.org/" rel="noopener noreferrer"&gt;SpanDSP&lt;/a&gt; and protocols like &lt;a href="https://en.wikipedia.org/wiki/T.38" rel="noopener noreferrer"&gt;T.38&lt;/a&gt; for Fax over IP (FoIP), further streamline this process.&lt;/p&gt;

&lt;p&gt;Consider this: with basic electrical or audio signals, we can achieve reliable results without overthinking the design. Once fax machines became commercially available, anyone who could use a printer or dial a phone could operate one—provided the machines and supplies were affordable—hence it’s an intuitive system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Consequences of Overcomplication
&lt;/h2&gt;

&lt;p&gt;I’m old enough to remember floppy disks, which stored multiple applications in minimal space. These programs used little RAM yet delivered impressive functionality. Even complex software managed with multiple disks, swapping data as needed, without demanding excessive resources other than storage space for its resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.collegesidekick.com/study-guides/santaana-informationsystems/tour-of-a-pc" rel="noopener noreferrer"&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%2F3vqodjaik90mbhk0j9ly.jpg" alt="Floppy disks" width="350" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These resource-efficient designs highlight the drawbacks of today’s complex systems, which carry serious consequences.&lt;/p&gt;

&lt;p&gt;Modern technology often abandons simplicity, with serious consequences. For example, containers like Docker or Podman require complex network stacks, registries, proxies, gateways, and often privilege escalation. A simple &lt;code&gt;.tar.gz&lt;/code&gt; file with statically compiled binaries or a &lt;code&gt;.rpm&lt;/code&gt;/&lt;code&gt;.deb&lt;/code&gt; package with clear dependencies could suffice. Ecosystems like Kubernetes amplify this complexity, increasing development time, maintenance costs, and error risks, while distancing users from intuitive control. Developers often need to manage multiple database or server instances or build custom dependency instructions. This can slow execution or create security risks, such as running containers as ‘root’ or ‘Administrator’ when a ‘nobody’ user with &lt;a href="https://wiki.archlinux.org/title/Capabilities" rel="noopener noreferrer"&gt;Linux capabilities&lt;/a&gt; would have sufficed.&lt;/p&gt;

&lt;p&gt;Similarly, AI is often treated as the ultimate tool, overshadowing simpler alternatives. Its complexity—while powerful—shouldn’t dominate every solution. The “all-or-nothing” mindset, where AI is seen as the only path forward, risks sidelining human labor entirely. This could have dire economic consequences: if AI automates most work, people may lose access to jobs and income, potentially rendering currency obsolete as economic power shifts to machines. Instead of complementing human efforts, AI becomes a replacement, eroding the human-centered purpose of technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Call for Simpler, Human-Centered Design
&lt;/h2&gt;

&lt;p&gt;Overcomplication doesn’t just make technology harder to use; it risks inefficiency, user alienation, and economic instability. Just because we have abundant computing resources doesn’t mean we should bloat software or rely solely on AI. Technology should empower humans, not overwhelm them or render their contributions obsolete.&lt;/p&gt;

&lt;p&gt;The fax machine reminds us that simplicity can be powerful. By prioritizing straightforward, human-centered design, we can create tools that enhance our lives, preserve human agency, and maintain economic stability. Let’s think simpler, ensuring technology serves people first.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>simplicity</category>
      <category>technology</category>
    </item>
    <item>
      <title>What I've Learned About My Editing Skills</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Tue, 10 Dec 2024 17:19:32 +0000</pubDate>
      <link>https://dev.to/ik5/what-ive-learned-about-my-editing-skills-22oc</link>
      <guid>https://dev.to/ik5/what-ive-learned-about-my-editing-skills-22oc</guid>
      <description>&lt;p&gt;I experimented with an impressive text editor called &lt;a href="https://helix-editor.com/" rel="noopener noreferrer"&gt;Helix&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I believe the work on this editor is fantastic, and I love its feature set.&lt;/p&gt;

&lt;p&gt;However, I have one “small” issue with it — it operates very differently from (neo)vim &lt;a href="https://github.com/helix-editor/helix/wiki/Migrating-from-Vim" rel="noopener noreferrer"&gt;key bindings&lt;/a&gt;.&lt;br&gt;
I tried to reconfigure it to be as close to vim as possible, but I couldn't achieve 100% vim-like key bindings.&lt;/p&gt;

&lt;p&gt;If you think I'm criticizing the editor, think again. It's awesome, and you should give it a try (at least for a month).&lt;/p&gt;

&lt;p&gt;This post is about what I learned about my skills while trying the editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some History
&lt;/h2&gt;

&lt;p&gt;In the year 2000, I started using Unix systems (AIX, Solaris, and FreeBSD) as a user for specific services, and I liked them much more compared to Windows. By the end of the year, someone offered me to try something new called Linux.&lt;/p&gt;

&lt;p&gt;He gave me a CD named Mandrake Linux, and when I booted my machine, I saw a nice GUI installation screen.&lt;/p&gt;

&lt;p&gt;Back then, I was a Windows-based software developer (Delphi, VB(A), and some basic yucky C++), so it was very different for me.&lt;/p&gt;

&lt;p&gt;A friend showed me a cool editor named &lt;a href="https://www.vim.org/" rel="noopener noreferrer"&gt;vim&lt;/a&gt; and some tricks he did with text on it.&lt;/p&gt;

&lt;p&gt;In 2003, Microsoft decided to obsolete a library that a startup I worked for used, and I decided to move from the MS world to Linux.&lt;br&gt;
I think it was the best decision of my life.&lt;/p&gt;

&lt;p&gt;I wanted to understand how to do the cool stuff I saw with vim, so I wrote a guide on how to do some basic work in VIM (in my native language) to help me learn vim.&lt;/p&gt;

&lt;h2&gt;
  
  
  The VIM Language
&lt;/h2&gt;

&lt;p&gt;One big misunderstanding about vim for non-vim users is the lack of randomness when using keys.&lt;/p&gt;

&lt;p&gt;You have a count of something, an action to do, and a movement of some kind.&lt;/p&gt;

&lt;p&gt;What does it mean?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;3yw&lt;/code&gt; means to copy 3 boundaries of words (including spaces) forward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;3ye&lt;/code&gt; means to copy 3 boundaries of words (not including the last space) forward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;3yb&lt;/code&gt; means to copy 3 boundaries of words (including the first space) backward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;3dw&lt;/code&gt; means to delete 3 boundaries of words (including spaces) forward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;3cw&lt;/code&gt; means to change 3 boundaries of words (including spaces) forward.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Can you see a pattern?&lt;br&gt;
That's the vim language, but it's more than that. You can do it on paragraphs, parameters, and more.&lt;/p&gt;

&lt;p&gt;What does “more” mean? You have something called &lt;a href="https://vimdoc.sourceforge.net/htmldoc/motion.html#object-motions" rel="noopener noreferrer"&gt;“text objects”&lt;/a&gt; that you can define, for example, “class,” "method," etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Skills, Damn Skills, and Muscle Memory
&lt;/h2&gt;

&lt;p&gt;One of the issues I have with vim (I actually use &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;neovim&lt;/a&gt; for several years now) is that I do not remember most of the language.&lt;/p&gt;

&lt;p&gt;Even while writing this blog post, I needed to test what I've written regarding the vim language because I do not remember it by heart.&lt;/p&gt;

&lt;p&gt;So, how do I use vim? &lt;a href="https://en.wikipedia.org/wiki/Muscle_memory" rel="noopener noreferrer"&gt;Muscle memory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I just do it, and it works for me for some strange reason.&lt;/p&gt;

&lt;p&gt;And that's my issue with the Helix editor — it uses similar but different key bindings for doing the same things.&lt;br&gt;
While I can find a way to re-learn it, I still need vim when I'm inside servers (for example).&lt;/p&gt;

&lt;p&gt;But I can't figure out how to have two types of muscle memory based on the application I'm using. It's the same for me when I'm writing software.&lt;br&gt;
I'm polyglot and use around 3 programming languages at the moment, and in each language, I sometimes write the wrong syntax at the start.&lt;br&gt;
Also, it happens to me when I'm using different human languages that are close to each other (e.g., Spanish, Portuguese, and Italian) while my native language is not Latin-based.&lt;/p&gt;

&lt;p&gt;But why the vim way and not something word processing-like (nano, pico, emacs, VSc, etc.)?&lt;/p&gt;

&lt;p&gt;First, I live in the terminal. I love it, and for most stuff, it is enough for me, so Zed or VSc are not that.&lt;br&gt;
Second, I find myself much more productive while using the vim language over word processing shortcuts.&lt;/p&gt;

&lt;p&gt;So now I'm in a deadlock situation where an amazing text editor is unusable for me simply because it offers a means that makes me work well but with a different language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Do I Go From Here?
&lt;/h2&gt;

&lt;p&gt;Maybe I'll try &lt;a href="https://github.com/usagi-flow/evil-helix" rel="noopener noreferrer"&gt;Evil Helix&lt;/a&gt;: "A soft fork of Helix which introduces Vim keybindings and more."&lt;/p&gt;

&lt;p&gt;But I think I wil keep myself at the moment in (neo)vim, until my skills becomes better.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>helix</category>
      <category>neovim</category>
      <category>editors</category>
    </item>
    <item>
      <title>You (probably) do not understand UDP</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Sat, 03 Aug 2024 11:18:51 +0000</pubDate>
      <link>https://dev.to/ik5/you-probably-do-not-understand-udp-jhf</link>
      <guid>https://dev.to/ik5/you-probably-do-not-understand-udp-jhf</guid>
      <description>&lt;p&gt;On my day to day work, I find that few types of IT equipment cannot properly support anything but TCP transport layers, even when their specification explains that it does.&lt;/p&gt;

&lt;p&gt;I also read rants such as &lt;a href="https://quic.video/blog/never-use-datagrams/" rel="noopener noreferrer"&gt;this&lt;/a&gt; regarding implementing something in UDP where TCP would have been better.&lt;/p&gt;

&lt;p&gt;So this post is about giving a small idea of what is UDP, and I hope it will shed more light on what is missing in the understanding of the transport protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;You and I (probably) do not (fully) understand UDP.&lt;/p&gt;

&lt;p&gt;TCP and UDP have different usages and should be compared based on the &lt;strong&gt;end application&lt;/strong&gt; needs rather than "you do not have a 3-way handshake so it sucks" like rants.&lt;/p&gt;

&lt;p&gt;Most of the time, TCP does not require you to do anything regarding transport instructions besides the port number regarding L7 (there are very few exceptions to this rule that this post never touches and blatantly ignores).&lt;/p&gt;

&lt;p&gt;UDP is a lightweight transport protocol that forces handling needed transport logic at the application layer (L7), while TCP does most of it on its own almost auto-magically (when you just handle L7) for you.&lt;br&gt;
This post tries to provide examples of such usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network story
&lt;/h2&gt;

&lt;p&gt;Let's talk about networking (almost) without talking about the transport layer.&lt;/p&gt;

&lt;p&gt;There is a need for some sort of way to deliver data (e.g., &lt;a href="https://en.wikipedia.org/wiki/Registered_jack" rel="noopener noreferrer"&gt;RJ&lt;/a&gt;45-based Ethernet cable).&lt;/p&gt;

&lt;p&gt;Then there are some physical hardware (e.g., &lt;a href="https://en.wikipedia.org/wiki/Wi-Fi" rel="noopener noreferrer"&gt;Wifi&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Ethernet" rel="noopener noreferrer"&gt;Ethernet&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Token_Ring" rel="noopener noreferrer"&gt;token-ring&lt;/a&gt; [not really], &lt;a href="https://en.wikipedia.org/wiki/Bluetooth" rel="noopener noreferrer"&gt;Bluetooth&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Mobile_broadband_modem" rel="noopener noreferrer"&gt;Cellular&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Modem" rel="noopener noreferrer"&gt;modem&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/FXO_and_FXS" rel="noopener noreferrer"&gt;FXO/FXS&lt;/a&gt; modem, etc.&lt;br&gt;
A.K.A. "Physical layer" or Layer #1.&lt;/p&gt;

&lt;p&gt;Then there is some sort of &lt;a href="https://en.wikipedia.org/wiki/Firmware" rel="noopener noreferrer"&gt;firmware&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Device_driver" rel="noopener noreferrer"&gt;device driver&lt;/a&gt; at the software level that can read stuff on operating systems such as Windows/Linux/MacOS/... and provides a low-level API for the OS to do stuff that makes it unified for &lt;a href="https://en.wikipedia.org/wiki/User_space_and_kernel_space" rel="noopener noreferrer"&gt;user-space&lt;/a&gt; stuff.&lt;/p&gt;

&lt;p&gt;From Layer 2 up to and including Layer 7, everything is software-based.&lt;/p&gt;

&lt;p&gt;Each layer is encapsulated backward than what the numerical layer should be, so application level (L7) data is encapsulated first, then L6..L5 it goes down to Layer 2, and then hardware layer to pass data around in a &lt;a href="https://en.wikipedia.org/wiki/Endianness" rel="noopener noreferrer"&gt;Big-Endian&lt;/a&gt; way.&lt;/p&gt;

&lt;p&gt;The order of each "capsule" exists, so the first thing that gets accessed will get the data it knows how to parse, leaving everything else to the next level in the chain to handle until it's our program that handles an application layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let us network a bit
&lt;/h3&gt;

&lt;p&gt;To figure out what the size of encapsulation is, there is a measuring unit named &lt;a href="https://en.wikipedia.org/wiki/Maximum_transmission_unit" rel="noopener noreferrer"&gt;MTU (Max Transmission Unit)&lt;/a&gt;—the biggest payload size that can send/receive (on normal networking, the value can be only up to 1500 bytes) with the entire encapsulation of everything.&lt;/p&gt;

&lt;p&gt;If our payload is bigger than the MTU size, there is a requirement to fragment the payload into smaller chunks and send each of them on their own.&lt;/p&gt;

&lt;p&gt;The part that might do that is either our software or transport layer depends first on our application and only then on the transport layer (when supported by it).&lt;/p&gt;

&lt;p&gt;The application can decide to perform fragmentation of the payload without considering the transport layer. HTTP has a nice usage for L7 fragmentation using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests" rel="noopener noreferrer"&gt;HTTP range requests&lt;/a&gt;, for example.&lt;/p&gt;

&lt;h4&gt;
  
  
  What did you say?
&lt;/h4&gt;

&lt;p&gt;Let's take a hardware tool named "&lt;a href="https://en.wikipedia.org/wiki/Ethernet_hub" rel="noopener noreferrer"&gt;hub&lt;/a&gt;".&lt;br&gt;
That tool is an array of RJ45 Ethernet cards that are only separated by actual position, but all data is available at the same time by all used cards.&lt;/p&gt;

&lt;p&gt;On that hub, let's connect a single point (that is, a machine = computer).&lt;/p&gt;

&lt;p&gt;Let's ask using the "&lt;a href="https://en.wikipedia.org/wiki/Address_Resolution_Protocol" rel="noopener noreferrer"&gt;arp&lt;/a&gt;" protocol, who knows some sort of hardware address, to return its IP address.&lt;br&gt;
While doing that, let's do some &lt;a href="https://en.wikipedia.org/wiki/Tcpdump" rel="noopener noreferrer"&gt;tcpdump&lt;/a&gt;ing magic and &lt;a href="https://en.wikipedia.org/wiki/Packet_analyzer" rel="noopener noreferrer"&gt;sniff&lt;/a&gt; our requests.&lt;/p&gt;

&lt;p&gt;We will find out very soon that now and then we cannot see our request after it exists from our machine.&lt;/p&gt;

&lt;p&gt;Even if we add another machine and sniff the traffic using the new machine, the result will be the same.&lt;/p&gt;

&lt;p&gt;Sometimes we are losing packets!&lt;br&gt;
Why? &lt;a href="https://en.wikipedia.org/wiki/Gremlin" rel="noopener noreferrer"&gt;Gremlins&lt;/a&gt; love bits on the net, that's why!&lt;/p&gt;

&lt;p&gt;So some transport layers also handle the loss of data.&lt;/p&gt;

&lt;p&gt;But if there are a lot of requests (or heavy traffic, or slower processing, etc..), sometimes the order of the packets does not go by the order the L7 wanted them to go, so packet #10 arrives before packet #4, for example.&lt;/p&gt;

&lt;p&gt;So some transport layers also handle the assembling of the packets based on the order number inside that layer.&lt;/p&gt;

&lt;p&gt;And by talking about "some", it is usually about TCP (in our case).&lt;/p&gt;

&lt;h2&gt;
  
  
  TCP (and) UDP
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TCP
&lt;/h3&gt;

&lt;p&gt;TCP is a complex transport protocol that does so many things for you (almost in an automagically manner), such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a communication path to the endpoint, preparing it to accept your data (&lt;a href="https://en.wikipedia.org/wiki/Handshake_(computing)#TCP_three-way_handshake" rel="noopener noreferrer"&gt;3-way handshake&lt;/a&gt;) and also alert that the entire payload was sent.&lt;/li&gt;
&lt;li&gt;Understand for you how to fragment a payload and number it.&lt;/li&gt;
&lt;li&gt;Understand the timeout and missing fragment, and send the missing fragment again (retransmission).&lt;/li&gt;
&lt;li&gt;Handle &lt;a href="https://en.wikipedia.org/wiki/TCP_congestion_control" rel="noopener noreferrer"&gt;congestion&lt;/a&gt; of the network by using a sending window handler.&lt;/li&gt;
&lt;li&gt;Can send "ping" like to &lt;a href="https://en.wikipedia.org/wiki/Keepalive#TCP_keepalive" rel="noopener noreferrer"&gt;keep alive&lt;/a&gt; the path and endpoint of the connection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sounds amazing, but it comes with a few costs, such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Heavy traffic (e.g., 3-way handshake, retransmission of fragments, and keep-alive).&lt;/li&gt;
&lt;li&gt;If you have network issues, you'll lose your connection to the endpoint when timers are timed out.&lt;/li&gt;
&lt;li&gt;Big header to include many features = smaller payload (MTU).&lt;/li&gt;
&lt;li&gt;The speed of data is much slower than UDP (for example) due to so many things that are going on that need to be verified.&lt;/li&gt;
&lt;li&gt;Your TCP stack implementation handles for you the congestion, and if it supports using the wrong algorithm for your needs, you need mostly to suck it up.&lt;/li&gt;
&lt;li&gt;When a reply is too slow for your timers (L7/L4), it will re-transmit the same fragment many times even though the endpoint did receive it but was slow to respond.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  UDP
&lt;/h3&gt;

&lt;p&gt;UDP is a simple lightweight (compared to TCP) transport protocol.&lt;br&gt;
It does not assume anything besides Port (mostly) and lets your application do all that it needs as &lt;a href="https://en.wikipedia.org/wiki/Business_logic" rel="noopener noreferrer"&gt;business logic&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Does it sound bad compared to TCP?&lt;br&gt;
Well, no, because it exists for different uses.&lt;/p&gt;

&lt;h4&gt;
  
  
  Examples
&lt;/h4&gt;

&lt;h5&gt;
  
  
  VPN
&lt;/h5&gt;

&lt;p&gt;Let's say I create a site-to-site &lt;a href="https://en.wikipedia.org/wiki/Virtual_private_network" rel="noopener noreferrer"&gt;VPN&lt;/a&gt;—that is, a VPN as infrastructure—that provides new network legs rather than two machines connected.&lt;/p&gt;

&lt;p&gt;If an application creates a VPN using TCP transport, every packet will take a long time to work.&lt;br&gt;
It never knows when something will be sent, and the traffic will create congestion in the network.&lt;/p&gt;

&lt;p&gt;So to mitigate some of the issues, things are more relaxed, thanks to UDP&lt;sup&gt;*&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The connection can be once every 10 hours, but in theory, there is a connection that will transport that content and is "alive" and kicking.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;*There are some TCP-based VPNs, but they are not suited for site-to-site, to my knowledge. &lt;/sup&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  ssh
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c3yi8ksqrb90v3vaopl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c3yi8ksqrb90v3vaopl.png" alt="mosh session" width="477" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Normal &lt;a href="https://en.wikipedia.org/wiki/Secure_Shell" rel="noopener noreferrer"&gt;ssh&lt;/a&gt; is TCP-based.&lt;br&gt;
But there is also a different implementation named &lt;a href="https://mosh.org/" rel="noopener noreferrer"&gt;mosh&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What happens if your network connection is unstable?&lt;br&gt;
Well, the connection will be lost at some point, no matter how stable the protocol is trying to be (even with keep-alive), the end server will disconnect you when the client is up again.&lt;/p&gt;

&lt;p&gt;For the above reason &lt;a href="https://en.wikipedia.org/wiki/Mosh_(software)" rel="noopener noreferrer"&gt;mosh&lt;/a&gt; is using UDP.&lt;br&gt;
Even when your connection was lost for 10 hours (don't you love my magic numbers in this post?), you can still connect and continue from the point it ended.&lt;/p&gt;

&lt;h5&gt;
  
  
  Streaming
&lt;/h5&gt;

&lt;p&gt;When using communication protocols (it does not have to be telephony), there is a &lt;a href="https://en.wikipedia.org/wiki/Real-time_Transport_Protocol" rel="noopener noreferrer"&gt;Real Time Protocol (RTP)&lt;/a&gt; that sends chunks of media (audio and/or video) for this example.&lt;/p&gt;

&lt;p&gt;That media is broken out into "frames", and there is a buffer (&lt;a href="https://en.wikipedia.org/wiki/Jitter" rel="noopener noreferrer"&gt;jitter&lt;/a&gt; buffer) that collects X amount of media chunks and sends it to be processed by a device (such as audio devices).&lt;/p&gt;

&lt;p&gt;Such media is part of a &lt;a href="https://en.wikipedia.org/wiki/Codec" rel="noopener noreferrer"&gt;codec (encoder-decoder)&lt;/a&gt; that stores the data in a specific format instead of its raw form.&lt;br&gt;
Such codec defines (or provides a range of) several frames that need to be collected to be proper media.&lt;br&gt;
Some codecs also contain a variant of frames that change based on the bandwidth and/or performance (such as &lt;a href="https://en.wikipedia.org/wiki/Opus_(audio_format)" rel="noopener noreferrer"&gt;OPUS&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;When there are fewer frames of a defined amount of frames available at the buffer level, audio (up to a point) sounds more like a metallic sound (the issue named jittering), and video will not be updated.&lt;br&gt;
Also, each implementation needs to define a sweet spot between waiting for data and releasing the current buffer, and that also can create the jittering.&lt;br&gt;
Older frames that arrive late are thrown away if the buffer was already released (or the re-ordering of data will cause a big delay).&lt;/p&gt;

&lt;p&gt;But there is no need to collect older frames that arrived late because it misses the point of streaming; there is a need to continue with the newer frames, ignoring older ones.&lt;/p&gt;

&lt;p&gt;But how can a program know how much was arrived in total and how much was lost if there isn't any L4 implementation?!&lt;/p&gt;

&lt;p&gt;There is another "nice" protocol named &lt;a href="https://en.wikipedia.org/wiki/RTP_Control_Protocol" rel="noopener noreferrer"&gt;RTCP (RTP Control Protocol)&lt;/a&gt;&lt;br&gt;
that sums up every X amount of time how much data (frames) were sent, and now there are also statistics and the ability to change variants of codecs or even negotiate new ones based on that information.&lt;/p&gt;

&lt;p&gt;Such decisions usually use table scores such as &lt;a href="https://en.wikipedia.org/wiki/Mean_opinion_score" rel="noopener noreferrer"&gt;MOS&lt;/a&gt; to help understand packet loss of media and its effect over time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa38871jxt5jnlxqgazqv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa38871jxt5jnlxqgazqv.png" alt="Google's streaming as example" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion?!
&lt;/h2&gt;

&lt;p&gt;Well, to explain UDP, I'll require several boring blog posts (even more than this one), so I decided to explain the way networking works and provide examples of using UDP and why TCP might not be suited for the task.&lt;/p&gt;

&lt;p&gt;I hope that by doing so, I was able to explain a bit more why there is a need for UDP and why it is so different from TCP.&lt;br&gt;
It's not about "what L4 protocol is better", but "what L4 protocol suits my needs", and what is required to be made for that.&lt;/p&gt;

&lt;h2&gt;
  
  
  About me
&lt;/h2&gt;

&lt;p&gt;I'm writing telecommunication software in my day-to-day work.&lt;/p&gt;

&lt;p&gt;My day-to-day work forces me to interact with many networking protocols, and many &lt;a href="https://en.wikipedia.org/wiki/OSI_model" rel="noopener noreferrer"&gt;OSI network layers&lt;/a&gt;, including three transport layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol" rel="noopener noreferrer"&gt;TCP&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol" rel="noopener noreferrer"&gt;UDP&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol" rel="noopener noreferrer"&gt;SCTP&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My work also forces me to work with so many IT-related stuff, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Router_(computing)" rel="noopener noreferrer"&gt;routers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Network_switch" rel="noopener noreferrer"&gt;switches&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Firewall_(computing)" rel="noopener noreferrer"&gt;firewalls&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Network_address_translation" rel="noopener noreferrer"&gt;NAT&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Link_aggregation" rel="noopener noreferrer"&gt;nic teaming/bonding&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Load_balancing_(computing)" rel="noopener noreferrer"&gt;Load Balancers&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To name a few...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/File:Mr._Meeseeks.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84z0yb2c82m572074wpe.png" alt="Mr Meeseeks from Rick and Morty" width="209" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>udp</category>
      <category>networking</category>
      <category>tcp</category>
      <category>sockets</category>
    </item>
    <item>
      <title>Not a malware</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Wed, 07 Apr 2021 14:01:16 +0000</pubDate>
      <link>https://dev.to/ik5/not-a-malware-2n9l</link>
      <guid>https://dev.to/ik5/not-a-malware-2n9l</guid>
      <description>&lt;p&gt;For the past year or so I wrote several Golang based applications for the Windows environment.&lt;/p&gt;

&lt;p&gt;The pain of writing software for Windows in non Microsoft tooling is a whole set of posts that I can create, but one thing is worst.&lt;/p&gt;

&lt;p&gt;Many applications that are written using Golang are considered to be a Virus, or a maleware of some kind simply because they are written in Go.&lt;/p&gt;

&lt;p&gt;When you use tools such as Virus Total, upload a Go based application that you wrote and see how many results of Anti Viruses think that you are trying to create a malware of some kind.&lt;/p&gt;

&lt;p&gt;The malware I wrote is just an HTTP server with support of TLS certificate and JWT, registry access for some information, Windows service(ing) to run as one, loading dynamically a .dll file that I wrote (using c++) and few additional COM binding for my witchcraft mix.&lt;/p&gt;

&lt;p&gt;That simple mixture was tagged as ransomware just because I had support for x509 inside my code and working as non GUI service.&lt;/p&gt;

&lt;p&gt;An "expert" of the organization that the server was suppose to use it told me that I have "hidden code" because of the traces on x509 PKI implementation inside the .exe .&lt;/p&gt;

&lt;p&gt;I know, I'm a bad person just because I use tech that can be used for evil.&lt;br&gt;
Like if you use a knife you are an evil person because you can stab or just cut another person - that's why anti viruses consider my code to be a malicious one, right?&lt;/p&gt;

&lt;p&gt;After investigation, I realized that I'm not the only one, look at the &lt;a href="https://golang.org/doc/faq#virus"&gt;Golang FAQ&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a common occurrence, especially on Windows machines, and is almost always a false positive. Commercial virus scanning programs are often confused by the structure of Go binaries, which they don't see as often as those compiled from other languages.&lt;/p&gt;

&lt;p&gt;If you've just installed the Go distribution and the system reports it is infected, that's certainly a mistake. To be really thorough, you can verify the download by comparing the checksum with those on the downloads page.&lt;/p&gt;

&lt;p&gt;In any case, if you believe the report is in error, please report a bug to the supplier of your virus scanner. Maybe in time virus scanners can learn to understand Go programs. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If (almost) every program written in Go is considered a malware, what can a simple developer can do?!&lt;/p&gt;

&lt;p&gt;I never ever wrote a malware in my life, never tried to do harm, but now if I use a term from my native language: "I need to prove that I do not have a sister" just because someone/thing decided that I do.&lt;/p&gt;

&lt;p&gt;So what would you do?&lt;/p&gt;

</description>
      <category>go</category>
      <category>malware</category>
      <category>falsepositive</category>
      <category>windows</category>
    </item>
    <item>
      <title>First class citizen</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Sat, 02 May 2020 08:09:09 +0000</pubDate>
      <link>https://dev.to/ik5/first-class-citizen-4l68</link>
      <guid>https://dev.to/ik5/first-class-citizen-4l68</guid>
      <description>&lt;p&gt;In the past few months I find myself writing a Windows based service using the Go.&lt;/p&gt;

&lt;p&gt;Long time ago (almost 20 years back) I used to be a Delphi and VB(A) developer, but I moved to Linux, and almost never looked back again.&lt;/p&gt;

&lt;p&gt;I had one small project back in 2012 for a simple cross platform service (it needed to work both on Windows and Linux) and then I learned Go and created it by providing a single binary that "just works".&lt;/p&gt;

&lt;p&gt;These months it's something different. I create an infrastructure for a big company that is going to work on over 40,000 machines just on Windows as a standalone servic, and it is an infrastructure for a big high demand service that the company provides to everyone and not just to their regular customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go and Windows
&lt;/h2&gt;

&lt;p&gt;The first thing you notice using Go is that it feels right at home when using it on Unix based systems (Linux in my case).&lt;/p&gt;

&lt;p&gt;But Windows is not Linux or Unix for that matter. It does have some &lt;a href="https://en.wikipedia.org/wiki/POSIX"&gt;POSIX&lt;/a&gt; &lt;a href="https://en.wikipedia.org/wiki/Microsoft_POSIX_subsystem"&gt;support&lt;/a&gt; but it's not a POSIX OS.&lt;/p&gt;

&lt;p&gt;I tried to take a string holding environment variable and replace it with it's content, so I found &lt;a href="https://golang.org/pkg/os/?m=windows#Expand"&gt;&lt;code&gt;os.Expand&lt;/code&gt;&lt;/a&gt; that exists for Windows as well, Great.&lt;br&gt;
But when it execute in Windows it does not do a it's job at Windows.&lt;/p&gt;

&lt;p&gt;Note that the link is for Windows related functions, but the implementation when you &lt;a href="https://golang.org/src/os/env.go?s=403:460#L6"&gt;read the code&lt;/a&gt; is not for &lt;a href="https://en.wikipedia.org/wiki/Environment_variable#Syntax"&gt;environment variables of Windows&lt;/a&gt; that uses percentages as variable marks, but rather for a dollar sign that is used mostly by &lt;a href="https://en.wikipedia.org/wiki/Unix_shell"&gt;Unix based shell(s)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Windows has it's own function to do the same action named &lt;a href="https://docs.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-expandenvironmentstringsw"&gt;&lt;code&gt;ExpandEnvrionmentStringsW&lt;/code&gt;&lt;/a&gt; (or ends with &lt;code&gt;S&lt;/code&gt; as well). &lt;/p&gt;

&lt;p&gt;I would expected with Go's &lt;code&gt;os&lt;/code&gt; package to create &lt;code&gt;env_unix.go&lt;/code&gt; and &lt;code&gt;env_windows.go&lt;/code&gt; to provide the same function, but internally do different work when having the Go method for doing things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Citizen Go
&lt;/h2&gt;

&lt;p&gt;I know what you are now thinking, Go is doing a bad work on providing a standard and extended libraries.&lt;/p&gt;

&lt;p&gt;Well, sort of, but not really. Only incomplete work for that.&lt;/p&gt;

&lt;p&gt;There is a thinking that was not invented by Go - "I" should provide the same syntax regardless of uniqueness of things unless there is absolutely no way in doing that, and then there is an exception for that rule. That is create something with the least common denominator. &lt;/p&gt;

&lt;p&gt;Go implement that idea but not invented it. But it did something different then most languages. That is create their own "lingo" for the standard library, rather then using the lingo of a specific environment/operating system.&lt;/p&gt;

&lt;p&gt;There are other languages such as &lt;a href="https://en.wikipedia.org/wiki/Object_Pascal"&gt;Object Pascal&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)"&gt;C#&lt;/a&gt;* that tries to provide the same standard library idea - emphasis on specific environment regarding the main libraries syntax it provides.&lt;/p&gt;

&lt;p&gt;Both Object Pascal (&lt;a href="https://en.wikipedia.org/wiki/Delphi_(software)"&gt;Delphi&lt;/a&gt;/&lt;a href="https://en.wikipedia.org/wiki/Free_Pascal"&gt;FPC&lt;/a&gt;) and C# provides Windows based API thinking for everything. &lt;/p&gt;

&lt;p&gt;Both Object Pascal and C# run also on Unix based systems today, but still, the API is Windows based, rather then more generic way. It is important to note that C# does much better work then Object Pascal, due to &lt;a href="https://en.wikipedia.org/wiki/Standard_Libraries_(CLI)"&gt;CLI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Go did the opposite - POSIX is the default (and most common denominator of OS based) rather then Windows, but also provide it's own syntax or "lingo" for that.&lt;/p&gt;

&lt;p&gt;But it's not the only way of doing things.&lt;/p&gt;

&lt;h2&gt;
  
  
  A coin have infinite sides
&lt;/h2&gt;

&lt;p&gt;All three languages: Go, C# and Object Pascal took a shortcut. Both Object Pascal and C# started with Windows, so that was the thinking when creating the language support.&lt;/p&gt;

&lt;p&gt;Go started by a Unix Developers (&lt;a href="https://en.wikipedia.org/wiki/Ken_Thompson"&gt;Ken Thompson&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Rob_Pike"&gt;Rob Pike&lt;/a&gt;), and most usage of Go is on Unix based systems mainly Linux.&lt;/p&gt;

&lt;p&gt;But the there are other ways such as how Rust* made it.&lt;br&gt;
&lt;a href="https://doc.rust-lang.org/std/os/index.html"&gt;Rust provides an OS specific implementation&lt;/a&gt; for everything that is not unified.&lt;/p&gt;

&lt;p&gt;It makes few things a bit harder to do though (the support for generics didn't help there btw).&lt;/p&gt;

&lt;p&gt;For example Unix provides a mask for a file or directory/library - The permission. So a mask for owner to read, write and execute (enter) a directory while group and others can only read and execute (enter) is &lt;code&gt;0644&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It does not exists for specific file systems, and by default Windows (unless it supports a file system that does support it) does not support it as well.&lt;/p&gt;

&lt;p&gt;Using the Rust way will have me check both OS and file systems together.&lt;br&gt;
For example both &lt;code&gt;Linux&lt;/code&gt;, &lt;code&gt;Unix&lt;/code&gt; and &lt;code&gt;raw&lt;/code&gt; have metadata for their own uniqueness, but based on documentation, &lt;code&gt;Windows&lt;/code&gt; does not have it.&lt;/p&gt;

&lt;p&gt;So at the end developers will create a higher level class/function that tries to answer that need, or will create two implementations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;With masks.&lt;/li&gt;
&lt;li&gt;Without masks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And if you do it for compile time, and for example Windows 10 added &lt;a href="https://en.wikipedia.org/wiki/Ext4"&gt;Ext4 file system&lt;/a&gt; for example, you will not be able to create or change mask.&lt;br&gt;
If it's on runtime, you will not have any support for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's C
&lt;/h3&gt;

&lt;p&gt;C also has it's own way of doing things, but it's Unix based because C was invented for creating Unix back in the 70's.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/C_standard_library"&gt;C standard library&lt;/a&gt; is actually a &lt;a href=""&gt;POSIX standard&lt;/a&gt;, and as such it is very Unix based that every implementation must support a syntax that might not be native to that operating system, and might require additional libraries that will help in that matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The best way is...
&lt;/h2&gt;

&lt;p&gt;I do not really know what is the best way for solving this issue.&lt;/p&gt;

&lt;p&gt;I find myself less opinionated. I do not think that there is a single way of doing it "right", but only the least worst.&lt;/p&gt;

&lt;p&gt;The effort and the result must matter in the path.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Important note&lt;/strong&gt;: I never wrote programs on C# or Rust, only investigated it.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>windows</category>
      <category>linux</category>
    </item>
    <item>
      <title>Design it simple, stupid</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Sun, 01 Mar 2020 08:07:09 +0000</pubDate>
      <link>https://dev.to/ik5/design-it-simple-stupid-2lo3</link>
      <guid>https://dev.to/ik5/design-it-simple-stupid-2lo3</guid>
      <description>&lt;p&gt;I love some programming principles such as as &lt;a href="https://en.wikipedia.org/wiki/KISS_principle"&gt;KISS - Keep it Simple Stupid&lt;/a&gt;, or even &lt;a href="https://en.wikipedia.org/wiki/Occam%27s_razor"&gt;Ockham razor&lt;/a&gt; when debugging my code.&lt;/p&gt;

&lt;p&gt;But somehow I do not practice them as much as I wish to see them on my daily work.&lt;/p&gt;

&lt;p&gt;For example, I designed a powerful syntax the other day for a new customer, but the person that needed to code it didn't understand how simple it is (in my eyes at least).&lt;/p&gt;

&lt;p&gt;When another fellow developer cannot see the simplicity of things I design, well, it is not simple as I see it!&lt;br&gt;
&lt;strong&gt;It's on me&lt;/strong&gt;, not on the fellow developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Complexity
&lt;/h2&gt;

&lt;p&gt;The fast thinkers probably thinking "you are mixing between understanding and design".&lt;/p&gt;

&lt;p&gt;I used to think that the two are different, but no longer.&lt;/p&gt;

&lt;p&gt;As an example, lets say I provide you with two oval shapes. Then I'm explaining to you that the system must have oval shapes in order for it to work.&lt;/p&gt;

&lt;p&gt;It is simpler to understand when everything is designed to help you understand that only oval shaped objects for example can get inside the system.&lt;/p&gt;

&lt;p&gt;If you place a rectangle, well, the entry will not fit. The opening contain oval cutting, and the entire way of the system enforces the oval shape. &lt;/p&gt;

&lt;p&gt;When my design helps at very fast glance to understand things I wanted them to understand, then my design is good.&lt;/p&gt;

&lt;p&gt;When my design does not help that, and a lot of effort is taken place to figure it out, then my design is bad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing a design
&lt;/h2&gt;

&lt;p&gt;I know what you are thinking, let's create some unit testing for my theory.&lt;/p&gt;

&lt;p&gt;Well there is a problem with that.&lt;/p&gt;

&lt;p&gt;Things that are easy for me to understand and figuring it out, are not the same as what is simple and easy for others.&lt;/p&gt;

&lt;p&gt;I need to generate something in a cultural agnostic way that can be understood by many.&lt;/p&gt;

&lt;p&gt;That's why Emoji for example works. Emoji started with few symbols, and then incremented over the years.&lt;/p&gt;

&lt;p&gt;The shapes are simple to understand most of the time - Happy face, Sad face, Angry face, Laughing face etc...&lt;/p&gt;

&lt;p&gt;Then some less understood faces appeared, and we misused them. And that was the time that the design was over complicated.&lt;/p&gt;

&lt;p&gt;The shape of the Emoji was too confusing.&lt;br&gt;
On that point, many icons were re-shaped to be much better and much clearer for us to understand.&lt;/p&gt;

&lt;p&gt;If something that supposed to be simple for humans to do (well, it is actually very complicated) became so hard, it's not the people that misunderstand it, it's the design that has a flaw in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking responsibility
&lt;/h2&gt;

&lt;p&gt;I'm taking full responsibility when something is not that clear for others.&lt;/p&gt;

&lt;p&gt;If there are people that it's clearer for them without me helping them, and others that it's unclear for them, then I'm trying to figure out what is the places people misunderstand the most.&lt;/p&gt;

&lt;p&gt;If one or two people misunderstand, then I do not know if I can simplify it further (that is the effort for it, rather then imagination).&lt;/p&gt;

&lt;p&gt;But if most or all people misunderstand something... &lt;br&gt;
It's time to re-group and re-think on a better way of designing the same thing.&lt;/p&gt;

&lt;p&gt;Learn from what makes people misunderstand the design, rather then blame the people, and you'll become a much better KISS'er then me ;)&lt;/p&gt;

</description>
      <category>kiss</category>
      <category>codedesign</category>
    </item>
    <item>
      <title>Quick and dirty Audio playing in Golang on Windows</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Thu, 20 Feb 2020 15:50:17 +0000</pubDate>
      <link>https://dev.to/ik5/quick-and-dirty-audio-playing-in-golang-3n7c</link>
      <guid>https://dev.to/ik5/quick-and-dirty-audio-playing-in-golang-3n7c</guid>
      <description>&lt;p&gt;Over 20 years ago I used to write Delphi and VB in the MS Windows world.&lt;/p&gt;

&lt;p&gt;A decision by MS to remove something from Windows libraries helped me  switching to Linux, and I never really looked back.&lt;/p&gt;

&lt;p&gt;But now I have a client that wish for my service to work on their Windows (instead of Linux). &lt;/p&gt;

&lt;p&gt;I started looking at the Windows API again (hello old MSDN), and understood how much have changed since I last touched the API.&lt;/p&gt;

&lt;p&gt;Most documentation are for the C# dev's, but I never even written an &lt;code&gt;Hello world&lt;/code&gt; with it, and found out how much effort does the working with &lt;a href="https://docs.microsoft.com/en-us/windows/win32/api/mmdeviceapi/nn-mmdeviceapi-immdevice"&gt;&lt;code&gt;IMMDevice&lt;/code&gt;&lt;/a&gt; requires from me, and all my client requires from me here is to play a &lt;code&gt;wav&lt;/code&gt; file for the default Audio device.&lt;/p&gt;

&lt;p&gt;So I started thinking how to do that. Google reminded me by accident the "good" old world of &lt;a href="https://docs.microsoft.com/en-us/windows/win32/multimedia/waveform-audio?redirectedfrom=MSDN"&gt;&lt;code&gt;waveform&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/en-us/previous-versions//dd743680(v=vs.85)?redirectedfrom=MSDN"&gt;&lt;code&gt;PlaySound&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;After several hours, I came up with a working copy of Go over Windows (my development is still on Linux, and cross compiled to Windows).&lt;br&gt;
I do not own a Windows copy, only Linux(es) for so many years now, so my tests are on my Client's Windows machine, while I'm connected using &lt;a href="https://en.wikipedia.org/wiki/Remote_Desktop_Protocol"&gt;RDP&lt;/a&gt; (the pain).&lt;/p&gt;
&lt;h2&gt;
  
  
  Binding ...
&lt;/h2&gt;

&lt;p&gt;Windows usually provides C based ABI for API calls (unless you are using .NET apps, and then you are using &lt;a href="https://en.wikipedia.org/wiki/Common_Language_Runtime"&gt;CLR&lt;/a&gt; based virtual machine's ABI).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ik5/golang-and-shared-objects-part-1-the-background-4ecf"&gt;There are two ways for me to load it...&lt;/a&gt;, and I decided to bind myself on &lt;code&gt;run-time&lt;/code&gt;, using Go's &lt;a href="https://golang.org/pkg/syscall/?GOOS=windows#DLL"&gt;&lt;code&gt;syscall.DLL&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  First step
&lt;/h3&gt;

&lt;p&gt;My first step was going over the &lt;code&gt;mmsystem.h&lt;/code&gt; header file, just to find out that it's a &lt;code&gt;meta&lt;/code&gt; header for including many headers. &lt;br&gt;
Quick &lt;a href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt; (thanks Google for that command btw) I found that all I need is under the &lt;code&gt;playsoundapi.h&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;I copied all the integer based constants and just made it Go syntax friendly (but not Linter friendly).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;SND_SYNC&lt;/span&gt;      &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x0000&lt;/span&gt; &lt;span class="c"&gt;/* play synchronously (default) */&lt;/span&gt;
    &lt;span class="n"&gt;SND_ASYNC&lt;/span&gt;     &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x0001&lt;/span&gt; &lt;span class="c"&gt;/* play asynchronously */&lt;/span&gt;
    &lt;span class="n"&gt;SND_NODEFAULT&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x0002&lt;/span&gt; &lt;span class="c"&gt;/* silence (!default) if sound not found */&lt;/span&gt;
    &lt;span class="n"&gt;SND_MEMORY&lt;/span&gt;    &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x0004&lt;/span&gt; &lt;span class="c"&gt;/* pszSound points to a memory file */&lt;/span&gt;
    &lt;span class="n"&gt;SND_LOOP&lt;/span&gt;      &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x0008&lt;/span&gt; &lt;span class="c"&gt;/* loop the sound until next sndPlaySound */&lt;/span&gt;
    &lt;span class="n"&gt;SND_NOSTOP&lt;/span&gt;    &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x0010&lt;/span&gt; &lt;span class="c"&gt;/* don't stop any currently playing sound */&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Initialize &lt;code&gt;syscall.DLL&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;I can implement some nice functions after having the constants.&lt;/p&gt;

&lt;p&gt;After some thinking, I decided to create a wrapper using a more Go friendly function that calls the ugly Windows API functions.&lt;/p&gt;

&lt;p&gt;I started by defining a call to the &lt;code&gt;.dll&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;mmsystem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MustLoadDLL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"winmm.dll"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;syscall.MustLoadDLL&lt;/code&gt; loads a &lt;code&gt;.dll&lt;/code&gt; file to memory, and if fails the loading will panic my process.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mmsystem&lt;/code&gt; is now a pointer of struct &lt;code&gt;syscall.DLL&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Using Go, every function with &lt;code&gt;Must&lt;/code&gt; will &lt;code&gt;panic&lt;/code&gt; if there is an error.&lt;/p&gt;
&lt;h3&gt;
  
  
  Memory address for functions
&lt;/h3&gt;

&lt;p&gt;Now that I have the &lt;code&gt;.dll&lt;/code&gt; file all loaded an warm up for me (thanks Go), I can get do some stuff with it.&lt;/p&gt;

&lt;p&gt;In this case, I need some API's function love.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;playSound&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmsystem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MustFindProc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PlaySound"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sndPlaySoundA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmsystem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MustFindProc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sndPlaySoundA"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sndPlaySoundW&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmsystem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MustFindProc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sndPlaySoundW"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The old world of Windows (maybe also in the new?) the &lt;code&gt;NT&lt;/code&gt;/&lt;code&gt;server&lt;/code&gt; based run-time supported &lt;a href="https://en.wikipedia.org/wiki/UTF-16"&gt;Unicode (UTF-16BE)&lt;/a&gt;, while home/pro etc.. editions supported mostly &lt;a href="https://en.wikipedia.org/wiki/Extended_ASCII"&gt;extended ASCII&lt;/a&gt; with some &lt;a href="https://en.wikipedia.org/wiki/Windows_code_page"&gt;&lt;code&gt;code page&lt;/code&gt;&lt;/a&gt; encoding for human languages.&lt;/p&gt;

&lt;p&gt;The suffix of &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;W&lt;/code&gt; provides support for the two types.&lt;br&gt;
The &lt;code&gt;A&lt;/code&gt; suffix is for &lt;code&gt;ASCII&lt;/code&gt; and the &lt;code&gt;W&lt;/code&gt; suffix is for &lt;code&gt;Wide char&lt;/code&gt; encoding - meaning multi-byte encoding.&lt;/p&gt;

&lt;p&gt;I decided to support both of them in order to learn how Go works with both of them.&lt;/p&gt;
&lt;h3&gt;
  
  
  Wrapping and gifting
&lt;/h3&gt;

&lt;p&gt;I loaded the functions that I wish to use.&lt;/p&gt;

&lt;p&gt;Now it's time to wrap the API functions in order to have a nice Go like code rather then repeating my code usage each time.&lt;/p&gt;

&lt;p&gt;When I used &lt;code&gt;MustFindProc&lt;/code&gt;, I actually got a new pointer to a struct named &lt;code&gt;Proc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Proc&lt;/code&gt; have one interesting function: &lt;code&gt;Call&lt;/code&gt;. It actually execute the arguments we need (up to 18 arguments), using &lt;code&gt;syscallXX&lt;/code&gt; for us instead of us writing this ugly code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Call&lt;/code&gt; returns three arguments, but I ignored them (bad dev, bad dev) - the last argument is an error that might have happened.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="c"&gt;// PlaySound play sound in Windows&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;PlaySound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hmod&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;flags&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF16PtrFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;playSound&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uintptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s16&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hmod&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// SndPlaySoundA play sound file in Windows&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SndPlaySoundA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sound&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;append&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="n"&gt;sound&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="n"&gt;sndPlaySoundA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uintptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&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="kt"&gt;uintptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;On &lt;code&gt;PlaySound&lt;/code&gt; I converted the Go string (UTF-8) to &lt;code&gt;syscall&lt;/code&gt;'s &lt;code&gt;UTF16BE&lt;/code&gt; (c-)string.&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;SndPlaySoundA&lt;/code&gt; I converted Go string into ASCII, using slice of byte, and added a &lt;a href="https://en.wikipedia.org/wiki/Null-terminated_string"&gt;null terminated&lt;/a&gt; at the end of the slice to let C based code when the string needs to end.&lt;/p&gt;

&lt;p&gt;On all functions  (&lt;code&gt;PlaySound&lt;/code&gt; and &lt;code&gt;SndPlaySoundX&lt;/code&gt;) there is some ugly code, so the wrapper hides it, giving us a nice Go-ish syntax instead.&lt;/p&gt;

&lt;p&gt;When using &lt;code&gt;unsafe&lt;/code&gt;, it is important to note that &lt;a href="https://en.wikipedia.org/wiki/Endianness"&gt;CPU's endian&lt;/a&gt;, and so does memory addresses are not cross platformed as much as other code.&lt;/p&gt;

&lt;p&gt;So it is important to understand that usage of code that touches &lt;code&gt;unsafe&lt;/code&gt; contain some possible pitfalls that will be discovered on run-time only, and on some machines only. FUN!&lt;/p&gt;
&lt;h2&gt;
  
  
  The full Code
&lt;/h2&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On a real production code, there are more steps to take - &lt;strong&gt;Always check and validate errors, never ignore them as I did&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>audio</category>
      <category>go</category>
      <category>windows</category>
    </item>
    <item>
      <title>Golang and shared objects Part 1 - The background</title>
      <dc:creator>ik_5</dc:creator>
      <pubDate>Fri, 10 Jan 2020 17:29:52 +0000</pubDate>
      <link>https://dev.to/ik5/golang-and-shared-objects-part-1-the-background-4ecf</link>
      <guid>https://dev.to/ik5/golang-and-shared-objects-part-1-the-background-4ecf</guid>
      <description>&lt;p&gt;When creating an application using Golang, it is usually a monolithic executable that holds "everything" is inside.&lt;/p&gt;

&lt;p&gt;When there is a need to separate some logic for execution, I find that many software architects prefer actors/model or workers for that.&lt;/p&gt;

&lt;p&gt;I do think that there is room for having actors/model or workers, and I personally do use them, but as software developers we have so many tools for our disposal that I feel like they are not in use or taken in consideration on places that they can be helpful, and that is the trigger for the current series of posts.&lt;/p&gt;

&lt;p&gt;One tool that is over looked is &lt;strong&gt;shared object&lt;/strong&gt; a.k.a. &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Library_(computing)#Shared_libraries"&gt;shared library&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The following series of blog posts are about shared objects/libraries. On my next posts I will use Golang (and sometimes even C) for explaining how things are done, but the basics are the same in their concept for most programming languages - even most dynamic languages (such as Python and Ruby), uses the same concept but with different syntax or tool set.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is it all about
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Shared Object
&lt;/h2&gt;

&lt;p&gt;In a nutshell: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Shared Object/Library is a binary file with dynamic/static loading table for functions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are two types of shared objects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dynamic.&lt;/li&gt;
&lt;li&gt;Static.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As I wrote at the beginning of the post - the static version is usually what Go is using. Static library compiles functions inside the executable causing the function to be part of the program inside the executable as it was written by us for that program.&lt;/p&gt;

&lt;p&gt;Dynamic library is actually the same as an executable file on most systems and formats, but without the execution part, only dynamic memory table that holds function addresses that can be used when looking for a function.&lt;/p&gt;

&lt;p&gt;We know dynamic libraries as &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Dynamic-link_library"&gt;.dll&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Executable_and_Linkable_Format"&gt;.so&lt;/a&gt;&lt;/em&gt; and &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Mach-O"&gt;.dylib&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;On this post, I'll only talk about Dynamic Library. You can find &lt;a href="https://en.wikipedia.org/wiki/Static_library"&gt;more information about static library on this link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loading of a library
&lt;/h2&gt;

&lt;p&gt;A library can be used in two main ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Static loading&lt;/li&gt;
&lt;li&gt;Dynamic loading&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Static Loading
&lt;/h3&gt;

&lt;p&gt;The main usage of a library is to provide reusable functions.&lt;br&gt;
The functions do have memory address, but it is built to be as it was part of the application that calls it.&lt;/p&gt;

&lt;p&gt;In order to do that, a programming language requires to share the function name, and it's arguments.&lt;/p&gt;

&lt;p&gt;A function name (as well as some additional data structures) are called &lt;a href="https://en.wikipedia.org/wiki/Symbol_(programming)"&gt;symbol&lt;/a&gt;. The symbols hold a unique identifier for accessing, and contain "human readable" value.&lt;/p&gt;

&lt;p&gt;In order to access a symbol, there is a need to know the memory order of argument both for input and output values of the function.&lt;/p&gt;

&lt;p&gt;The signature and arguments order have the name of &lt;a href="https://en.wikipedia.org/wiki/Application_binary_interface"&gt;ABI - Application Binary Interface&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once a developer knows all of that information, it can instruct a &lt;a href="https://en.wikipedia.org/wiki/Dynamic_linker"&gt;linker&lt;/a&gt; on how to connect a library and it's function(s) to the executable or another library.&lt;/p&gt;

&lt;p&gt;It happens on build time (after compilation), when the executable is ready, there is an instruction for the Operating System (OS) on how it should be loaded with the process as part of it dependencies.&lt;/p&gt;

&lt;p&gt;A library is loaded by the OS when it is executing the process (program) as part of the memory address as the rest of the process, having the memory address of the library as something virtual rather then physical.&lt;/p&gt;

&lt;p&gt;A library can be loaded many times on the entire system, based on the number of processes or other libraries that uses it and are loaded by the OS, but each copy has it's own memory address that is private and not accessible by non related processes and shared libraries.&lt;/p&gt;

&lt;p&gt;On Unix system, it is easy to see the static linking by using the &lt;code&gt;ldd&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ldd main
        linux-vdso.so.1 &lt;span class="o"&gt;(&lt;/span&gt;0x00007fffed2c9000&lt;span class="o"&gt;)&lt;/span&gt;
        libc.so.6 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; /usr/lib/libc.so.6 &lt;span class="o"&gt;(&lt;/span&gt;0x00007f5321c21000&lt;span class="o"&gt;)&lt;/span&gt;
        /lib64/ld-linux-x86-64.so.2 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; /usr/lib64/ld-linux-x86-64.so.2 &lt;span class="o"&gt;(&lt;/span&gt;0x00007f5321e74000&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Dynamic Loading
&lt;/h3&gt;

&lt;p&gt;On static loading the linker and OS connects a library function to memory address, but it requires to bind a shared library to a process or another library. It is limiting when writing extensions for example.&lt;/p&gt;

&lt;p&gt;Another way to connect such function is on run-time.&lt;br&gt;
Run-time means that the process is loading the library to memory and requires to handle the entire ABI on run-time, including freeing the memory that is allocated and any issues that can happen by going that way.&lt;/p&gt;

&lt;p&gt;Due to the fact that the information is dynamic, it is impossible to know beforehand what library will be linked, unlike the static loading.&lt;/p&gt;
&lt;h2&gt;
  
  
  Loading of a function
&lt;/h2&gt;

&lt;p&gt;As mentioned above, a function on a shared library/object is called a &lt;a href="https://en.wikipedia.org/wiki/Symbol_(programming)"&gt;symbol&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;A symbol is a unique identifier for function, variable, constants etc...&lt;br&gt;
Something that the execution process knows how to access when it finds the name, and can find it's memory using &lt;a href="https://en.wikipedia.org/wiki/Symbol_table"&gt;Symbol table&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The symbol table holds a given name, the type of what the symbol is, memory position in order to attach to it's execution and ABI.&lt;/p&gt;

&lt;p&gt;Based on the format, it can hold additional information, or even a bit different method of getting such information, but that does not matter for us on this post.&lt;/p&gt;

&lt;p&gt;When a function is called, it is translated to a symbol name, and the symbol is looked upon and is used based on the memory address and usage.&lt;/p&gt;

&lt;p&gt;There are two ways in doing so:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Static loading&lt;/li&gt;
&lt;li&gt;Dynamic loading&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Static loading
&lt;/h3&gt;

&lt;p&gt;For static loading of a function, the main code need to have a function  with the same &lt;a href="https://en.wikipedia.org/wiki/Application_binary_interface"&gt;ABI&lt;/a&gt;, and the function will hold the memory to the function at the library.&lt;/p&gt;

&lt;p&gt;It is done after "compile time" - The linker places the memory address of the library symbol to the function at the executable (or other library that uses it).&lt;/p&gt;

&lt;p&gt;Using the command &lt;a href="https://linux.die.net/man/1/objdump"&gt;&lt;code&gt;objdump&lt;/code&gt;&lt;/a&gt; on Linux it is possible to see the linked symbols and their usage (written by me in C):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ objdump -t ./main

./main:     file format elf64-x86-64 

SYMBOL TABLE:
...
000000000000000       F *UND*  0000000000000000              printf@@GLIBC_2.2.5    
0000000000000000       F *UND*  0000000000000000              __libc_start_main@@GLIBC_2.2.5                     
0000000000000000       F *UND*  0000000000000000              g_uri_parse_scheme        
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Dynamic loading
&lt;/h3&gt;

&lt;p&gt;Dynamic loading of a function is as of dynamic loading of a library, and actually is part of it.&lt;br&gt;
The dynamic loading happens on run-time - The linking is done dynamically at the code level rather then at &lt;a href="https://en.wikipedia.org/wiki/Link_time"&gt;linkage time&lt;/a&gt;, providing more flexible way on expanding a process capabilities when needed.&lt;/p&gt;

&lt;p&gt;A function or memory address a.k.a pointer (depends on the programming language) is assigned to hold the loaded symbol.&lt;/p&gt;

&lt;p&gt;On Unix system the main library to use commands is named &lt;a href="https://en.wikipedia.org/wiki/C_standard_library"&gt;&lt;code&gt;libc&lt;/code&gt;&lt;/a&gt; or &lt;code&gt;C Standard Library&lt;/code&gt;. &lt;code&gt;libc&lt;/code&gt; contains a set of commands to load libraries dynamically, however it is not part of the main &lt;code&gt;libc&lt;/code&gt;, but an extension, because it is part of an operating system and not a standard way of dynamic loading a symbol out of a shared object.&lt;/p&gt;

&lt;p&gt;On most Unix systems, the API for loading symbols dynamically are under &lt;a href="https://linux.die.net/man/3/dlsym"&gt;&lt;code&gt;dlsym&lt;/code&gt;&lt;/a&gt; extensions. &lt;/p&gt;

&lt;p&gt;On MS-Windows there is a different but similar implementation named &lt;a href="https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/"&gt;&lt;code&gt;libloaderapi&lt;/code&gt;&lt;/a&gt;, contains additional functionality that Windows provides.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;On this blog post I have provided information that explains what is a shared object that is also known as shared library.&lt;/p&gt;

&lt;p&gt;I explained that there are two types of shared objects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Static shared object.&lt;/li&gt;
&lt;li&gt;Dynamic shared objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have explained in a nutshell the differences, and focused on dynamic shared objects.&lt;/p&gt;

&lt;p&gt;Explained that there are two methods of using them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Static linking.&lt;/li&gt;
&lt;li&gt;Dynamic linking.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And in a nutshell what it means.&lt;/p&gt;

&lt;h1&gt;
  
  
  What comes next?
&lt;/h1&gt;

&lt;p&gt;On the next part I will start writing some code, providing examples on how to write shared library both using C and Go.&lt;/p&gt;

&lt;p&gt;And on the 3rd part how to use them inside both C and Go.&lt;/p&gt;

&lt;p&gt;The 4th part will explain how to create special cases of Shared libraries (e.g. Go's plugins).&lt;/p&gt;

</description>
      <category>abi</category>
      <category>sharedlibrary</category>
      <category>tutorial</category>
      <category>go</category>
    </item>
  </channel>
</rss>
