<?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: Neil Chaudhuri</title>
    <description>The latest articles on DEV Community by Neil Chaudhuri (@neilchaudhuri).</description>
    <link>https://dev.to/neilchaudhuri</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%2F726967%2F4fd7f530-ced5-4cad-ab94-b7912560fc99.png</url>
      <title>DEV Community: Neil Chaudhuri</title>
      <link>https://dev.to/neilchaudhuri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/neilchaudhuri"/>
    <language>en</language>
    <item>
      <title>Python Is Not the Language of AI</title>
      <dc:creator>Neil Chaudhuri</dc:creator>
      <pubDate>Tue, 30 Sep 2025 14:45:16 +0000</pubDate>
      <link>https://dev.to/neilchaudhuri/python-is-not-the-language-of-ai-3k8o</link>
      <guid>https://dev.to/neilchaudhuri/python-is-not-the-language-of-ai-3k8o</guid>
      <description>&lt;p&gt;MIT recently reported that a staggering &lt;a href="https://www.forbes.com/sites/jaimecatmull/2025/08/22/mit-says-95-of-enterprise-ai-failsheres-what-the-5-are-doing-right/" rel="noopener noreferrer"&gt;95% of enterprise AI deployments fail&lt;/a&gt;.&lt;br&gt;
That is &lt;em&gt;really bad!&lt;/em&gt; The primary reasons are strategic rather than technical like the absence of a data strategy and no clear business objectives beyond "We need to use more AI or we will fall behind!" In all things, AI or otherwise, whatever you do downstream from terrible leadership is pretty much doomed to fail.&lt;/p&gt;

&lt;p&gt;However, even the most thoughtful strategy will fail without a very particular technical understanding:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Python has always been and will likely always be the language of machine learning (ML), but it is not the language of AI. The failure to understand the difference is hurting AI adoption. Succeeding with AI is a function of context not computation.&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  A little history
&lt;/h2&gt;

&lt;p&gt;Imagine you work at Netflix in 2010. You have a hypothesis: People are more likely to watch content, and therefore ads that will make your manager happy, that takes place in the city where they grew up. For example, someone who grew up in Scranton, Pennsylvania, is more likely to watch &lt;a href="https://www.imdb.com/title/tt0386676/" rel="noopener noreferrer"&gt;The Office&lt;/a&gt; than they would otherwise.&lt;/p&gt;

&lt;p&gt;At that time and still to this day, Python was the best choice to test your hypothesis. With its dynamic typing and intuitive syntax, the Python language makes it very easy for data scientists, who are not programmers and understandably have no interest in the ceremony of traditional software engineering, to experiment quickly. With that &lt;br&gt;
growing popularity came the blossoming of a prolific ecosystem. Libraries we take for granted today like Pandas, NumPy, Scikit-learn, spaCy, GLiNER, and countless others emerged with Deep Learning staples like PyTorch and TensorFlow arriving later. Machine learning pipelines using tools like dbt, Dagster, Airflow, and Great Expectations became ubiquitous. Bombshell tooling like Jupyter Notebooks and powerful IDEs &lt;a href="https://www.youtube.com/watch?v=Ihum2Yk3Zyk" rel="noopener noreferrer"&gt;entered the villa&lt;/a&gt;. It is easy to see why the Python ecosystem has been so dominant for so long for running experiments and solving many popular use cases like spam detection, sentiment analysis, fraud detection, loan default prediction, and image classification. There are powerful data science alternatives like R and Julia, but they just don't have the juice.&lt;/p&gt;

