<?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: TKD Engineer</title>
    <description>The latest articles on DEV Community by TKD Engineer (@tkdeng).</description>
    <link>https://dev.to/tkdeng</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3837507%2Fa3a0caaf-9edf-4efa-b2c3-7110e123eecc.png</url>
      <title>DEV Community: TKD Engineer</title>
      <link>https://dev.to/tkdeng</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tkdeng"/>
    <language>en</language>
    <item>
      <title>What If AI Was the Compiler? (An Imaginary Programming Language)</title>
      <dc:creator>TKD Engineer</dc:creator>
      <pubDate>Tue, 14 Jul 2026 06:12:44 +0000</pubDate>
      <link>https://dev.to/tkdeng/what-if-ai-was-the-compiler-an-imaginary-programming-language-5b4m</link>
      <guid>https://dev.to/tkdeng/what-if-ai-was-the-compiler-an-imaginary-programming-language-5b4m</guid>
      <description>&lt;p&gt;&lt;strong&gt;The Idea:&lt;/strong&gt; A programming language compiled by AI.&lt;/p&gt;

&lt;p&gt;Imagine writing code like you're in a whiteboard interview. No syntax rules, no imports, no debugging APIs. You write the logic, make up whatever functions you want on the fly, and let the AI do the rest.&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;// Imaginary code:&lt;/span&gt;
&lt;span class="nf"&gt;getUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;filterActive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="nf"&gt;animateToSide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// moves the UI text to the side&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't write &lt;code&gt;animateToSide()&lt;/code&gt;. The compiler’s LLM reads the context, synthesizes the missing function, and maps your intent directly into a production-grade language (like Rust or C++).&lt;br&gt;
A traditional compiler backend then optimizes it into a secure, blazing-fast binary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No Debugging, Zero Boilerplate, Doesn't Need Updates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can maintain your code simply by recompiling it.&lt;/p&gt;

&lt;p&gt;You get the best of both worlds: The ergonomics of pseudo-code with the absolute performance of bare metal.&lt;/p&gt;

&lt;p&gt;Imagine writing pseudocode that actually runs. We aren't parsing syntax anymore, we’re compiling intent.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Would This Actually Work? (3 Architectural Paths)
&lt;/h2&gt;

&lt;p&gt;An "AI compiler" doesn't have to output raw machine code directly (which LLMs are terrible at doing reliably). Instead, we can pipe the translation through existing engineering standards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transpiler Pipeline
&lt;/h3&gt;

&lt;p&gt;The LLM reads your structured intent and transpiles it into idiomatic, production-ready source code (like Rust, C++, or Go). It automatically resolves dependencies and pulls in the right libraries. It then hands that code off to a traditional compiler like rustc or clang to emit a highly optimized, secure native binary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid AST / Symbol Resolver
&lt;/h3&gt;

&lt;p&gt;A traditional compiler frontend parses the strict logic you did write (like your standard for loops or math). When it encounters an undefined symbol (like &lt;code&gt;animateToSide()&lt;/code&gt;), it pauses, queries a local, lightweight model with the specific context, synthesizes just that function, and inserts it back into the AST (Abstract Syntax Tree).&lt;/p&gt;

&lt;h3&gt;
  
  
  Test-Driven Synthesis Loop
&lt;/h3&gt;

&lt;p&gt;To prevent hallucinations, the compiler operates in an active sandbox loop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It reads your code and comments, then generates a candidate implementation.&lt;/li&gt;
&lt;li&gt;It simultaneously writes a suite of unit tests based on your expressed intent.&lt;/li&gt;
&lt;li&gt;It runs the code in a secure sandbox.&lt;/li&gt;
&lt;li&gt;If a test fails, it feeds the stack trace back into itself, auto-corrects, and compiles again until it passes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Trade-Offs
&lt;/h2&gt;

