<?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: Kevin 心学</title>
    <description>The latest articles on DEV Community by Kevin 心学 (@0x1).</description>
    <link>https://dev.to/0x1</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%2F190975%2Fba4081f3-0907-4f29-828b-60c47cf6431f.png</url>
      <title>DEV Community: Kevin 心学</title>
      <link>https://dev.to/0x1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0x1"/>
    <language>en</language>
    <item>
      <title>🐘 TypeScript for PHP? YES, that's possible! And it's not what you think...</title>
      <dc:creator>Kevin 心学</dc:creator>
      <pubDate>Tue, 21 Jul 2026 12:57:51 +0000</pubDate>
      <link>https://dev.to/0x1/typescript-for-php-yes-thats-possible-and-its-not-what-you-think-394f</link>
      <guid>https://dev.to/0x1/typescript-for-php-yes-thats-possible-and-its-not-what-you-think-394f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;It is time to bring opposites together, to stir up these stagnant waters, and to restore an industry that is dynamic from within, with multiple connections that were previously impossible or unimaginable.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;In the previous parts of this series, we explored how &lt;a href="https://dev.to/0x1/a-quiet-rewrite-of-the-web-purescript-on-the-rooftops-of-javascript-c61"&gt;PureScript acts as a quiet rewrite of the Web&lt;/a&gt;, offering a territory of mathematical precision above JavaScript, and how &lt;a href="https://dev.to/0x1/the-ultimate-polymorphism-purescript-as-a-universal-language-5gdi"&gt;its universal polymorphism&lt;/a&gt; allows it to target wildly different runtimes like Node.js, Erlang's BEAM, Python, Go, Scheme, etc.&lt;/p&gt;

&lt;p&gt;But hey, what about the elephant in the room? Yes, what is running the &lt;strong&gt;majority&lt;/strong&gt; of the web, today, in the shadow? You know. The eternal one, the big one, the one whose death everyone talks about, but who never truly dies.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqd8vgeg3usvk2b8viokz.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqd8vgeg3usvk2b8viokz.jpg" alt="Totoro in the shadows" width="456" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PHP.&lt;/p&gt;

&lt;p&gt;While the modern JavaScript ecosystem (among others) races toward edge computing and containerized microservices, around 70% of the web is still &lt;a href="https://medium.com/@harishsingh8529/stop-calling-php-dead-it-runs-70-of-the-internet-ec86749d7f0f" rel="noopener noreferrer"&gt;powered by PHP&lt;/a&gt;. From legacy WordPress sites to affordable shared hosting (cPanel, OVH, GoDaddy, basic LAMP stacks), a &lt;strong&gt;massive portion&lt;/strong&gt; of the internet lives in environments where escaping the PHP runtime is either financially unviable, technically impossible, or simply unnecessary. And I haven't even mentioned powerful and mature ecosystems like Laravel, Symfony, etc. They have proven their worth time and again over the years.&lt;/p&gt;

&lt;p&gt;And yet...&lt;/p&gt;

&lt;p&gt;For a long time, the PHP ecosystem has been left without a true, &lt;strong&gt;strictly typed&lt;/strong&gt; functional and safe alternative, like TypeScript for Javascript. Even though recent PHP versions introduced fantastic features (short closures, match expressions, Fibers), the frustration that comes with its historical limitations and typing remains very real for some of its users.&lt;/p&gt;

&lt;p&gt;Oh yes, there is &lt;a href="https://hacklang.org" rel="noopener noreferrer"&gt;Hack&lt;/a&gt;, and there are phenomenal static analyzers like PHPStan... but Hack eventually required a custom runtime, and PHPStan (as powerful as it is) is ultimately trying to bolt safety onto a fundamentally permissive and imperative language through comments.&lt;/p&gt;

&lt;p&gt;What we are talking about here is a true paradigm shift in safety and ergonomics, keeping the great portability of PHP, as it is.&lt;/p&gt;

&lt;p&gt;Very well!&lt;/p&gt;

&lt;p&gt;This is why I built &lt;strong&gt;&lt;a href="https://github.com/0x000000000000000000001/phpurs" rel="noopener noreferrer"&gt;phpurs&lt;/a&gt;&lt;/strong&gt;: a brand new compiler backend that transpiles PureScript directly to modern PHP 8.4+ syntax.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx90p0skz6enka3tcf11o.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx90p0skz6enka3tcf11o.png" alt="phpurs" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is no longer a proof of concept. It is passing the &lt;a href="https://github.com/purescript/purescript/tree/master/tests/purs/passing" rel="noopener noreferrer"&gt;official PureScript test suite&lt;/a&gt;, and it is ready for production.&lt;/p&gt;

&lt;p&gt;Here is how we bring the elegance of purely functional programming to the big web, while keeping deployment as simple as a legacy FTP upload, or anything alike.&lt;/p&gt;




&lt;h2&gt;
  
  
  The easy deployment paradox
&lt;/h2&gt;

&lt;p&gt;In modern DevOps, deploying an app often means configuring Docker containers, CI/CD pipelines, Kubernetes, or serverless edge functions. It is &lt;strong&gt;powerful&lt;/strong&gt;, but it is expensive and sometimes... a bit too complex for the real need. Let's be clear: I have nothing against it, I use it &lt;strong&gt;every&lt;/strong&gt; day. But it's not always necessary. A website can run just fine on a very &lt;strong&gt;low cost&lt;/strong&gt; server, possibly a &lt;strong&gt;shared&lt;/strong&gt; one, without needing such an arsenal of tools.&lt;/p&gt;

&lt;p&gt;For many freelancers and agencies, the reality is different indeed: clients often have a simple, &lt;strong&gt;small&lt;/strong&gt; and cheap shared hosting plan. They want a robust application, but they don't want to pay for a managed AWS infrastructure.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu1nlihkp349pch1lmjwr.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu1nlihkp349pch1lmjwr.jpg" alt="Small Totoro" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So... &lt;code&gt;phpurs&lt;/code&gt; bridges this gap. It allows you to write your entire business logic, API, and background processes in 100% pure, strictly typed PureScript. And you get all the guarantees of ADTs, pattern matching, the &lt;code&gt;Aff&lt;/code&gt; monad, HKTs... and so much more... &lt;em&gt;(some concepts will be new to some of you: don't be intimidated, they're very practical)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Then, you compile it, and you get plain &lt;code&gt;.php&lt;/code&gt; files. No overhead. The compiler has pruned what the runtime won't need, and &lt;strong&gt;optimized&lt;/strong&gt; everything (e.g. &lt;a href="https://www.stanza.dev/courses/javascript-functional-architecture/recursion/javascript-functional-architecture-tail-recursion" rel="noopener noreferrer"&gt;Tail-Call Optimization&lt;/a&gt;, Dead-Code Elimination, Uncurrying...).&lt;/p&gt;

&lt;p&gt;You just drag and drop these files via FTP to your client's cheap HostGator, OVH server, or whatever... and it works. No container, no daemon, no reverse proxy. Just &lt;strong&gt;native&lt;/strong&gt; execution. &lt;/p&gt;

&lt;p&gt;One of the biggest strengths of PHP is its portability. We leverage it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: standing on the shoulders of giants
&lt;/h2&gt;