&lt;p&gt;When ChatGPT came along in 2022, Python appeared poised to &lt;a href="https://www.youtube.com/watch?v=iVBX7l2zgRw" rel="noopener noreferrer"&gt;become more powerful than you can possibly imagine&lt;/a&gt;. With Python the clear choice for NLP and Deep Learning, AI companies use Python to train Large Language Models (LLMs). If you want to fine tune an existing model to train it for your use case, you use Python tools like &lt;a href="https://unsloth.ai/" rel="noopener noreferrer"&gt;Unsloth&lt;/a&gt;. Naturally, Python also led the way in AI orchestration. As Retrieval Augmented Generation (RAG) became all the rage, &lt;a href="https://www.langchain.com/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt; and &lt;a href="https://www.llamaindex.ai/" rel="noopener noreferrer"&gt;LlamaIndex&lt;/a&gt; inherited the Python pipeline tradition and made it easier to ground LLMs on your own structured and unstructured data. To take things even further, because Python has dominated ML for so long and there have always been so many outstanding ML models, and now AI models, on Hugging Face, core Hugging Face libraries like Transformers are Python libraries. Other approaches like &lt;a href="https://docs.djl.ai/master/docs/demos/huggingface/hybrid/index.html" rel="noopener noreferrer"&gt;Deep Java Library&lt;/a&gt; and &lt;a href="https://docs.spring.io/spring-ai/reference/api/chat/huggingface.html" rel="noopener noreferrer"&gt;Spring AI&lt;/a&gt; are technically possible to work with Hugging Face, but the process is never very straightforward.&lt;/p&gt;

&lt;p&gt;The result was predictable. You can see the surge in Python popularity in various Python language rankings like the August 2025 TIOBE Index, which not only puts Python at #1 but also jumping 8.1% after the last ranking!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipfk0kkf6xpklfjx6tmc.webp" 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%2Fipfk0kkf6xpklfjx6tmc.webp" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, as AI adoption explodes, organizations are butting against the limits of Python for building mission-critical, production software for real users. Python doesn't readily deliver what enterprise AI needs to thrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  In the Real World, ML ≠ AI
&lt;/h2&gt;

&lt;p&gt;It's a vast oversimplification, but machine learning is computation. And to be fair, it's true you need very advanced computations to build LLMs in the first place. But once you have LLMs in place doing real work, generating value from them for your business is not about computation at all.&lt;/p&gt;

&lt;p&gt;It's about &lt;em&gt;context&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The key to success with AI is to provide the best context to the best suited LLM(s) so they can pattern match their way to the best result.&lt;/p&gt;

&lt;p&gt;For you individually, if you are using an LLM to find a job, context means using &lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro" rel="noopener noreferrer"&gt;Model Context Protocol (MCP)&lt;/a&gt; clients like &lt;a href="https://block.github.io/goose/" rel="noopener noreferrer"&gt;Goose&lt;/a&gt; to integrate the job description on a company website and other relevant pages about company strategy and values with the PDF resume on your laptop. That context helps LLMs offer suggestions on what to emphasize in your work history to maximize your chances for an interview. That doesn't require any code from you, Python or otherwise. It's simply knowing which context matters and making it available to AI.&lt;/p&gt;

&lt;p&gt;Similarly for a business, context means gleaning the most relevant information across the enterprise—in databases, Notion, Jira, Slack, GitHub, Salesforce, Dropbox, Confluence, SharePoint, Google Workspace, Office 365, and all the other typical black holes of organizational memory in big companies—to your problem and providing &lt;em&gt;that&lt;/em&gt; to an LLM. This likely requires some code, but it's just API calls to the data and the LLM(s), which software engineers have been doing forever, rather than calculating &lt;a href="https://statisticsbyjim.com/regression/root-mean-square-error-rmse/" rel="noopener noreferrer"&gt;root mean squared error&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Put simply, AI is a context integration challenge not a number crunching challenge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python Limitations
&lt;/h2&gt;

&lt;p&gt;I have a deep appreciation for Python. In fact, it's the language I recommend to people who want to get into programming for the first time for all the same reasons it's so popular with data scientists.&lt;/p&gt;