&lt;p&gt;It sounds like magic, but we'd face two massive bottlenecks immediately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Non-Determinism:&lt;/strong&gt; If you compile the exact same file twice, a pure LLM compiler might generate slightly different binary layouts or optimization paths each time. This would make debugging low-level memory leaks or race conditions a nightmare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference Latency:&lt;/strong&gt; Standard compilers process millions of lines of code per second. Waiting 10–30 seconds for an LLM inference pass every time you want to test a quick change would break the tight feedback loop devs rely on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But as local models get smaller, faster, and more deterministic, this feels less like a pipe dream and more like a logical next step.&lt;/p&gt;

&lt;p&gt;Obviously, trying to debug a memory leak when the compiler might rewrite your code on a whim sounds like a nightmare. But for rapid prototyping? I’d use this in a heartbeat.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>discuss</category>
      <category>ai</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Go's any is a Lie: The Case for Sum Types and Truthful API Contracts</title>
      <dc:creator>TKD Engineer</dc:creator>
      <pubDate>Sat, 21 Mar 2026 19:59:30 +0000</pubDate>
      <link>https://dev.to/tkdeng/gos-any-is-a-lie-the-case-for-sum-types-and-truthful-api-contracts-4j56</link>
      <guid>https://dev.to/tkdeng/gos-any-is-a-lie-the-case-for-sum-types-and-truthful-api-contracts-4j56</guid>
      <description>&lt;p&gt;When we define a function that accepts &lt;code&gt;map[string]any&lt;/code&gt;, we are telling the user: 'Give me anything.' But in reality, our code only handles &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;int&lt;/code&gt;. This is a broken contract. It forces us to move safety checks from the compiler to the runtime, trading 'red squiggles' in the IDE for &lt;code&gt;err != nil&lt;/code&gt; blocks in production. It's time for Go to embrace First-Class Sum Types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it currently works (The "Boilerplate" way):&lt;/strong&gt;&lt;br&gt;
We are forced to write "safety" code that should be handled by the compiler.&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;type&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="k"&gt;map&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="n"&gt;any&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="n"&gt;List&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// logic here&lt;/span&gt;
      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// This error only happens at RUNTIME.&lt;/span&gt;
        &lt;span class="k"&gt;return&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;"invalid type: %T"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it should work (The "Truthful" way):&lt;/strong&gt;&lt;br&gt;
The interface becomes a strict contract that the IDE and Compiler can enforce.&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="c"&gt;// The contract is defined at the type level&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="k"&gt;map&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;interface&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&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;func&lt;/span&gt; &lt;span class="n"&gt;Compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// No 'error' return or 'default' case needed. &lt;/span&gt;
    &lt;span class="c"&gt;// The compiler guaranteed the types.&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In modern development, an interface should be a contract.&lt;/p&gt;

&lt;p&gt;Using any is a broken contract. It tells the user 'Give me anything', but then my function fails at runtime if they actually do. That is a lie in the API design.&lt;/p&gt;

&lt;p&gt;A "General Interface" (like &lt;code&gt;interface{string|int}&lt;/code&gt;) is a truthful contract. It tells the programmer exactly what is allowed before they even hit 'Save'.&lt;/p&gt;

&lt;p&gt;Go is a statically typed language. By forcing me to use any for mixed-type maps, we are regressing to a 'JavaScript-like' experience where I, or someone else, has to look at the source code or documentation to know what a function accepts.&lt;/p&gt;

&lt;p&gt;Red squiggles in VS Code are better than &lt;code&gt;panic&lt;/code&gt; or &lt;code&gt;err != nil&lt;/code&gt; at runtime. Type constraints allow the IDE to provide Autocompletion and Static Analysis.&lt;/p&gt;

&lt;p&gt;Runtime errors are expensive; compile-time errors are free.&lt;/p&gt;

&lt;p&gt;If a junior developer tries to pass a nested map into your "Flat Map", the compiler should stop them instantly. If we use &lt;code&gt;any&lt;/code&gt;, that bug might survive all the way to a production environment before the switch default case triggers an error.&lt;/p&gt;