&lt;p&gt;In fact, &lt;code&gt;phpurs&lt;/code&gt; doesn't reinvent the entiiiire wheel. It stands on the incredible work of the PureScript community (e.g. Arista's &lt;a href="https://github.com/aristanetworks/purescript-backend-optimizer" rel="noopener noreferrer"&gt;&lt;code&gt;purescript-backend-optimizer&lt;/code&gt;&lt;/a&gt;).&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F00i3pqp2snf18m66l6mn.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F00i3pqp2snf18m66l6mn.png" alt="On the shoulders" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The compilation pipeline is beautifully decoupled:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At first, &lt;code&gt;purs&lt;/code&gt; compiles your code to &lt;code&gt;corefn.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;backend-optimizer&lt;/code&gt; reads this CoreFn and performs aggressive dead code elimination (DCE), inlining, uncurrying, etc.&lt;/li&gt;
&lt;li&gt;At the end, &lt;code&gt;phpurs&lt;/code&gt; takes this highly optimized intermediary AST and prints it as modern PHP syntax. And of course, it will add additional and sophisticated optimizations for PHP's sake.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Concurrency: Aff meets PHP Fibers
&lt;/h2&gt;

&lt;p&gt;One of the biggest historical flaws of PHP was its synchronous, blocking nature. How do you implement PureScript's asynchronous &lt;code&gt;Aff&lt;/code&gt; monad in such an environment?&lt;/p&gt;

&lt;p&gt;Well, PHP 8.1 introduced &lt;a href="https://www.php.net/manual/fr/language.fibers.php" rel="noopener noreferrer"&gt;Fibers&lt;/a&gt;, and the &lt;a href="https://revolt.run" rel="noopener noreferrer"&gt;Revolt&lt;/a&gt; event loop followed.&lt;/p&gt;

&lt;p&gt;Support for &lt;code&gt;Aff&lt;/code&gt; has been &lt;strong&gt;natively&lt;/strong&gt; added to &lt;code&gt;phpurs&lt;/code&gt;. The behavior of the event loop in the compiled PHP code perfectly mirrors its Node.js counterpart: asynchronous operations are handled transparently without blocking the OS thread. The main process will automatically wait for all pending &lt;code&gt;Aff&lt;/code&gt; tasks to complete before exiting, for example. &lt;/p&gt;

&lt;p&gt;You can seamlessly run your code with a JS runtime, or a PHP one. You can even &lt;a href="https://github.com/0x000000000000000000001/b8x.pub/tree/main#-runtime-agnostic-in-the-real-world" rel="noopener noreferrer"&gt;switch from one to another&lt;/a&gt;, when you're coding.&lt;/p&gt;

&lt;p&gt;There is &lt;strong&gt;no need&lt;/strong&gt; for complex daemonized C or Go extensions like Swoole or FrankenPHP. By relying exclusively on native PHP Fibers and asynchronous libraries (like Amphp), &lt;code&gt;phpurs&lt;/code&gt; ensures that your concurrent PureScript code can run natively &lt;em&gt;anywhere&lt;/em&gt; PHP runs. It &lt;a href="https://github.com/0x000000000000000000001/b8x.pub/blob/7069afe6d39a041d18fc6cb4a8d3fd1cc2d9ae96/src/Inter/Api/_/Main.purs#L106" rel="noopener noreferrer"&gt;just works&lt;/a&gt;, and handles multiple requests, like a good ol' Express server in Node.&lt;/p&gt;




&lt;h2&gt;
  
  
  Moving complexity from runtime to comptime
&lt;/h2&gt;

&lt;p&gt;In standard PHP or JS development, safety often comes at the cost of &lt;strong&gt;defensive programming&lt;/strong&gt; at runtime: checking boolean flags, instantiating heavy wrapper classes, or placing &lt;code&gt;if (!$form-&amp;gt;isValid()) throw new Exception(...)&lt;/code&gt; checks throughout your domain logic.&lt;/p&gt;

&lt;p&gt;Like TypeScript, PureScript &lt;strong&gt;flips&lt;/strong&gt; this paradigm. But it goes &lt;strong&gt;further&lt;/strong&gt;, with a powerful Hindley-Milner type system. Once the PureScript compiler validates your logic, the underlying compiled PHP is freed from defensive checks, leaving a trivial, lightning-fast execution path.&lt;/p&gt;