&lt;p&gt;But there are several reasons why Python never really caught on to solve integration challenges at scale in enterprises:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lack of type safety, which &lt;a href="https://ai.pydantic.dev/" rel="noopener noreferrer"&gt;Pydantic AI&lt;/a&gt;, &lt;a href="https://boundaryml.com/" rel="noopener noreferrer"&gt;BAML&lt;/a&gt;, and other modern AI libraries try to address because it's so important to ground LLMs in structure&lt;/li&gt;
&lt;li&gt;Poor performance of Python at scale, which &lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;FastAPI&lt;/a&gt; and other modern libraries address in limited scope&lt;/li&gt;
&lt;li&gt;Lack of mature middleware options like Kafka integration&lt;/li&gt;
&lt;li&gt;Lack of mature tooling around security, observability, and resiliency &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is an old cliché in software engineering: Use the right tool for the job. The qualities that make Python dominant for ML are irrelevant, even counterproductive, to what you need for AI.&lt;/p&gt;

&lt;p&gt;Python is fine, but it's not the right tool for the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better Choices for AI
&lt;/h2&gt;

&lt;p&gt;If AI is an integration challenge rather than an ML challenge, AI success demands technologies built to solve integration challenges. There are lots of languages whose features, runtimes, and ecosystems&lt;br&gt;
make them far better options than Python:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JVM languages like Java, which has dominated the enterprise for decades, and Kotlin, which is a modern alternative interoperable with Java and currently my favorite language&lt;/li&gt;
&lt;li&gt;.NET languages like C#, which also dominates the enterprise, and F#&lt;/li&gt;
&lt;li&gt;TypeScript, which has emerged very quickly as a popular integration option with libraries like Prisma and tRPC&lt;/li&gt;
&lt;li&gt;Go, built for speed and integrates well with middleware&lt;/li&gt;
&lt;li&gt;Rust, &lt;em&gt;really&lt;/em&gt; built for speed with a devoted, growing community willing to tackle the tough learning curve&lt;/li&gt;
&lt;li&gt;Elixir, niche language but purpose built for scalable, fault tolerant distributed systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your choice depends on all the usual considerations like available talent and skills, deployment constraints, available SDKs, and so on. The key point is you are not limited to Python for AI because of its legacy in ML. You can even do better. You will find higher-level agent frameworks that rival and arguably beat LangChain and LlamaIndex like &lt;a href="https://docs.koog.ai/" rel="noopener noreferrer"&gt;Koog&lt;/a&gt; (Kotlin) and &lt;a href="https://docs.embabel.com/embabel-agent/guide/0.1.2-SNAPSHOT/" rel="noopener noreferrer"&gt;Embabel&lt;/a&gt; (Kotlin and Java) on the JVM, &lt;a href="https://mastra.ai/" rel="noopener noreferrer"&gt;Mastra&lt;/a&gt; in TypeScript, and &lt;a href="https://learn.microsoft.com/en-us/semantic-kernel/overview/" rel="noopener noreferrer"&gt;Semantic Kernel&lt;/a&gt; in C#, Java, and yes, Python. The great thing about these frameworks is they affirm the lessons we have learned about mature software engineering at scale over the last few decades by espousing concepts like type safety, testing, security, Domain-Driven Design, observability, and disaster recovery. While completely unnecessary for data science experiments, these concepts are all crucial for serious software deployed at scale, AI or otherwise.&lt;/p&gt;