&lt;p&gt;If I use &lt;code&gt;iota&lt;/code&gt;, I can still pass a random &lt;code&gt;int&lt;/code&gt; to a function expecting my "Enum". A sum type or enum would allow the compiler to check that every possible case is handled in a switch statement.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Just use any and a type switch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using any shifts the responsibility of type safety from the compiler to the runtime. My goal is to catch errors during development, not during execution. If I use any, a developer can pass a nested map into a function expecting a flat list, and the IDE won't warn them. That leads to a 'broken contract' where the function signature says 'Give me anything' but the implementation says 'Actually, I only wanted these three things.' I'm looking for a way to make the API signature match the implementation requirements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Go is meant to be simple, don't overcomplicate it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simplicity is also about predictability. Forcing developers to write manual validation boilerplate (like if &lt;code&gt;type != x { return err }&lt;/code&gt;) for every function call increases 'noise' in the codebase. By allowing the compiler to handle these constraints, the business logic becomes cleaner and the intent of the code becomes more transparent to anyone reading it later.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is just a Union Type/Sum Type, Go doesn't have those.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Exactly. Go already allows these 'Type Sets' within Generic constraints. The inconsistency is that we can define these sets to validate a function, but we can't use them to define a variable's storage. I'm advocating for making the existing Type Set logic first-class so that mixed-type maps can benefit from the same static analysis that Generics currently enjoy.&lt;/p&gt;




&lt;p&gt;The Problem: API "Lies"&lt;br&gt;
When we use &lt;code&gt;map[string]any&lt;/code&gt;, we are essentially telling the user, "You can put anything here." But that is a lie if our internal logic only supports a few type constraints, (like string | int for example).&lt;/p&gt;

&lt;p&gt;The "DX" (Developer Experience) Argument:&lt;br&gt;
Red Squiggles &amp;gt; Logs: We want junior devs to see an error in an IDE (like VSCode) the moment they try to pass a nested map, not find a nil pointer or a "wrong type" error in the production logs.&lt;/p&gt;

&lt;p&gt;Static Analysis: Using any turns Go into a "Guessing Game." Proper type constraints allow the IDE to provide actual help via autocompletion and type warnings.&lt;/p&gt;

&lt;p&gt;The Cost of any: In a statically typed language, any should be the last resort, not the default for mixed-type collections.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Go (any)&lt;/th&gt;
&lt;th&gt;TypeScript (&amp;amp;vert;)&lt;/th&gt;
&lt;th&gt;Rust (enum)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;API Contract&lt;/td&gt;
&lt;td&gt;"The Lie": Claims to take anything, but fails at runtime.&lt;/td&gt;
&lt;td&gt;Truthful: Defines exact allowed types.&lt;/td&gt;
&lt;td&gt;Strict: Types are explicitly wrapped and checked.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feedback Loop&lt;/td&gt;
&lt;td&gt;Logs: Errors found via err != nil in production.&lt;/td&gt;
&lt;td&gt;IDE: "Red squiggles" during development.&lt;/td&gt;
&lt;td&gt;Compiler: Won't build until all cases are handled.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exhaustiveness&lt;/td&gt;
&lt;td&gt;Manual: Requires a default case to catch "impossible" types.&lt;/td&gt;
&lt;td&gt;Optional: Can be enforced with strict linting.&lt;/td&gt;
&lt;td&gt;Native: The compiler forces you to handle every variant.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;td&gt;Runtime: Uses reflect or type switches with error returns.&lt;/td&gt;
&lt;td&gt;Static: Validated before the code ever runs.&lt;/td&gt;
&lt;td&gt;Static: Zero-cost abstractions for type safety.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;Currently, with &lt;code&gt;iota&lt;/code&gt; constants, if you add a new "Type" to your code, the compiler won't tell you that you forgot to update a switch statement somewhere else. If Go had the syntax I'm proposing (&lt;code&gt;interface{TypeA | TypeB}&lt;/code&gt;), the compiler could technically check if you've handled every case.&lt;/p&gt;

&lt;p&gt;My goal is to eliminate the &lt;code&gt;else { return error }&lt;/code&gt; block in my second example. I believe the compiler should handle that check, not my runtime code.&lt;/p&gt;

</description>
      <category>go</category>
      <category>architecture</category>
      <category>typescript</category>
      <category>rust</category>
    </item>
  </channel>
</rss>