&lt;p&gt;For example, consider a form processing pipeline where you must guarantee that data is validated before saving it to a database. Using Phantom Types, we can tag the state of our data (&lt;code&gt;Unchecked&lt;/code&gt; vs &lt;code&gt;Checked&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- 1. Phantom Types&lt;/span&gt;
&lt;span class="c1"&gt;--    They exist ONLY for the compiler, zero runtime cost.&lt;/span&gt;
&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Unchecked&lt;/span&gt;
&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Checked&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&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;age&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="c1"&gt;-- 2. Construction: Creates an `Unchecked` form&lt;/span&gt;
&lt;span class="n"&gt;createForm&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="kt"&gt;Unchecked&lt;/span&gt;
&lt;span class="n"&gt;createForm&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;-- 3. Smart Constructor.&lt;/span&gt;
&lt;span class="c1"&gt;--    Only validation transforms `Unchecked` into `Checked`&lt;/span&gt;
&lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="kt"&gt;Unchecked&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&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;FormData&lt;/span&gt; &lt;span class="kt"&gt;Checked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Pattern&lt;/span&gt; &lt;span class="s"&gt;"@"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;
  &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="s"&gt;"Invalid form data"&lt;/span&gt;

&lt;span class="c1"&gt;-- 4. Database operation ONLY accepts a `FormData Checked`!&lt;/span&gt;
&lt;span class="n"&gt;saveToDb&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="kt"&gt;Checked&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Effect&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt;
&lt;span class="n"&gt;saveToDb&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is mathematically &lt;strong&gt;impossible&lt;/strong&gt; to call &lt;code&gt;saveToDb&lt;/code&gt; with unvalidated data (&lt;code&gt;FormData Unchecked&lt;/code&gt;). If you try, the compiler halts with a type error before any code is ever generated.&lt;/p&gt;

&lt;p&gt;In PHP, we could translate what's above into something like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. We must define wrapper classes and mutable state flags&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nv"&gt;$isValidated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;// ⚠️ Runtime state to track!&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="c1"&gt;// 2. Construction: creates an "unchecked" form&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// We instantiate a real class object in memory&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Validation mutates the state or throws Exceptions&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;str_contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Invalid form data"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ⚠️ Runtime defensive throw&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;isValidated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ⚠️ Runtime mutation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 4. Database operation MUST defensively check the state&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;saveToDb&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FormData&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ⚠️ Defensive check at runtime: did the developer call validate() before?&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;isValidated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Security error: Data not validated!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ... &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, advanced PHP developers might say they could use strict Value Objects (creating a separate ValidatedFormData class) or advanced PHPStan docblocks to avoid the boolean flag. And they'd be completely right. I did it too, for years. &lt;/p&gt;

&lt;p&gt;But Value Objects add memory allocations and mapping &lt;strong&gt;overhead at runtime&lt;/strong&gt;, while PHPStan only enforces safety through comments, not rock-solid compiler guarantees. More generally speaking, existing solutions are often smart compromises.&lt;/p&gt;

&lt;p&gt;PureScript gives you the &lt;strong&gt;best of both worlds&lt;/strong&gt;: strict, mathematically proven safety at compile-time, that compiles down to raw, zero-overhead unboxed objects at runtime. I simplified it for the example, but now, look at the compiled PHP code &lt;code&gt;phpurs&lt;/code&gt; outputs for the entire pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Creating a `FormData Unchecked` simply returns a raw PHP object.&lt;/span&gt;
&lt;span class="c1"&gt;//    The `FormData` newtype wrapper is completely unboxed!&lt;/span&gt;
&lt;span class="nv"&gt;$createForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"age"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Validation checks the raw data and wraps it in `Right`.&lt;/span&gt;
&lt;span class="c1"&gt;//    No state classes or newtypes are instantiated!&lt;/span&gt;
&lt;span class="nv"&gt;$validate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$formData&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;str_contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$formData&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Data1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Right"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$formData&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Data1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Left"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Invalid form data"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Database save has ZERO defensive checks (no `$data-&amp;gt;isValidated`)&lt;/span&gt;
&lt;span class="c1"&gt;//    PureScript guaranteed 100% safety at compile-time.&lt;/span&gt;
&lt;span class="nv"&gt;$saveToDb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Zero defensive runtime overhead&lt;/strong&gt;. No boolean flags, no &lt;code&gt;try/catch&lt;/code&gt; blocks, no dynamic state assertions inside &lt;code&gt;$saveToDb&lt;/code&gt;. &lt;br&gt;
&lt;strong&gt;Zero object allocations&lt;/strong&gt;: the Phantom Types (&lt;code&gt;Unchecked&lt;/code&gt;/&lt;code&gt;Checked&lt;/code&gt;) and &lt;code&gt;FormData&lt;/code&gt; newtype wrapper don't instantiate any PHP classes. At runtime, &lt;code&gt;$formData&lt;/code&gt; is just a plain, raw PHP object seamlessly passed from &lt;code&gt;$createForm&lt;/code&gt; to &lt;code&gt;$saveToDb&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Complexity lives strictly &lt;strong&gt;in the compiler&lt;/strong&gt;. What runs on your host is &lt;strong&gt;clean&lt;/strong&gt; and &lt;strong&gt;fast&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  What about performance?
&lt;/h2&gt;

&lt;p&gt;It would be a legitimate question. For example, PHP is often criticized for its raw execution speed compared to V8 (Node.js).&lt;/p&gt;

&lt;p&gt;In raw micro-benchmarks, PHP 8 is indeed about 2 to 3 times slower than V8 for heavy computational tasks. However, in the vast majority of real-world web applications, the main bottleneck is &lt;strong&gt;I/O&lt;/strong&gt; (database, network, filesystem). &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm0d242bxuyccbrlepj14.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm0d242bxuyccbrlepj14.jpg" alt="Running Totoro" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The difference in performance is entirely &lt;strong&gt;negligible&lt;/strong&gt; in practice. You lose almost nothing in speed, but you gain the ability to deploy your code on any server in the world for pennies.&lt;/p&gt;

&lt;p&gt;I recently battle-tested &lt;code&gt;phpurs&lt;/code&gt; against the test suite of a &lt;a href="https://github.com/0x000000000000000000001/b8x.pub/tree/main#fullstack-purescript-architecture-a-public-poc" rel="noopener noreferrer"&gt;real-world project&lt;/a&gt; (still a WIP, but the code is mature). The results are &lt;strong&gt;clear&lt;/strong&gt;: in practice, it is &lt;strong&gt;only&lt;/strong&gt; x1.15 slower. Of course, the value of this factor will depend on your very specific project(s). But remember: PHP is not the preferred backend for performance, it is for portability.&lt;/p&gt;


&lt;h2&gt;
  
  
  What about interoperability? The entire PHP ecosystem at your fingertips
&lt;/h2&gt;

&lt;p&gt;You might be thinking: &lt;em&gt;"This is great, but do I have to rewrite the entire world in PureScript? What about my existing PHP libraries, the AWS SDK, the Symfony components I rely on... ?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fear not. PureScript has always been designed with a very pragmatic approach to the outside world, and &lt;code&gt;phpurs&lt;/code&gt; fully embraces this philosophy through its &lt;strong&gt;Foreign Function Interface (FFI)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You are not locked in a pure, isolated bubble. If you need to use a powerful, battle-tested PHP library, you can easily bind it to your PureScript code. The bridge between the two worlds is incredibly straightforward: you simply declare the type signature in PureScript, and provide the implementation in a standard &lt;code&gt;.php&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- In PureScript: src/Crypto.purs&lt;/span&gt;
&lt;span class="c1"&gt;-- We declare the function and its type&lt;/span&gt;
&lt;span class="n"&gt;foreign&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;hashPassword&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Effect&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In PHP: src/Crypto.php&lt;/span&gt;
&lt;span class="c1"&gt;// We implement the runtime behavior&lt;/span&gt;
&lt;span class="nv"&gt;$hashPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;callable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;password_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;PASSWORD_BCRYPT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all it takes. This simple mechanism allows you to tap into the gigantic Packagist ecosystem. You can &lt;strong&gt;leverage&lt;/strong&gt; Symfony's HttpFoundation, Laravel's Eloquent ORM, Guzzle... anything, while keeping the core of your domain logic purely functional and mathematically proven. &lt;/p&gt;

&lt;p&gt;Moreover, since the compiled output is just standard PHP, it plays perfectly well with Composer. This means you can &lt;strong&gt;incrementally introduce&lt;/strong&gt; PureScript into an existing, massive legacy codebase. No need for a Big Bang rewrite: you can start by migrating your most critical, bug-prone business logic first, and let it interact seamlessly with your existing PHP architecture. In &lt;strong&gt;both directions&lt;/strong&gt;: your PureScript modules can seamlessly tap into your existing Composer dependencies via FFI, and/or your legacy PHP codebase can simply require the compiler's output (i.e. PureScript code compiled into PHP code) to execute your newly written functions. &lt;/p&gt;




&lt;h2&gt;
  
  
  The next frontier
&lt;/h2&gt;

&lt;p&gt;I am &lt;strong&gt;already using it&lt;/strong&gt; in production for several client projects with strictly PHP-only environments, and the runtime stability is rock solid (and super fast). 🟢&lt;/p&gt;

&lt;p&gt;Pure dev pleasure, with pragmatic client constraints. Getting the best of both worlds is a very, very pleasant feeling.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo75s5fkr7p2hv3v56l5r.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo75s5fkr7p2hv3v56l5r.jpg" alt="Happy Totoro" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Community contributions are highly welcome! If you want to help add missing PHP FFIs to core and major PureScript libraries, your PRs are more than welcome.&lt;/p&gt;

&lt;p&gt;Let's bring the elegance of PureScript to the 70% of the web that still runs on PHP! 🐘&lt;/p&gt;

&lt;p&gt;Cheers 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: A huge thanks to PHP Weekly for &lt;a href="https://phpweekly.com/archive/2026-07-24.html" rel="noopener noreferrer"&gt;featuring this post&lt;/a&gt;! That's a delightful surprise. I'm really glad to see this approach resonating with the PHP community!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/0x000000000000000000001/phpurs" rel="noopener noreferrer"&gt;&lt;strong&gt;The Compiler&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/0x000000000000000000001/b8x.pub#-runtime-agnostic-in-the-real-world" rel="noopener noreferrer"&gt;&lt;strong&gt;PureScript Fullstack example, able to run on PHP runtime&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>typescript</category>
      <category>purescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🌈 The ultimate polymorphism: PureScript as a universal language (Node's V8, Erlang's BEAM, Chez Scheme...)</title>
      <dc:creator>Kevin 心学</dc:creator>
      <pubDate>Sun, 21 Jun 2026 13:12:49 +0000</pubDate>
      <link>https://dev.to/0x1/the-ultimate-polymorphism-purescript-as-a-universal-language-5gdi</link>
      <guid>https://dev.to/0x1/the-ultimate-polymorphism-purescript-as-a-universal-language-5gdi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Just as PureScript has &lt;strong&gt;expanded&lt;/strong&gt; into the backend after having long been assigned to the frontend (in people's minds), it is now spreading to all areas of programming. It’s a &lt;strong&gt;polymorphic&lt;/strong&gt; language that can target Erlang for concurrency, Chez Scheme for raw speed, etc. Here is why it works.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;A few months ago, I wrote an article about how PureScript serves as a &lt;a href="https://dev.to/0x1/a-quiet-rewrite-of-the-web-purescript-on-the-rooftops-of-javascript-c61"&gt;"quiet rewrite of the Web"&lt;/a&gt;, allowing developers to build robust, mathematically sound applications on the rooftops of JavaScript’s chaotic empire. &lt;/p&gt;

&lt;p&gt;But as I delved deeper into the ecosystem, a profound realization hit me: &lt;strong&gt;I could have written the exact same article&lt;/strong&gt; by replacing the word "JavaScript" with "Erlang", or "C++", or "Chez Scheme", etc. Not all languages: some aren't dense or powerful enough, others are currently being explored (e.g. WASM). But quite a few! In fact, often the ones having a very, very interesting runtime. JavaScript is a special case, as it is notoriously more controversial. But the principle is the same.&lt;/p&gt;

&lt;p&gt;In fact, and with a slightly broader definition, PureScript does not only &lt;em&gt;support&lt;/em&gt; powerful polymorphism in its type system. &lt;strong&gt;The language itself is polymorphic.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Let's pause for a second. What exactly is polymorphism in programming?&lt;/p&gt;

&lt;p&gt;At its core, and to simplify things a bit, polymorphism allows a single piece of code to adapt its behavior depending on the data it receives. Take a simple polymorphic function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Type "a" is generic.&lt;/span&gt;
&lt;span class="c1"&gt;-- In real code, we'd add the constraint "Show a =&amp;gt;"&lt;/span&gt;
&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Data: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;

&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;       &lt;span class="c1"&gt;-- Int context.&lt;/span&gt;
                 &lt;span class="c1"&gt;-- Returns 'Data: 42'&lt;/span&gt;
                 &lt;span class="c1"&gt;-- as if the signature was: &lt;/span&gt;
                 &lt;span class="c1"&gt;-- process :: Int -&amp;gt; String&lt;/span&gt;

&lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;  &lt;span class="c1"&gt;-- String context.&lt;/span&gt;
                 &lt;span class="c1"&gt;-- Returns 'Data: "Hello"'&lt;/span&gt;
                 &lt;span class="c1"&gt;-- as if the signature was: &lt;/span&gt;
                 &lt;span class="c1"&gt;-- process :: String -&amp;gt; String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function doesn't exist as a single, rigid block of code. Instead, the function will take the right shape at the very moment you call it: either the shape for integers, or the shape for strings. It is the context that defines what the function actually is.&lt;/p&gt;

&lt;p&gt;It's the exact same thing for PureScript itself, as a whole. &lt;strong&gt;Its nature can change depending on your context of use&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;It turns out that PureScript is quietly solving the holy grail of software engineering, the "&lt;strong&gt;Write Once, Run Anywhere&lt;/strong&gt;" promise, by succeeding exactly where older cross-platform languages (like Haxe) hit a glass ceiling. Not just inside the code, in some parts, but with the code &lt;strong&gt;itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is how, and more importantly, &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choose your morph (without changing your logic)
&lt;/h2&gt;

&lt;p&gt;If you think PureScript is just "Haskell for the browser", you may be missing one of the biggest paradigm shifts of the decade. Besides its unique features (e.g. Row polymorphism), and thanks to its unique architecture, PureScript compiles your code into an &lt;strong&gt;intermediate&lt;/strong&gt;, mathematically pure abstract syntax tree called &lt;code&gt;CoreFn&lt;/code&gt;. This tree can be transpiled into (almost) anything which is sufficiently powerful to understand it, and translate it in its own terms. That's &lt;strong&gt;philosophically&lt;/strong&gt; close to WASM, even though it deals with a completely different topic: you define a &lt;strong&gt;universal&lt;/strong&gt; layer, to facilitate the translation work everywhere else.&lt;/p&gt;

&lt;p&gt;From there, the community has built alternative backends that allow you to &lt;strong&gt;deploy&lt;/strong&gt; your identical business logic to &lt;strong&gt;radically different&lt;/strong&gt; physical realities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You want top-tier web UI and Node.js efficiency?&lt;/strong&gt; 
Keep the default compiler or use &lt;a href="https://github.com/aristanetworks/purescript-backend-optimizer" rel="noopener noreferrer"&gt;purs-backend-es&lt;/a&gt; for highly-optimized ECMAScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want massive telecom-grade concurrency and 99.99999% uptime?&lt;/strong&gt; 
Transpile to the BEAM (Erlang VM) using &lt;a href="https://github.com/purerl/purerl" rel="noopener noreferrer"&gt;purerl&lt;/a&gt;. You get the legendary resilience of Elixir/Erlang actors, but with absolute compile-time type safety.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want raw, bare-metal computing speed for heavy algorithms?&lt;/strong&gt; 
Transpile to Scheme using &lt;a href="https://github.com/purescm/purescm" rel="noopener noreferrer"&gt;purescm&lt;/a&gt;, which leverages the formidable Chez Scheme compiler to come very close to C/C++/Rust-level performance on recursive and computational tasks (thanks to 30 years of research by Cisco).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your core domain (your algorithms, parsers, state machines, and business rules) &lt;strong&gt;does not change by a single comma&lt;/strong&gt;. Yes: not, a, single, comma. &lt;/p&gt;

&lt;p&gt;Of course, your target language can and should influence what PureScript will offer to be transpiled into it. And the level of abstraction and generality given by PureScript is directly the one of Category Theory: you will almost certainly find the right tool for each problem. That's a permanently bidirectional dialogue between the two sides, maintained by great developers from the community. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;E.g. &lt;code&gt;Aff&lt;/code&gt; will be translated into &lt;code&gt;async/await&lt;/code&gt; in JS, or &lt;code&gt;Revolt&lt;/code&gt; and &lt;code&gt;Fiber&lt;/code&gt; internals in PHP.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Haxe paradox: Why did it stall?
&lt;/h2&gt;

&lt;p&gt;This "compile to anything" promise sounds familiar. In the 2000s and 2010s, languages like Haxe tried to be the ultimate Swiss Army knife, compiling to C++, Java, PHP, and JS. While Haxe became a massive success in the indie gaming industry (shoutout to &lt;em&gt;Dead Cells&lt;/em&gt;), it never conquered the mainstream backend or frontend world. &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgwkmvlqf5t2hgpezta5l.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgwkmvlqf5t2hgpezta5l.gif" alt="Morph looking confused and overwhelmed by a complex situation" width="500" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why? Because of the &lt;strong&gt;Lowest Common Denominator Syndrome&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Haxe is an Object-Oriented, imperative language. It tried to abstract the world by forcing its own Standard Library onto every target. When you compiled Haxe to C++, you didn't get idiomatic, lightning-fast C++: you got C++ weighed down by a Haxe garbage collector. When you compiled to JS, you got a heavy runtime overhead. You lost the native superpowers of the target platform. &lt;/p&gt;

&lt;p&gt;Furthermore, from a paradigm perspective, Haxe offered nothing that Java, C#, or TypeScript didn't already have. Why use a cross-platform layer when native tools do OOP better?&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8cyrnrmaeu2prt4egjpn.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8cyrnrmaeu2prt4egjpn.gif" alt="Morph sighing and dropping an object, looking counterproductive" width="500" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Haxe felt counterproductive for some. It may have suffered from &lt;a href="https://en.wikipedia.org/wiki/Esperanto" rel="noopener noreferrer"&gt;Esperanto&lt;/a&gt; syndrome. A universal system must include its parts without replacing them (not blindly, at least), so that it can grow alongside them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The PureScript epistemology: purity as a boundary
&lt;/h2&gt;

&lt;p&gt;PureScript succeeds where Haxe stalled because it adopts a radically different philosophy: &lt;strong&gt;Symbiosis through Purity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PureScript does not try to replace the native ecosystem. It fully respects it. And it grows with it.&lt;br&gt;
Because PureScript is strictly mathematically pure, its compiler doesn't need to inject a heavy "PureScript Virtual Machine" into the target code. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Cost Abstraction:&lt;/strong&gt; PureScript Arrays compile to native JS Arrays. PureScript Strings are native Strings. The integration is seamless.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The FFI Philosophy:&lt;/strong&gt; PureScript knows it cannot do database I/O or DOM manipulation natively. Instead of faking a universal HTTP library that runs poorly everywhere, the culture encourages you to use platform-specific Foreign Function Interfaces (FFI). &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You write your business logic once, in 100% pure code. Then, you plug in the right FFI. And don't worry about rewriting the world from scratch: the core kernels and standard bindings have already been written by the community for each runtime! And for libs: if you target Node.js, you plug in &lt;code&gt;purescript-node-postgres&lt;/code&gt;, if you target Erlang, you plug in &lt;code&gt;purescript-erl-epgsql&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: the ultimate alchemy
&lt;/h2&gt;

&lt;p&gt;The dilemma of hybrid technologies is the risk of creating a gray mush, a tool that &lt;strong&gt;loses&lt;/strong&gt; the qualities of both its parents. In software engineering, attempting to support everything often results in a mediocre middle ground: a language that is not as fast as C, as expressive and safe as Haskell, etc. &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F942svbsv0jgaz9wtclw0.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F942svbsv0jgaz9wtclw0.gif" alt="Morph transforming into a muddy and useless gray spoon" width="400" height="224"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Don't worry. In this case, the spoon is shaped like mud, but it's just that PureScript might play a prank on you!&lt;/em&gt; 😉&lt;/p&gt;

&lt;p&gt;In reality, being in the middle should not necessarily imply losing quality. PureScript completely avoids this gray mush by refusing to mix the substances until the very last second. It takes the absolute mathematical rigor of Haskell (substance A) and respectfully marries it to the &lt;strong&gt;omnipresence&lt;/strong&gt; of V8, the &lt;strong&gt;resilience&lt;/strong&gt; of BEAM, or the &lt;strong&gt;speed&lt;/strong&gt; of Scheme (substance B). The substances remain as they are, they just work together so closely that one can still speak of hybridization. &lt;/p&gt;

&lt;p&gt;No matter what the people who encounter your product prioritize (speed, safety, concurrency...), you can now rest easy and know your language inside and out.&lt;/p&gt;

&lt;p&gt;Needless to say, no single runtime is perfect for everything. In practice, PureScript acts as the unified, overarching language for your entire project, but your transpilation targets can differ from one folder to another. That is the whole point: every pillar of your architecture gets its &lt;strong&gt;own privileged runtime&lt;/strong&gt;. For instance, your background workers and core algorithms can be transpiled to Chez Scheme for raw, bare-metal speed; your real-time WebSocket brokers can compile to Erlang's BEAM for flawless, distributed concurrency; and your user-facing API can run on highly-optimized Node.js.&lt;/p&gt;

&lt;p&gt;It is not a downward compromise. PureScript is an epistemological little friend that &lt;strong&gt;protects your code, your thinking&lt;/strong&gt;, from the chaos of the outside world, while letting you choose the exact engine you want to power it. It's &lt;strong&gt;made for that&lt;/strong&gt;. It isn't afraid of movement. It encourages you to use the best runtime for your goal, without having to learn yet another language, right now. &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63bpxai4k04987wh2dmz.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63bpxai4k04987wh2dmz.gif" alt="Morph flying happily around, showing agility and freedom" width="600" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But wait, if you have a Node.js API, a Chez Scheme worker, and an Erlang broker, how do they &lt;strong&gt;communicate&lt;/strong&gt; safely? In a traditional microservices architecture, you would immediately reach for gRPC and Protobuf to enforce a strict, language-agnostic contract between these radically different environments. &lt;/p&gt;

&lt;p&gt;Here is the magic of a runtime-agnostic language: &lt;strong&gt;PureScript itself is your contract.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Because your entire architecture shares the &lt;strong&gt;same PureScript domain types&lt;/strong&gt;, you get the absolute safety of gRPC combined with the developer comfort of a TypeScript monorepo. Whether your containers communicate synchronously via simple HTTP or asynchronously via RabbitMQ, they serialize and deserialize JSON payloads using the exact same PureScript definitions. The compiler guarantees that all your microservices speak the &lt;strong&gt;exact same language&lt;/strong&gt;, eliminating an entire class of distributed system bugs without any heavy external schema configuration. In this paradigm, gRPC is relegated to being a pure performance optimization for extreme high-throughput binary transport. It becomes entirely unnecessary for 99% of projects.&lt;/p&gt;

&lt;p&gt;The quiet rewrite of the web is expanding, but it does not stop at the browser window. It is coming for distributed systems, heavy data pipelines, and bare-metal computations. By allowing developers to decouple their business domain from the physical execution engine, PureScript is silently &lt;strong&gt;shifting&lt;/strong&gt; the power dynamics of software architecture. &lt;/p&gt;

&lt;p&gt;We no longer have to compromise between safety and performance. We just have to choose the right form for the right environment.&lt;/p&gt;

&lt;p&gt;It’s a &lt;strong&gt;long-term endeavor&lt;/strong&gt;, underway on all fronts: academic and theoretical, as well as practical and industrial. But it’s an endeavor in which the progress made has now become so significant that it allows us to (re)discover &lt;strong&gt;the joy of doing this craft&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Say &lt;em&gt;Hello&lt;/em&gt; to your little polymorph, say &lt;em&gt;Hello&lt;/em&gt; to PureScript.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbm46alymsgjecvoya4go.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbm46alymsgjecvoya4go.gif" alt="Morph waving hello enthusiastically" width="480" height="240"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;P.S. Oh, and I almost forgot: a little concrete code never hurts! If you want to see what a production-ready PureScript project looks like in practice, check out this example repository, when our little polymorphic friend wants to take the form of Node.js by day and PHP by night:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/0x000000000000000000001/b8x.pub#-runtime-agnostic-in-the-real-world" rel="noopener noreferrer"&gt;&lt;strong&gt;PureScript Fullstack example (Node or PHP, whatever the runtime)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also find a multi-runtime benchmark here:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/0x000000000000000000001/altbak.pub" rel="noopener noreferrer"&gt;&lt;strong&gt;Purescript universal multi-runtime benchmark&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>erlang</category>
      <category>scheme</category>
      <category>purescript</category>
    </item>
    <item>
      <title>🍄 The End of Developers in 2026? Elon Musk is right... but wrong.</title>
      <dc:creator>Kevin 心学</dc:creator>
      <pubDate>Mon, 09 Mar 2026 15:02:27 +0000</pubDate>
      <link>https://dev.to/0x1/zero-developers-in-2026-musk-is-right-but-wrong-1nm2</link>
      <guid>https://dev.to/0x1/zero-developers-in-2026-musk-is-right-but-wrong-1nm2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;AI can generate code. But code is not just syntax: it’s a language for thinking about systems. It’s time to clarify why.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In recent years, discussions about software development automation have multiplied. Some technology leaders, such as Elon Musk, claim that developers could &lt;strong&gt;disappear&lt;/strong&gt;. At first glance, this idea seems radical: if AI can generate code from simple natural language instructions, why would we still need developers? It could generate machine binaries too.&lt;/p&gt;

&lt;p&gt;Yet this reasoning relies on a very narrow definition of code, where code is seen purely as a translation process, an intermediate step in a production chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Natural human idea --Developer--&amp;gt; Code --Compiler--&amp;gt; Phenomenon in the machine world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ν --Δ--&amp;gt; C --Κ--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we all know that AI (Α) and the compiler (Κ) help us in writing code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ν --Δ+Α+Κ--&amp;gt; C --Κ--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this sense, coding is only about transforming human ideas into executable binary instructions. On this ground, Musk is probably right: many repetitive or syntactic implementation tasks could indeed be automated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ν --Α+Κ--&amp;gt; C --Κ--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And AI could even do a better job than any compiler (as he said himself). So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ν --Α+Κ--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok… that may happen to a lot of companies. Musk may be right.&lt;/p&gt;

&lt;p&gt;Note that in this picture, we've &lt;strong&gt;lost control&lt;/strong&gt;. We cannot see what's going on in the machine… Because that was one of the many advantages of traditional code. Right? But anyway, that's another topic.&lt;/p&gt;

&lt;p&gt;Let's discuss another aspect of things, and see where Musk is wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Missing Definition
&lt;/h2&gt;

&lt;p&gt;These debates are very often truncated by a cut (sometimes accidental, sometimes deliberate) in the definitional scope of what we call "code".&lt;/p&gt;

&lt;p&gt;Let us put aside announcements, speculative interests, and stock prices for a moment, and &lt;strong&gt;focus&lt;/strong&gt; instead on the &lt;strong&gt;definition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In my experience with functional programming (which I have studied for two years), I (re)discovered another dimension of code. Something absolutely essential.&lt;/p&gt;

&lt;p&gt;Here, coding primarily means &lt;strong&gt;formalizing an idea&lt;/strong&gt;, modeling a domain, &lt;strong&gt;expressing&lt;/strong&gt; invariants, and &lt;strong&gt;structuring&lt;/strong&gt; a complex system. In this perspective, code becomes an intermediate symbolic language, a &lt;strong&gt;tool for thought&lt;/strong&gt;, &lt;strong&gt;not&lt;/strong&gt; merely a translation to the machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code as Maths
&lt;/h2&gt;

&lt;p&gt;In FP, code is absolutely not reduced to a translative layer from one language to another, from one world to another. It is an &lt;strong&gt;extensive layer of language itself&lt;/strong&gt;. It is then transpiled (e.g. PureScript → JavaScript).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ν --Δ+Α+Τ--&amp;gt; Σ --Τ--&amp;gt; C --Κ--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here comes the difference. We cannot prune the chain the same way we did before (i.e. remove Δ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ν --Α+Τ--&amp;gt; Σ --Τ--&amp;gt; C --Κ--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? Because Σ is a &lt;strong&gt;extension&lt;/strong&gt; of Ν. Not a translation, not another shape, not another physicality we give to a substance. This is the substance itself, going further: Σ &amp;gt; N. It is there to express what Ν cannot express. And guess who does the expression job? Δ. The delta. The difference. The added value. The developer. &lt;/p&gt;

&lt;p&gt;AI &lt;strong&gt;cannot&lt;/strong&gt; generate human knowledge &lt;strong&gt;outside&lt;/strong&gt; of humanity. If AI generates Σ autonomously, with tangible results, humans will be interested in knowing them. They will want to know the formula, the symbols that are useful to manipulate reality. There will always be Bob, to check a generated idea. His Σ will then become his new N, and a new cycle of territory extension will begin. It will give him more power on reality. And people who have been ignoring their Σ (letting it to AI) will try to imitate Bob's one, will learn his Σ (which became his N). His Σ will become the new N, for everyone. AI will never generate an everlasting and independent Σ, with no human to catch up with it. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that these assumptions are based on an &lt;strong&gt;ideal world&lt;/strong&gt;, where AI is truly capable of validating its Σ ideas. Current practice shows something different. It can barely iterate through several validation cycles by attaching itself to your browser to validate the visual reality of your website. It is impressive, but it is still imperfect. And it is pure 2D virtuality. Nothing to do with reality and 3D-world human stakes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There will always be Σ. There will always be the need to compress ideas or express something new and interesting for the rest of humanity. We need someone to understand the move: that will not come from the entirety of the group, at the same time. Experts are, in my humble opinion, &lt;strong&gt;consubstantial&lt;/strong&gt; to humans. They will always be there. As long as Ν exists, Σ will exist. &lt;/p&gt;

&lt;p&gt;Ν is indeed a social convention. It can grow, it can extend its limits. And Σ is in fact one of the many special corners of Ν. Like math vocabulary, like biology vocabulary… Ν and Σ are two faces of the &lt;strong&gt;same cube&lt;/strong&gt;, and cannot be dissociated. We can invent, with AI help (but only help, by definition), ways of expressing intuitions of Ν into Σ, or vulgarize Σ into Ν. But Ν and Σ are none of AI's real business; they are the very core of human ideas, desires, viewpoints, and knowledge. And they work hand in hand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Ν &amp;lt;~~Δ+Α+Τ~~&amp;gt; Σ] --Τ--&amp;gt; C --Κ--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Σ is richer than English N. More compact, declarative, and precise than traditional code C (it focuses on &lt;em&gt;what&lt;/em&gt;, not &lt;em&gt;how&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;In Musk’s world, companies will add value if they bring Ν in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ν --Α--&amp;gt; Μ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The more efficient they are in providing Ν and helping Α to translate, the more they will succeed. That's why we see numerous tutorials to help us speak to AI, in a sort of infinitely recursive (and sometimes absurd) loop. Just to improve the final Ν in the chain. Of course, the diagram goes far beyond something linear, and becomes indigestible (and costly).&lt;/p&gt;

&lt;p&gt;But.&lt;/p&gt;

&lt;p&gt;Us humans will still persist information within groups, and make tech companies, to produce Μ. In the FP chain, we can play on Σ, not Ν. That is necessary to add value.&lt;/p&gt;

&lt;p&gt;Here, should we call Σ "code"? In my opinion, yes. Because it is not Ν, it is not C or Μ. It is technical, read on screen. It just not the traditional intermediary layer it used to be.&lt;/p&gt;

&lt;p&gt;Eliminating code, in this respect, would mean reducing the added value. This is obviously not what the industry prefers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code as Expression
&lt;/h2&gt;

&lt;p&gt;It is here that expression becomes central to the modern definition of code. Code is no longer just translation. It is the terrain for expressing particular ideas, with a strong &lt;strong&gt;epistemological dimension&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is exactly what languages like Haskell or Rust enable: code becomes almost an executable &lt;strong&gt;specification&lt;/strong&gt; rather than a mere sequence of instructions. The ability to model and formalize is far more resistant to automation than simple syntax writing.&lt;/p&gt;




&lt;h2&gt;
  
  
  The AI Wave
&lt;/h2&gt;

&lt;p&gt;In other words, your "protection" against the AI wave lies in your ability to think and formalize a problem correctly. If your language gives you that power, this is the way to go.&lt;/p&gt;

&lt;p&gt;Musk is both right and wrong.&lt;/p&gt;

&lt;p&gt;He is right with the &lt;strong&gt;traductive&lt;/strong&gt; flavour of code definition.&lt;/p&gt;

&lt;p&gt;He is wrong with the &lt;strong&gt;expressive&lt;/strong&gt; flavour of code definition.&lt;/p&gt;

&lt;p&gt;The good news is that in this expressive sense, the role of developers remains &lt;strong&gt;central&lt;/strong&gt;. It simply changes in nature. I am inclined to think that this reasoning can and should extend beyond FP.&lt;/p&gt;

&lt;p&gt;The rules have changed. But human, expression and "code" are &lt;strong&gt;still&lt;/strong&gt; at the heart of the game. &lt;/p&gt;

&lt;p&gt;In the AI village, you'll never be the fool.&lt;/p&gt;




&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/bWIms21MybA"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>programming</category>
      <category>haskell</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🪽 A quiet rewrite of the Web: PureScript on the rooftops of JavaScript</title>
      <dc:creator>Kevin 心学</dc:creator>
      <pubDate>Mon, 27 Oct 2025 13:14:11 +0000</pubDate>
      <link>https://dev.to/0x1/a-quiet-rewrite-of-the-web-purescript-on-the-rooftops-of-javascript-c61</link>
      <guid>https://dev.to/0x1/a-quiet-rewrite-of-the-web-purescript-on-the-rooftops-of-javascript-c61</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;JavaScript became more than code: a culture, a dynasty, a paradox. In the shadow of this legacy, a bold team embarked on an athletic, and deeply inspiring adventure: rewriting everything…&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;For over decades, web developers have lived in a &lt;strong&gt;love–hate&lt;/strong&gt; relationship with JavaScript, and this has &lt;strong&gt;affected&lt;/strong&gt; their own &lt;strong&gt;sense of community&lt;/strong&gt;, with internal disagreements turning into verbal altercations, sometimes brutal and cruel.&lt;br&gt;
These are the facts. We &lt;a href="https://cscalfani.medium.com/breaking-free-of-javascript-c4b6fae152c3" rel="noopener noreferrer"&gt;criticize it&lt;/a&gt;, we &lt;a href="https://dev.to/pamoffice/why-this-cto-thinks-javascript-is-the-worst-programming-language-hm5"&gt;mock&lt;/a&gt; it, we &lt;a href="https://dev.to/yukinisihikawa/i-built-jetscript-a-new-javascript-like-language-for-solo-founders-indie-hackers-and-educators-1pe2"&gt;reinvent&lt;/a&gt; it, and yet, we often (if not always) &lt;strong&gt;come back&lt;/strong&gt;, partially or not.&lt;br&gt;
Because, deep down, &lt;strong&gt;the web &lt;em&gt;is&lt;/em&gt;&lt;/strong&gt; JavaScript (or almost): the &lt;em&gt;lingua franca&lt;/em&gt; of the browser, the keystone of everything that runs inside a tab.&lt;/p&gt;

&lt;p&gt;And yet… between the endless &lt;code&gt;undefined is not a function&lt;/code&gt;, the inconsistent APIs, and the jungle of an evergrowing ecosystem (which can sometimes be overwhelmed by his proposals), it’s &lt;strong&gt;hard&lt;/strong&gt; to &lt;strong&gt;find a line&lt;/strong&gt; of reasoning that makes lasting sense.&lt;br&gt;
So we look for escapes: CoffeeScript yesterday, TypeScript today, Elm or Reason for the boldest.&lt;/p&gt;

&lt;p&gt;And now… there’s &lt;strong&gt;&lt;a href="https://www.purescript.org" rel="noopener noreferrer"&gt;PureScript&lt;/a&gt;&lt;/strong&gt;, a quiet language (but one of rare elegance).&lt;/p&gt;

&lt;p&gt;I know I know, you may be suffering from &lt;a href="https://medium.com/loop-of-thought/javascript-fatigue-was-supposed-to-end-it-didnt-833352bea8f2" rel="noopener noreferrer"&gt;JS fatigue&lt;/a&gt;, like I was (“&lt;em&gt;oh, more promotion from an official team member, infiltrating dev.to…&lt;/em&gt;”), and you’re thinking that it’s irrelevant to come up with yet another thing in this saturated universe.&lt;/p&gt;

&lt;p&gt;But.&lt;/p&gt;

&lt;p&gt;I am a freelance developer, and I do not do any promotion.&lt;/p&gt;

&lt;p&gt;That’s when things &lt;strong&gt;start to take a turn&lt;/strong&gt; toward something completely &lt;strong&gt;different&lt;/strong&gt;. It’s not just a thing, a tool, a framework, a bundler… or even a mere language. It’s a &lt;strong&gt;parallel universe&lt;/strong&gt;, both independent and connected, which stands on the shoulders of profound epistemological mathematics. We’ll get back to that.&lt;/p&gt;


&lt;h2&gt;
  
  
  JavaScript, the Dynastic Dystopia
&lt;/h2&gt;

&lt;p&gt;Let’s face it: &lt;strong&gt;JavaScript has won&lt;/strong&gt;.&lt;br&gt;
It reigns over the web like a dynasty: (almost) uncontested, omnipresent, eternal.&lt;br&gt;
From browsers to servers, from build tools to mobile apps, a lot of things eventually bends to its rule.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/3jfI-z__GY0"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;But it’s a dynasty with a dystopian flavor: a vast, prosperous empire, yet inherently unstable.&lt;br&gt;
Each new framework promises order and simplicity, but also sows significant additional chaos. Nothing seems to be completely resolved. This is probably what contributes to such dynamism, but it is also what can unnecessarily exhaust some people.&lt;br&gt;
Dependencies &lt;strong&gt;multiply&lt;/strong&gt;, paradigms &lt;strong&gt;collide&lt;/strong&gt;, and peace always seems one &lt;code&gt;npm install&lt;/code&gt; &lt;strong&gt;away&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can’t leave this empire, the web is its territory. It holds up, and &lt;strong&gt;it does the job&lt;/strong&gt;, which is no small feat (far from it). And no one is rude enough to claim that there isn’t wonder in many places within this ecosystem.&lt;br&gt;
So what remains?&lt;br&gt;
The art of &lt;strong&gt;navigating&lt;/strong&gt; it: creating your own bubble of confidence, and diving into it fully, without fear.&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%2Fcljbso01hy24m3cbth55.jpg" 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%2Fcljbso01hy24m3cbth55.jpg" alt="Rooftops" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;Purescript&lt;/strong&gt; comes in.&lt;/p&gt;


&lt;h2&gt;
  
  
  PureScript: Haskell for the Great Web (and more)
&lt;/h2&gt;

&lt;p&gt;PureScript is a purely functional language (strongly) inspired by Haskell, compiling down to plain and optimized JavaScript. As such, it encapsulates all the power of &lt;a href="https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface" rel="noopener noreferrer"&gt;Category Theory&lt;/a&gt; (remaining dev-oriented), and still can run on browsers, desktop (e.g. Electron), backend (Node), etc.&lt;br&gt;
&lt;em&gt;N.b. Because the subtleties of Node's Event Loop are misunderstood or disliked by non-JS devs, Haskell is sometimes preferred for backend purposes. PureScript has now made these subtleties much easier to handle.&lt;/em&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strong static typing&lt;/strong&gt;, everything is checked before runtime.
Functional purity, no hidden side effects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readable, efficient output&lt;/strong&gt;, no black magic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Powerful type inference&lt;/strong&gt;, the compiler often knows your intentions before you finish typing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Algebraic data types and pattern matching&lt;/strong&gt;, express complex logic elegantly and safely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effect system&lt;/strong&gt;, explicit control over side effects, concurrency, and async behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensible records and row polymorphism&lt;/strong&gt;, flexible data structures without sacrificing type safety.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typed foreign function interface (FFI)&lt;/strong&gt;, seamless bridges between PureScript and JavaScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem synergy&lt;/strong&gt;, works hand-in-hand with frameworks like Halogen, React Basic, or Concur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small, composable abstractions&lt;/strong&gt;, build large systems from simple, predictable parts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mathematically grounded&lt;/strong&gt;, category theory isn’t decoration here; it’s the backbone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform by nature&lt;/strong&gt;, browser, Node.js, Deno, Electron, Cloudflare Workers, it just runs.&lt;/li&gt;
&lt;li&gt;And… so much more. It’s another world…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PureScript lets you reason about your code with mathematical &lt;strong&gt;precision&lt;/strong&gt;, while still building modern, reactive, performant apps.&lt;/p&gt;

&lt;p&gt;It’s the &lt;strong&gt;Hextech gem&lt;/strong&gt; from &lt;a href="https://www.netflix.com/title/81435684" rel="noopener noreferrer"&gt;the Arcane series&lt;/a&gt;, the &lt;strong&gt;philosopher’s stone&lt;/strong&gt;, allowing clarity to emerge from a world saturated with conflicting forces.&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%2Fnnlcsf11dlfkaizdpllh.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%2Fnnlcsf11dlfkaizdpllh.webp" alt="Jinx and the Hextech" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Writing JavaScript without suffering from it
&lt;/h2&gt;

&lt;p&gt;Take asynchronous effects, for example.&lt;/p&gt;

&lt;p&gt;In JavaScript, Promises are convenient but quickly spiral out of control, nested callbacks, silent errors, ghost exceptions.&lt;br&gt;
In PureScript, effects (&lt;code&gt;Effect&lt;/code&gt;, &lt;code&gt;Aff&lt;/code&gt;) are &lt;strong&gt;described and typed explicitly&lt;/strong&gt;.&lt;br&gt;
No more partial functions. The compiler &lt;strong&gt;knows&lt;/strong&gt; when you’re touching the outside world, and makes you handle it properly.&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%2Fdwbrqjnnwaqnyrgp2e7p.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%2Fdwbrqjnnwaqnyrgp2e7p.png" alt="Purescript" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And yet, you’re &lt;strong&gt;still within&lt;/strong&gt; the JS ecosystem: you can import npm libraries, use React through Halogen or React Basic, or even handcraft JS interop directly. You’re not lost.&lt;/p&gt;

&lt;p&gt;PureScript doesn’t flee the dynastic dystopia: it &lt;strong&gt;reveals islands of long-lasting structure&lt;/strong&gt; within it, and ensures their sustainability, development, promotion, expansion, and scaling.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Art of Compromise: Purity without the Ivory Tower
&lt;/h2&gt;

&lt;p&gt;One of the most compelling aspects of PureScript is that it does &lt;strong&gt;not&lt;/strong&gt; force you to &lt;strong&gt;pick a side&lt;/strong&gt;.&lt;br&gt;
You do &lt;strong&gt;not&lt;/strong&gt; have to choose &lt;strong&gt;between&lt;/strong&gt; the &lt;em&gt;pure, safe, and elegant&lt;/em&gt; and the &lt;em&gt;flexible, fast, and pragmatic&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;PureScript offers a genuine &lt;strong&gt;compromise&lt;/strong&gt;, perhaps the smartest one seen around this duality.&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%2Fe6x1fp8ujbs26bl49gcm.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%2Fe6x1fp8ujbs26bl49gcm.webp" alt="Ivory tower" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’ll let you write everything you love about functional programming (strong typing, purity, composition…), but I won’t lock you in an ivory tower.&lt;br&gt;
If you want to use JS libraries, APIs, or even write some JS yourself, you can.&lt;br&gt;
Just declare a foreign import in one line.&lt;br&gt;
I want you to do things because you understand why, not because I force you to.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isn’t a weak compromise, it’s a &lt;strong&gt;collaboration between two worlds&lt;/strong&gt;.&lt;br&gt;
You don’t sacrifice native safety or pragmatic flexibility, you make them &lt;strong&gt;work together&lt;/strong&gt; through anti-corruption layers.&lt;/p&gt;

&lt;p&gt;There’s no need to throw away your JS experience or deny your love of functional purity.&lt;br&gt;
You can do &lt;strong&gt;both&lt;/strong&gt;, and this &lt;em&gt;&lt;strong&gt;upward&lt;/strong&gt; hybridization&lt;/em&gt; is deeply promising: the very best of both world is kept intact.&lt;br&gt;
No &lt;em&gt;downward mixing&lt;/em&gt;, no sacrifice, no ideological war between paradigms: just a fluid membrane, allowing the boundary to shift, sometimes to 100% PureScript, sometimes close to 100% JS, if you feel so.&lt;/p&gt;

&lt;p&gt;Instead of turning the table upside down, PureScript ensures &lt;strong&gt;continuity&lt;/strong&gt;, compatibility, and a transition without violence.&lt;br&gt;
You could write X(&amp;lt; 100)% of your code in PureScript, and the rest in JS &lt;strong&gt;without guilt or pressure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s a rare philosophy: a language that values not just purity, but &lt;strong&gt;maturity&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Conclusion: the Web as a playground, not a prison
&lt;/h2&gt;

&lt;p&gt;JavaScript has become the &lt;strong&gt;universal runtime&lt;/strong&gt;. You can’t escape it.&lt;br&gt;
And that’s perfectly fine, as long as you can really choose &lt;strong&gt;how&lt;/strong&gt; to enter it.&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%2Fb4s7wtjj3218g4hicm9k.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%2Fb4s7wtjj3218g4hicm9k.png" alt="Jinx torch" width="799" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TypeScript tries to make JS less dangerous by adding safeguards. And we can thank it for that.&lt;br&gt;
PureScript, on the other hand, comes from a different world, the purely functional one, and &lt;strong&gt;builds a bridge&lt;/strong&gt; to JS. There is no interference, no hidden language design isomorphism, no subconscious mental pollution.&lt;/p&gt;

&lt;p&gt;It took me almost 2 years to understand a satisfactory portion of these lands, even in its most remote regions. I read almost every night on this. This is not a small episode: it is an endless series, full of academic work in progress. In any case, the front door is now increasingly easier to &lt;strong&gt;open&lt;/strong&gt;, thanks to &lt;a href="https://discourse.purescript.org/t/new-purescript-book-functional-programming-made-easier/2390" rel="noopener noreferrer"&gt;high-quality courses&lt;/a&gt; made by enthusiasts, and what seemed impossible yesterday has become reality today.&lt;/p&gt;

&lt;p&gt;PureScript &lt;strong&gt;offers&lt;/strong&gt; a rare path to achieve your ends with JS: to harness its power without inheriting its potential chaos, to turn its flexibility in a plain quality, to create without betrayal, and to rediscover the joy of writing code where every line &lt;strong&gt;does what it says&lt;/strong&gt;, and &lt;strong&gt;says what you think&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/y_fB0IMbq54"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>haskell</category>
      <category>functional</category>
      <category>purescript</category>
    </item>
  </channel>
</rss>