&lt;p&gt;Succeeding with AI begins with sound business strategy and data strategy. After that, your technical implementation is a matter of integrating context not performing computations. Solve the right problem with the right solution to maximize your chances for success with AI.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why Types and Tests are Both Essential in Programming</title>
      <dc:creator>Neil Chaudhuri</dc:creator>
      <pubDate>Sun, 05 Mar 2023 15:53:11 +0000</pubDate>
      <link>https://dev.to/neilchaudhuri/why-types-and-tests-are-both-essential-in-programming-4cip</link>
      <guid>https://dev.to/neilchaudhuri/why-types-and-tests-are-both-essential-in-programming-4cip</guid>
      <description>&lt;p&gt;90% of Tech Twitter is the same arguments over and over again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Are engineers being laid off simply not good enough? (No. Layoffs are all but random and serve, along with stock buybacks using all the cash on hand tech companies have, to impress The Street and inflate stock price.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does preference for remote work mean you're lazy? (No. What matters is if your customers are happy and your business is profitable, and your business should enable you to contribute in the easiest way possible for you and your family.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is HTML a programming language? (Who cares? Stop gatekeeping.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is Tailwind CSS a productivity boost or the spawn of Satan? (This is stupid. Mind your business. Use what you like and let others do the same.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should you have more unit tests or integration tests? (Shoot me.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Must you love programming to excel? (No. Don't believe me? Then believe &lt;a href="https://leaddev.com/culture-engagement-motivation/why-flow-matters-more-passion"&gt;Sarah Drasner&lt;/a&gt;, who is smarter than both of us.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another common debate, and one that is more interesting, is whether you should invest in types or tests. It raises some key questions about what makes each valuable, but unfortunately the debate gets lost in the haze of programming language preferences, developer experiences, and other tangential concerns. Still, the answer matters because it's central to improving our process so we can build as efficiently and with the highest quality as possible.&lt;/p&gt;

&lt;p&gt;It turns out you need types &lt;em&gt;and&lt;/em&gt; tests because each solves completely different problems that are both important to you as a developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types automate API integrity at development time
&lt;/h2&gt;

&lt;p&gt;The key components of an API call—whether it's a Java method, a REST endpoint, or a Python function—are the input parameters and the output. There are infinite ways a consumer can interact with your API, but we don't want that.&lt;/p&gt;

&lt;p&gt;Consider an API call that takes first name, last name, and an amount of money parameters with no types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each parameter has literally infinite possible values, so our API forces consumers to be very careful. For example, it's very easy to mix up the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; strings.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;True story: There is a political fundraising apparatus that has switched my first and last names, so every email starts off "Chaudhuri, we need your help!" when they really mean "Neil, we need your help!" It's like my high school coach is yelling at me to donate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even worse, they could mix up one of the string values with the number in the amount. In fact, it's very easy to put garbage of any type into each parameter, and relatively speaking almost all of it is bad. Of course you can paper over the problem in a number of ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intuitive parameter names like I did above&lt;/li&gt;
&lt;li&gt;Logical order for parameters&lt;/li&gt;
&lt;li&gt;Comments or other documentation&lt;/li&gt;
&lt;li&gt;Default values or optionality for parameters (if your programming language has those features)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These things are good as a general matter, but they don't solve the problem. &lt;/p&gt;

&lt;p&gt;We can improve the situation considerably by adding types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have ensured &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; can only be strings and &lt;code&gt;amount&lt;/code&gt; can only be a number. But I know. We can still switch &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt;. We can put a negative number in for amount. Each parameter &lt;em&gt;still&lt;/em&gt; has literally infinite possible values, but we have shrunk the universe of valid inputs immeasurably. &lt;a href="https://en.wikipedia.org/wiki/Perfect_is_the_enemy_of_good"&gt;Don't let perfect be the enemy of good.&lt;/a&gt; This is progress!&lt;/p&gt;

&lt;p&gt;We can tighten up our types further to do even better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Currency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How you do this depends on the features of your programming language. Maybe it has a built-in type already for currency. Or you can define a type with a custom implementation or as simply as a type alias. Regardless of how you get there, look how far we've come. No confusing name with amount. No mixing up names. No improper values for the amount. The tigher our type constraints, the more we make life easier for consumers by narrowing the field of possible values for each parameter. Yes, there are still infinite possible permutations of parameters, but at least it's not "infinite infinite."&lt;/p&gt;

&lt;p&gt;Types constrain our API to limit the universe of possible inputs, and best of all, they work at development time. If API consumers make a mistake by supplying a value outside the type boundary, they are going to hear about it: from the IDE, type checker, compiler, code generator. We all know the faster you find something wrong the easier it is to fix, and nothing works faster than types to all but guarantee the integrity of our APIs. This is the beauty of automating API integrity rather than wasting time as human compilers and static analyzers who inevitably get it wrong. You also get a form of documentation that helps you understand the API just by looking at it.&lt;/p&gt;

&lt;p&gt;As for outputs, constraints on return types are also valuable because as we compose functions, the return value from one call becomes the input to another. Programs are essentially data pipelines of composed functions, so types guarantee the integrity of the entire call chain, which is pretty amazing.&lt;br&gt;
If you maximize the power of types of the values going in and coming out of your API calls, and you then compose them so they fit together like Legos, you have made enormous strides in maximizing the quality of your code without writing a single test.&lt;/p&gt;

&lt;p&gt;But that isn't quite enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests &lt;em&gt;verify&lt;/em&gt; your API behavior at runtime
&lt;/h2&gt;

&lt;p&gt;We've used types to limit the universe of values our API consumers can apply, but how do we know we have done the right thing with them to satisfy our API contract and return what consumers asked for?&lt;/p&gt;

&lt;p&gt;Or more simply, does our code work? This is where tests come in.&lt;/p&gt;

&lt;p&gt;As entire books have been written about testing and you likely already know much about it, I won't spend a lot of time on it here. What matters for this discussion is that while types define APIs in development, tests act at runtime to verify your API behavior with the parameters whose types have &lt;br&gt;
already been guaranteed. Types and tests are &lt;em&gt;complementary&lt;/em&gt;. You need both.&lt;/p&gt;

&lt;h2&gt;
  
  
  So why the controversy?
&lt;/h2&gt;

&lt;p&gt;While it's been around for as long as static and dynamically typed languages have coexisted, in my experience the Types vs. Tests debate blew up fairly recently in the JavaScript community, where more experienced developers in particular were already comfortable acting as human compilers and static analyzers and viewed the emergence of TypeScript with skepticism. After all, types add more verbosity (to varying degrees given your programming language's talent for type inference), and developers hate extra keystrokes. Add to that more work like &lt;code&gt;tsconfig.json&lt;/code&gt; for TypeScript or adding hints or the &lt;code&gt;typing&lt;/code&gt; library in Python and you have a recipe for tension.&lt;/p&gt;

&lt;p&gt;But at the core of the debate is one key question: "Tests can do everything types can do, so why bother with all the ceremony?" &lt;/p&gt;

&lt;p&gt;My view: Nah not really.&lt;/p&gt;

&lt;p&gt;Sure you can fake type safety with tests by enforcing invariants like ensuring &lt;code&gt;amount&lt;/code&gt;, a &lt;code&gt;number&lt;/code&gt; in the second example above, is nonnegative. That isn't &lt;em&gt;actual&lt;/em&gt; type safety though. It's just moving type enforcement from the interface to the implementation, which has disastrous consequences. Like all tests, "type tests" depend on your discipline. You may not write any at all because of deadlines, or you may write bad ones that don't add value. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some might say types demand discipline too. If your types are loose, you don't reap the benefits. That depends on how strongly typed the language is and how effective you are at maximizing the power of its type system. But intentionally widening types is more sabotage than lack of discipline.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You've also shifted type guarantees right, from development time to runtime, and delayed feedback as a result. This makes you slower.&lt;/p&gt;

&lt;p&gt;You know what else makes you slower? You've chosen a manual process over automation. You've sacrificed tooling support and implicit documentation for the chance to waste time doing extra work types do more reliably and cheaply. That's particularly weird since one of the primary objections to types is extra work.&lt;/p&gt;

&lt;p&gt;In the end, substituting types with tests in your code is like substituting &lt;a href="https://www.eonline.com/news/1341657/liam-hemsworth-trolls-perfect-brother-chris-hemsworth-in-marvelous-birthday-tribute"&gt;Chris Hemsworth with his brother Liam&lt;/a&gt; in the cast of your movie. You could do worse but look at how much you've lost in the process. Use types to automate API integrity and tests to verify API behavior &lt;em&gt;together&lt;/em&gt; to build the most reliable and maintainable code in the shortest amount of time.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
      <category>python</category>
    </item>
  </channel>
</rss>
