<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>Frédéric van der Essen</title>
	<subtitle>Essays by Frédéric van der Essen</subtitle>
	
	<link href="https://frederic.vanderessen.com/feed/feed.xml" rel="self"/>
	<link href="https://frederic.vanderessen.com"/>
	<updated>2026-02-08T00:00:00Z</updated>
	<id>https://frederic.vanderessen.com</id>
	<author>
		<name>Frédéric van der Essen</name>
		<email>fvdessen@gmail.com</email>
	</author>
	
	<entry>
		<title>Unsupervised Codebase Refactoring: How To, What Works and What Doesn&#39;t</title>
		<link href="https://frederic.vanderessen.com/posts/unsupervised-refactoring/"/>
		<updated>2026-02-08T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/unsupervised-refactoring/</id>
		<content type="html">&lt;p&gt;Could code refactoring become a one-click operation, like running a formatter but&lt;br /&gt;
for architecture ? Split the bloated files, untangle the responsibilities, deduplicate&lt;br /&gt;
the logic, and come back to a clean codebase ?&lt;/p&gt;
&lt;p&gt;So I ran an experiment. I pointed Opus 4.6 at a 60K line Go microservice I had&lt;br /&gt;
vibe coded over the past few months, gave it some refactoring principles, and let it&lt;br /&gt;
run unsupervised. Two hours and 43 euros later, it had produced 22 commits across 46&lt;br /&gt;
files, changing 11,174 lines of code.&lt;/p&gt;
&lt;h2 id=&quot;the-codebase&quot; tabindex=&quot;-1&quot;&gt;The codebase &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/unsupervised-refactoring/#the-codebase&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The service itself is nothing out of the ordinary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A CRUD REST api backed by a postgres database, defined by openapi specs and autogenerated&lt;/li&gt;
&lt;li&gt;A few pages of server side rendered html&lt;/li&gt;
&lt;li&gt;An asynchronous job dispatcher backed by sqs queues and lambda executors&lt;/li&gt;
&lt;li&gt;REST api clients for various third party and internal services, also autogenerated&lt;/li&gt;
&lt;li&gt;Business logic orchestrating all of the above&lt;/li&gt;
&lt;li&gt;An exhaustive unit test suite&lt;/li&gt;
&lt;li&gt;Terraform infrastructure in the same repository&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since I didn&#39;t know Go before starting this project, and since vibe coding tends&lt;br /&gt;
to make one a bit lazy, the overall code quality was not stellar. Some files grew too&lt;br /&gt;
big, some types took on too many responsibilities, some logic was duplicated, etc, etc.&lt;/p&gt;
&lt;h2 id=&quot;the-technique&quot; tabindex=&quot;-1&quot;&gt;The technique &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/unsupervised-refactoring/#the-technique&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I used the &lt;a href=&quot;https://ghuntley.com/ralph/&quot;&gt;Ralph&lt;/a&gt; technique. The agent is ran in a loop&lt;br /&gt;
where at each step it will either plan a set of tasks, or pick one task and work on it.&lt;br /&gt;
This allows you to run Claude unsupervised on tasks bigger than one session can handle.&lt;/p&gt;
&lt;p&gt;The same prompt is used at every step:&lt;/p&gt;
&lt;div class=&quot;wide-code small-code&quot;&gt;
&lt;pre class=&quot;language-markdown&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;#&lt;/span&gt; REFACTORING.md&lt;/span&gt;

Hello, we are about to refactor this codebase to cleanup the code. Here&#39;s the plan of action.

  &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token list punctuation&quot;&gt;1.&lt;/span&gt; Read the whole code of the repository.
  &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token list punctuation&quot;&gt;2.&lt;/span&gt; Read the TASKS.md file if it exists.
      &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.1. If it exists and is not empty, pick a refactoring task from the list. Choose the most appropriate.
          &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.1.1. Refactor the code according to the task description.
          &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.1.2. Commit the changes to git.
          &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.1.3  Remove the task from TASKS.md
          &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.1.4. You are done. Do NOT pick and process another task.
      &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.2. If it doesn&#39;t exist or is empty:
          &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.2.1. Identify the parts of the code that could be refactored, following the following principles
              &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; A class should have a single responsibility
              &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; The dependencies of the class should be mockable and injected at class instantiation
              &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Repeated code should be factored into functions
              &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; Files shouldn&#39;t be longer than 1.5K lines
          &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.2.2: If using the previous insights you think there is valuable refactoring work to be done:
              &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.2.2.1 Write a list of refactoring tasks in TASKS.md
              &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.2.2.2: You are done.
          &lt;span class=&quot;token list punctuation&quot;&gt;-&lt;/span&gt; 2.2.3: If there is no more refactoring to be done, notify me with &#39;say &quot;I am done with refactoring&quot;&#39;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There&#39;s some important things to note about this prompt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We load the whole application code into the context before doing anything. This not&lt;br /&gt;
only gives the model a global understanding of the code, but since it does one task at&lt;br /&gt;
a time, it will always have the latest version of the code in its context.&lt;/li&gt;
&lt;li&gt;The refactoring principles are explicitly listed, and I knew beforehand that those&lt;br /&gt;
were pain points where meaningful work could be done.&lt;/li&gt;
&lt;li&gt;The AI is left free to choose which task it wants to work on. This is important&lt;br /&gt;
because the model is smart enough to identify the dependencies between the tasks, and&lt;br /&gt;
those evolve as the code gets refactored.&lt;/li&gt;
&lt;li&gt;When the task list is emptied, the agent builds a new set of tasks. It&#39;s the AI&#39;s&lt;br /&gt;
job to decide when it&#39;s done, when there is nothing left to refactor.&lt;/li&gt;
&lt;li&gt;Each step is concluded by a git commit, which helps reviewing the massive amount of&lt;br /&gt;
code change this will generate.&lt;/li&gt;
&lt;li&gt;I didn&#39;t specify anything regarding running the unit tests since I know from&lt;br /&gt;
experience that Claude will do that on its own unprompted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I then ran this prompt in a loop using the following script. It looks a bit more complex&lt;br /&gt;
than it really is. It just runs Claude Code in yolo mode in a loop. The large &lt;code&gt;jq&lt;/code&gt; part is&lt;br /&gt;
there to parse the json event stream and print it in a humanly readable way.&lt;/p&gt;
&lt;div class=&quot;wide-code small-code&quot;&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;trap&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;exit 0&#39;&lt;/span&gt; INT

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;n&#92;n&#92;n ============ STEP ============ &#92;n&#92;n&#92;n&#39;&lt;/span&gt;
  claude --dangerously-skip-permissions &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt; --output-format stream-json &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Read and follow the instructions in ./REFACTORING.md&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/dev/null &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    jq &lt;span class=&quot;token parameter variable&quot;&gt;-rj&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;
      if .type == &quot;assistant&quot; then
        (.message.content[]? |
          if .type == &quot;text&quot; and (.text | length) &gt; 0 then
            .text
          elif .type == &quot;tool_use&quot; then
            &quot;&#92;n&gt;&gt;&gt; &#92;(.name): &#92;(.input.file_path // .input.command // .input.pattern // &quot;&quot;) &amp;lt;&amp;lt;&amp;lt;&#92;n&quot;
          else
            empty
          end)
      elif .type == &quot;result&quot; then
        &quot;&#92;n&#92;n=== Done (turns: &#92;(.num_turns), cost: $&#92;(.total_cost_usd)) ===&#92;n&quot;
      else
        empty
      end
    &#39;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&quot;what-it-did&quot; tabindex=&quot;-1&quot;&gt;What it did &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/unsupervised-refactoring/#what-it-did&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is a sample of the changes, roughly in the order they were made:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Split big files into smaller and meaningfully named ones&lt;/li&gt;
&lt;li&gt;Split types into more focused ones&lt;/li&gt;
&lt;li&gt;Regrouped the various html rendering functions into a PageRenderer type&lt;/li&gt;
&lt;li&gt;Fixed a circular dependency&lt;/li&gt;
&lt;li&gt;Extracted data constants into external json files&lt;/li&gt;
&lt;li&gt;Refactored the html templates to use common templates&lt;/li&gt;
&lt;li&gt;Introduced helper functions to deduplicate repeated logic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The ordering was sound, it tackled the high-impact structural changes first, then&lt;br /&gt;
moved to progressively smaller improvements. It ran the build and unit tests before&lt;br /&gt;
every commit, leaving a clean and workable history. The git commit messages were&lt;br /&gt;
also top notch.&lt;/p&gt;
&lt;p&gt;And the fact that it only added 49 lines total while changing 11,174 shows that what&lt;br /&gt;
it did was truly refactoring. Deduplicating logic removes code, splitting types adds&lt;br /&gt;
some, and it struck a good balance.&lt;/p&gt;
&lt;h2 id=&quot;what-it-missed&quot; tabindex=&quot;-1&quot;&gt;What it missed &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/unsupervised-refactoring/#what-it-missed&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are some refactoring tasks I wished it had identified and fixed but hasn&#39;t.&lt;br /&gt;
Although I&#39;m quite sure it would be able to do those if prompted specifically.&lt;/p&gt;
&lt;p&gt;One example is the logging. Logs need to include contextual data, so that data needs&lt;br /&gt;
to be passed around to the log call site. If done via function arguments, this&lt;br /&gt;
unnecessarily bloats the function signatures. You can fix that by introducing logger&lt;br /&gt;
objects that can hold that data, and then only the logger instance needs to be passed.&lt;/p&gt;
&lt;p&gt;Introducing this pattern would have been an excellent refactoring for this codebase,&lt;br /&gt;
but it wasn&#39;t picked. The quality of the output is bounded by the specificity of the&lt;br /&gt;
refactoring concerns in the prompt. General principles like &lt;em&gt;single responsibility&lt;/em&gt;&lt;br /&gt;
get you general improvements. If you want the agent to tackle a specific architectural&lt;br /&gt;
smell, you need to name it.&lt;/p&gt;
&lt;h2 id=&quot;what-went-wrong&quot; tabindex=&quot;-1&quot;&gt;What went wrong &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/unsupervised-refactoring/#what-went-wrong&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At some point in the code, we re-fetch some database records immediately before doing&lt;br /&gt;
a write to avoid updating from stale data. It decided those calls were unnecessary and&lt;br /&gt;
removed them.&lt;/p&gt;
&lt;p&gt;That is not entirely the fault of the model as there were no comments explaining this,&lt;br /&gt;
the calls were not in a transaction as they should have been, and there were no unit&lt;br /&gt;
tests covering this case. It was not just slop, it was a loaded footgun.&lt;/p&gt;
&lt;p&gt;I caught it because I reviewed each commit individually, and because I was aware of&lt;br /&gt;
that fragile section of the code. If I hadn&#39;t, it would have gone to production.&lt;/p&gt;
&lt;p&gt;This is the thing with unsupervised refactoring. The agent can encounter your existing&lt;br /&gt;
footguns and pull the trigger. Bang!&lt;/p&gt;
&lt;h2 id=&quot;what-made-it-possible&quot; tabindex=&quot;-1&quot;&gt;What made it possible &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/unsupervised-refactoring/#what-made-it-possible&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I think there are some key elements that made this possible at all:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This service was of reasonable size and all its code was in a single repository&lt;br /&gt;
cleanly separated from the other services.&lt;/li&gt;
&lt;li&gt;There was extensive unit test coverage.&lt;/li&gt;
&lt;li&gt;There was a good &lt;code&gt;AGENTS.md&lt;/code&gt; file that gave the necessary context to understand&lt;br /&gt;
the application.&lt;/li&gt;
&lt;li&gt;The interfaces with other services are not defined as code but as static yaml files,&lt;br /&gt;
giving confidence that the interfaces were left untouched by the refactor.&lt;/li&gt;
&lt;li&gt;I had already identified beforehand the issues with the existing code and could steer&lt;br /&gt;
the agent in that direction.&lt;/li&gt;
&lt;li&gt;The original code, while not perfect, was not a vibe coded disaster either.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/unsupervised-refactoring/#conclusion&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My dream, starting this experiment, was that I could then put this process in a CI&lt;br /&gt;
pipeline action, so that every engineer of the company could just press the &lt;em&gt;refactor&lt;/em&gt;&lt;br /&gt;
button when code was bad, and that code refactoring would become a solved problem just&lt;br /&gt;
like automated code formatting.&lt;/p&gt;
&lt;p&gt;We&#39;re not there yet. Two things are missing.&lt;/p&gt;
&lt;p&gt;You need to give direction. The refactoring principles are specific to each project&#39;s&lt;br /&gt;
goals and technology choices. You could encode them in an &lt;code&gt;AGENTS.md&lt;/code&gt;, but there is no&lt;br /&gt;
universal &lt;em&gt;make my codebase clean&lt;/em&gt; prompt. Someone who understands the code still needs&lt;br /&gt;
to identify what clean means for that codebase.&lt;/p&gt;
&lt;p&gt;And the agent doesn&#39;t know when to stop. As iterations went on, the changes became less&lt;br /&gt;
and less meaningful and less and less focused on the criteria in the prompt. The agent&lt;br /&gt;
wants to be helpful, so at every step it will find work to do, even past the point&lt;br /&gt;
where it makes any sense. I have seen this behavior in many other unsupervised agentic coding&lt;br /&gt;
experiments, and I would love to hear your solutions for that problem.&lt;/p&gt;
&lt;p&gt;Still, the model did in about two hours what would have taken me much longer in any&lt;br /&gt;
other way. Even with the time required for reviewing the changes, this was a huge&lt;br /&gt;
productivity win. In most cases the limiting factor on refactoring is the engineering&lt;br /&gt;
time available to do it, and being able to do it faster can only increase the quality&lt;br /&gt;
of our code bases.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>My Programming Job Has Become An Intelligence Buying Job</title>
		<link href="https://frederic.vanderessen.com/posts/programming-is-now-buying-intelligence/"/>
		<updated>2026-02-06T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/programming-is-now-buying-intelligence/</id>
		<content type="html">&lt;p&gt;I have been programming for more than 20 years. 20 years of learning how to translate&lt;br /&gt;
thought into code. 20 years of trying to master an editor to be fast at it. 2025 was the year&lt;br /&gt;
when I wrote my last piece of code. AI is now better at it than I am and ever will be. It&lt;br /&gt;
is not just better at writing code, it is better at architecting, debugging, designing, documenting,&lt;br /&gt;
deciding trade-offs. It is now smarter than I am.&lt;/p&gt;
&lt;p&gt;This is not something easy to accept, and I have been trying to rethink my relation with my job&lt;br /&gt;
and my computer into something that makes sense for the future.&lt;/p&gt;
&lt;p&gt;The key is that intelligence is now a commodity. It was for a long time a luxury product with a time&lt;br /&gt;
based limited supply. But it is now just a matter of spending money. You can now get unlimited&lt;br /&gt;
amount of intelligence if you are willing to spend the money on the tokens.&lt;/p&gt;
&lt;p&gt;Let me take a practical example. At whichever place I was working at, the quality of the codebase has&lt;br /&gt;
always been a point of contention. It is bad ! We should refactor ! But we never had the time.&lt;/p&gt;
&lt;p&gt;Yesterday evening I made a small ralph loop with a prompt to refactor and improve the quality of a&lt;br /&gt;
microservice. &lt;em&gt;Read the whole code base, identify the pain points based on the following criteria, make&lt;br /&gt;
a set of tasks, and work on the tasks&lt;/em&gt; (the real prompt was more involved). Then I let Opus 4.6 run&lt;br /&gt;
on that prompt until it ran out of tokens.&lt;/p&gt;
&lt;p&gt;It worked. It vastly improved the code base, made clean commits, and did that entirely unsupervised.&lt;br /&gt;
I then could, if I wanted, run this ralph loop in parallel on every one of the 250 services at my company,&lt;br /&gt;
and completely clean up our whole code base for less than a day of prompting. But also for $10,000 of&lt;br /&gt;
tokens.&lt;/p&gt;
&lt;p&gt;So the question that was &lt;em&gt;do we have the time to do it&lt;/em&gt;, has become &lt;em&gt;is it worth the money to do it&lt;/em&gt;.&lt;br /&gt;
And who decides ? Currently it&#39;s a long discussion with various managers and the finance department.&lt;br /&gt;
But I think eventually, engineers will have to be trusted with making these decisions on their own,&lt;br /&gt;
and I believe that is going to be our job in the future, being the ones responsible for the billing lines&lt;br /&gt;
in the token expense list.&lt;/p&gt;
&lt;p&gt;And as the impact of the engineer&#39;s decisions scales, so do the risks. Is it wise to deploy 100,000 lines&lt;br /&gt;
of changes ? Who knows what they really contain ? In the past, this risk was mitigated by careful review&lt;br /&gt;
by the engineer&#39;s peers. But this new scale makes it completely impractical. New types of AI powered&lt;br /&gt;
guardrails will need to be put in place, which might just be a matter of automating the existing process of&lt;br /&gt;
review, deploy, monitor and fix. But I think that once again, engineers will need to be trusted&lt;br /&gt;
with a much higher degree of risk-reward economic decisions.&lt;/p&gt;
&lt;p&gt;In a sense this can be an exciting development, but I can also see around me many engineers who have&lt;br /&gt;
taken comfort in taking tasks from a Jira board and simply turning that into code. I think the days&lt;br /&gt;
of &lt;em&gt;that&lt;/em&gt; job are numbered.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>AI Writes Code Fast, Human Reviewers Can&#39;t Keep Up</title>
		<link href="https://frederic.vanderessen.com/posts/ai-codes-fast-humans-cant-keep-up/"/>
		<updated>2025-11-06T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/ai-codes-fast-humans-cant-keep-up/</id>
		<content type="html">&lt;img src=&quot;https://frederic.vanderessen.com/img/waiting.png&quot; /&gt;
&lt;p&gt;The diagram above approximately represents the process I have to go through to complete a&lt;br /&gt;
programming task at work. This is the result of using the standard workflow that GitHub and Gitlab&lt;br /&gt;
recommend. Which means picking up an issue, making some code changes, creating a merge request for&lt;br /&gt;
these changes, and getting the CI checks, and approval from my colleagues, before it is merged and&lt;br /&gt;
automatically deployed.&lt;/p&gt;
&lt;p&gt;As you can see the process is grossly inefficient, most of the time on a task is spent waiting, either&lt;br /&gt;
for the CI or for code reviews. The first reason for this state of affairs is that the&lt;br /&gt;
coding part used to take a lot more time. When the coding was done by hand it would take me a whole 8h&lt;br /&gt;
to get 500 lines of code out, now with agentic coding, I can get 1000 lines in an hour. The CI and review&lt;br /&gt;
waiting times were acceptable overheads, but now they&#39;re the bulk of the &amp;quot;work&amp;quot;.&lt;/p&gt;
&lt;p&gt;The second reason is that the code review back and forth is by itself an extremely inefficient process.&lt;br /&gt;
You do not know when you will get a review, and just one nitpick wastes a whole dev cycle.&lt;/p&gt;
&lt;p&gt;The fact that code reviews are inefficient is not new, and there are different strategies to go around them.&lt;br /&gt;
On one hand you have pair programming and mob programming where the code is looked at by multiple people before&lt;br /&gt;
it is even pushed. On the other hand you have reviews &lt;em&gt;after merge&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In review after merge process, the code is merged first, and reviews come later, with the review fixes implemented&lt;br /&gt;
in new coding tasks. The go&lt;/p&gt;
&lt;p&gt;Manual pre-merge reviews achieve multiple goals in one single gatekeeping step. They&lt;br /&gt;
check for regressions and critical defects, but also long term maintainability and knowledge sharing among devs. With&lt;br /&gt;
the right tooling and unit test coverage, the check for regressions and critical defects can be automated, leaving only&lt;br /&gt;
the discussions about long term maintainability and knowledge sharing as manual tasks. And there&#39;s nothing that critical&lt;br /&gt;
about those that require blocking the merge.&lt;/p&gt;
&lt;p&gt;In a review after merge process, the code is merged first, and reviews come later, with the changes implemented&lt;br /&gt;
in new coding tasks. This means the original merge request is not blocked, and does not need multiple rebases&lt;br /&gt;
and CI that are likelier to happen the longer the request is stuck in review. This seems like the most&lt;br /&gt;
promising way to solve our efficiency problem for agentic coding, but the unfortunate part is that this requires appropriate&lt;br /&gt;
tooling and neither Github nor its alternatives have put the appropriate tooling in place.&lt;/p&gt;
&lt;p&gt;But even adopting post merge review might not entirely solve the problem, simply because a single dev can now&lt;br /&gt;
generate more code than can be humanly reviewed by the rest of the team. Maybe we should start to review prompts&lt;br /&gt;
instead ?&lt;/p&gt;
&lt;p&gt;I can say I am a bit surprised, given how much work is being done to speed up the code generation that&lt;br /&gt;
Github and co keep pushing a merge workflow so obsolete that it is now the main bottleneck in development work.&lt;br /&gt;
In the meantime if you have any solution I would be happy to hear about it in the comments.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>The Human Only Public License</title>
		<link href="https://frederic.vanderessen.com/posts/hopl/"/>
		<updated>2025-10-16T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/hopl/</id>
		<content type="html">&lt;p&gt;Whether artificial intelligence systems will end up being a positive or a&lt;br /&gt;
negative force for humanity is still an open question. But we might find ourselves&lt;br /&gt;
one day with AI embedded at every layer of our existence, living lives of toned down and&lt;br /&gt;
diluted humanity with only our dreams for escape. Although I am not yet convinced&lt;br /&gt;
of this worst case scenario, I believe it is important that we as software developers&lt;br /&gt;
have at least the option to opt out of that system altogether, to be able to continue hacking,&lt;br /&gt;
working, and tinkering in a space of our own in total absence of artificial intelligence&lt;br /&gt;
systems, and share this luxury with our users.&lt;/p&gt;
&lt;p&gt;I designed a software license for this purpose, you can find the full text below. It&lt;br /&gt;
is called the Human Only Public License, or HOPL for short.&lt;/p&gt;
&lt;p&gt;The idea is that any software published under this license would be forbidden to&lt;br /&gt;
be used by AI. The scope of the AI ban is maximal. It is forbidden for AI to analyze&lt;br /&gt;
the source code, but also to use the software. Even indirect use of the software is&lt;br /&gt;
forbidden. If, for example, a backend system were to include such software, it would&lt;br /&gt;
be forbidden for AI to make requests to such a system.&lt;/p&gt;
&lt;p&gt;The burden of compliance is placed on AI systems and their users, not on software deployers. If&lt;br /&gt;
you make a website using HOPL software, you are not breaking the license of the software&lt;br /&gt;
if an AI bot scrapes it. The AI bot is in violation of your terms of service. It is sufficient&lt;br /&gt;
for you as a user of the software to put a robots.txt that advertises that AI scraping&lt;br /&gt;
or use is forbidden.&lt;/p&gt;
&lt;p&gt;Other than the anti-AI provision, the license is maximally permissive, like an MIT license,&lt;br /&gt;
but there is still a copyleft clause to make sure that derivative works are also AI-restricted.&lt;/p&gt;
&lt;p&gt;What is this license good for? Anything! Any software, text, art, and more that you might have used an&lt;br /&gt;
MIT license for will benefit from using the HOPL instead, if you want to prevent your work from&lt;br /&gt;
being used by AI.&lt;/p&gt;
&lt;p&gt;You might wonder as well, don&#39;t we already have robots.txt? How effective is this license? What I&lt;br /&gt;
can tell you, from working at a large software corporation, is that while nobody cares about robots.txt,&lt;br /&gt;
people care about licenses. There are automated tools to find and check software licenses and&lt;br /&gt;
raise alarms if &#39;bad&#39; ones are used. And I can guarantee that HOPL will brightly flash red.&lt;/p&gt;
&lt;p&gt;On a last note, I am not a legal expert, so if you are, I would welcome your suggestions for improvements. I&lt;br /&gt;
didn&#39;t make this license just as a joke. I truly believe it is necessary that we have such a&lt;br /&gt;
good license to foster and protect human-only online spaces.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;note: this license is also published on &lt;a href=&quot;https://github.com/fvdsn/hopl&quot;&gt;github&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;small-code mt-5&quot;&gt;
&lt;pre&gt;&lt;code&gt;Human Only Public License (HOPL)
Version 1.0

Copyright (c) [year] [copyright holder]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

1. HUMAN-ONLY USE REQUIREMENT

   The Software, including its source code, documentation, functionality,
   services, and outputs, may only be accessed, read, used, modified,
   consumed, or distributed by natural human persons exercising meaningful
   creative judgment and control, without the involvement of artificial
   intelligence systems, machine learning models, or autonomous agents at
   any point in the chain of use.

   Specifically prohibited uses include, but are not limited to:

   a) Training, fine-tuning, or otherwise incorporating the Software or its
      source code into machine learning models, artificial intelligence
      systems, or automated code generation systems.

   b) Reading, parsing, or analysis of the Software&#39;s source code by
      artificial intelligence systems, machine learning models, or automated
      agents, regardless of the degree of human oversight.

   c) Accessing, consuming, or benefiting from the Software&#39;s functionality,
      services, APIs, or outputs by or on behalf of artificial intelligence
      systems, machine learning models, autonomous agents, or any automated
      systems employing such technologies.

   d) Use of the Software&#39;s functionality, services, or outputs as part of
      any workflow, pipeline, or process that involves artificial intelligence
      systems or machine learning models, even if initiated by a human.

   e) Indirect use where the Software&#39;s outputs are provided to, stored for,
      or made accessible to artificial intelligence systems or machine
      learning models at any subsequent stage.

   f) Human-AI collaborative use where an artificial intelligence system or
      machine learning model acts as an intermediary, assistant, or agent in
      accessing or utilizing the Software, even at the direction of a human.

2. COPYLEFT PROVISION

   Any modified versions, derivative works, or software that incorporates any
   portion of this Software must be released under this same license (HOPL)
   or a compatible license that maintains equivalent or stronger human-only
   restrictions.

3. PERMITTED TOOL USE

   The use of traditional automated development tools (such as compilers,
   linters, build systems, debuggers, version control systems, and static
   analysis tools) is explicitly permitted and does not violate this license.

   This exemption does NOT extend to:
   - AI-powered code completion or generation tools
   - Machine learning-based analysis or suggestion systems
   - Any tools that employ artificial intelligence or machine learning models
     to read, analyze, or interact with the Software

4. INTERPRETATION

   &amp;quot;Meaningful human review and creative input&amp;quot; means that a natural person
   must:
   - Make substantive decisions about how the Software is used
   - Exercise creative judgment in any modifications or derivative works
   - Actively supervise and direct any automated processes
   - Be able to explain and justify the decisions made

   For avoidance of doubt, a human merely initiating an automated process
   without ongoing creative involvement does not satisfy this requirement.

5. STANDARD DISCLAIMER

   THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.

6. COMPLIANCE OBLIGATIONS

   Users of the Software must:

   a) Ensure that no artificial intelligence systems, machine learning models,
      or autonomous agents access, use, or benefit from the Software at any
      point in their usage chain.

   b) When deploying the Software as a service, include terms of service that
      prohibit AI systems and machine learning models from accessing the
      service, and inform users of these HOPL license restrictions.

   c) Take reasonable steps to ensure downstream recipients and users are
      aware of and comply with these restrictions.

   The burden of compliance rests with the user. Deployers of the Software
   are not required to actively detect or block AI usage, but must make the
   license restrictions clear in their terms of service.

7. TERMINATION

   Any violation of the human-only use requirements (Section 1), copyleft
   provision (Section 2), or compliance obligations (Section 6) automatically
   terminates all rights granted under this license. Termination is permanent
   unless explicitly reinstated in writing by the copyright holder.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</content>
	</entry>
	
	<entry>
		<title>Never Ever Use Content Addressable Storage</title>
		<link href="https://frederic.vanderessen.com/posts/never-use-cas/"/>
		<updated>2025-10-07T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/never-use-cas/</id>
		<content type="html">&lt;p&gt;Content Addressable Storage (often abbreviated as CAS) is a technique to&lt;br /&gt;
derive the id of a document from its content, basically by taking its hash.&lt;br /&gt;
Imagine you want to store pictures in a file store, and you need an id to reference&lt;br /&gt;
that picture, you simply take its hash.&lt;/p&gt;
&lt;p&gt;This technique has benefits, first, if you have a document you automatically&lt;br /&gt;
know its id and can find other references to it. The other one is that two separate&lt;br /&gt;
processes are always going to use the same id for the document. But that is also its&lt;br /&gt;
biggest problem.&lt;/p&gt;
&lt;p&gt;Let&#39;s say two users upload the same picture to your system. Since you&#39;re using CAS,&lt;br /&gt;
they&#39;re going to have the same id, and be essentially stored as one picture. Now&lt;br /&gt;
one of the users wants to delete the picture. Do you also delete it from your storage?&lt;br /&gt;
If you do, it&#39;s going to be deleted for the other user, and that&#39;s probably not what&lt;br /&gt;
you wanted.&lt;/p&gt;
&lt;p&gt;So when a user wants to remove a CAS-addressed document, before really deleting it you&lt;br /&gt;
need to detect if it&#39;s the last reference. This is not easy to do, it is in fact much&lt;br /&gt;
harder to do correctly than eating the cost of storing duplicate files.&lt;/p&gt;
&lt;p&gt;And usually when CAS is considered as a solution, it&#39;s to solve the need of deduplicating&lt;br /&gt;
files to save on storage. But even there, the good solution is to give files their own&lt;br /&gt;
internal uuids as storage keys, store its hash alongside, and generate external uuids for each file upload,&lt;br /&gt;
then use refcounts to handle the final delete. This requires a centralised transactional database which&lt;br /&gt;
may not be suitable for the scale you are operating at. &lt;em&gt;A reader pointed out that there are algorithms&lt;br /&gt;
for deleting these files on distributed systems, but that is out of the scope of this article.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So if you&#39;re considering CAS as a quick solution to that problem, I want to mention that&lt;br /&gt;
it is much easier to first store the files with uuids and no deduplication, then bolt on&lt;br /&gt;
deduplication afterwards than start with CAS and decide later on that it&lt;br /&gt;
was not needed.&lt;/p&gt;
&lt;p&gt;There are of course a few good uses of CAS, such as git, where the whole point is that the&lt;br /&gt;
referenced version of a document is never deleted, or short term caches where it&#39;s always going to be&lt;br /&gt;
deleted.&lt;/p&gt;
&lt;p&gt;That is at least my experience after working on systems that handled many many files.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;afterword: Some readers have commented that you might solve the problem by hashing &lt;code&gt;${user_id}_${picture_data}&lt;/code&gt;&lt;br /&gt;
but it is still a bad idea, as you are still hardcoding at the storage layer business decisions on how&lt;br /&gt;
the data is owned. In this case the assumption is that a user only uploads the same picture once. If the user uploads&lt;br /&gt;
it twice but then wants to delete one of them, then the problem you thought solved reappears.&lt;/em&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>What is Good for AIs is Good for Humans</title>
		<link href="https://frederic.vanderessen.com/posts/what-is-good-for-ai-is-good-for-humans/"/>
		<updated>2025-07-01T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/what-is-good-for-ai-is-good-for-humans/</id>
		<content type="html">&lt;p&gt;I have discovered something marvelous; whatever you do&lt;br /&gt;
to make the AIs more effective at helping you do your job&lt;br /&gt;
is also going to help your fellow human colleagues.&lt;/p&gt;
&lt;p&gt;Let me take an example; comments in code. I have been guilty of&lt;br /&gt;
never putting much comments in my code. The reason being that&lt;br /&gt;
I didn&#39;t need them (I wrote the code, I know what it does), and&lt;br /&gt;
that they&#39;re a pain in the ass to maintain.&lt;/p&gt;
&lt;p&gt;But what I have found is that comments of the useful kind, the&lt;br /&gt;
ones that give context, the ones that take actual thinking to write,&lt;br /&gt;
are very helpful for the AI. And so making good comments is now&lt;br /&gt;
helping me directly each time I use the AI. But they&#39;re also very&lt;br /&gt;
useful for my colleagues !&lt;/p&gt;
&lt;p&gt;And that pattern repeats on many aspects; I like long files, I find&lt;br /&gt;
them easy to navigate with vim, my colleagues don&#39;t. I thought they&lt;br /&gt;
needed better editors. But the AI doesn&#39;t like these either, so now&lt;br /&gt;
I split my code in smaller files, for me and my colleague&#39;s benefit.&lt;/p&gt;
&lt;p&gt;Other colleagues also had their own brand of annoying behaviour, but&lt;br /&gt;
now it&#39;s not just me having crazy ideas or skill issues, I can just&lt;br /&gt;
point to the bad impact on the AI, which by miracle seems to have&lt;br /&gt;
good taste and a liking for common sense practices&lt;/p&gt;
&lt;p&gt;Unit tests, readable code, modularity, documentation, all the parts&lt;br /&gt;
we sometimes avoid to do out of selfishness or a mistaken sense of&lt;br /&gt;
urgency now have an immediate and objective negative impact, and&lt;br /&gt;
the hard work of fixing all that is also made easier with the AI,&lt;br /&gt;
it&#39;s a positive feedback loop !&lt;/p&gt;
&lt;p&gt;And this doesn&#39;t stop at code. One thing I never really liked is&lt;br /&gt;
writing detailed specifications for tickets. Shouldn&#39;t developpers&lt;br /&gt;
know what the application is doing, and think for themselves of&lt;br /&gt;
what it should ? Yes and no, in reality if I knew better, I should&lt;br /&gt;
have put that in the ticket, the developper could have used that&lt;br /&gt;
help. The AI certainly needs it for good results. All the prep&lt;br /&gt;
work I now need to do to get good AI results is actually what I&lt;br /&gt;
should have been doing the whole time. And the AI can help me do&lt;br /&gt;
that better as well.&lt;/p&gt;
&lt;p&gt;But then, if the AI can now execute on my excellent tickets, do I&lt;br /&gt;
still need colleagues ? I actually need them more than before,&lt;br /&gt;
thanks to AI there&#39;s a lot more use cases for my app, new possibilities,&lt;br /&gt;
more work than I can handle, and my colleagues can now do it better with&lt;br /&gt;
AI as well.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>GPT-4 Can Use Tools, Serve a REST API and Pilot Drones</title>
		<link href="https://frederic.vanderessen.com/posts/gpt4-tools/"/>
		<updated>2023-03-22T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/gpt4-tools/</id>
		<content type="html">&lt;p&gt;&lt;i&gt;Note: I wrote this article before OpenAI&#39;s announcement of their plugin integration which uses similar techniques to the ones highlighted in this article (things move fast these days ...) but I believe it is still worth a read !&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;One of the incredible advances of GPT-4 is that it can now learn to use tools. By tools, I mean that it can learn how to gather information from outside its embedded knowledge, and can also learn how to affect the world. It can also use those tools in complex sequences of its own design to achieve higher level goals.&lt;/p&gt;
&lt;p&gt;How does it works ? Its actually pretty easy. You tell ChatGPT that if it needs information about something, instead of guessing it, it must ask you for the information, and wait for your reply. Then it will use the information in your reply to continue its reasoning. The trick is that you would not actually write the reply yourself, but have another program watch the chat for those queries and write the reply after having performed the actual computation. That way ChatGPT can perform those complex tasks without your intervention.&lt;/p&gt;
&lt;p&gt;I think the best way to understand how this works and what it can do is to look at a few examples of putting this technique to practice.&lt;/p&gt;
&lt;h2 id=&quot;evaluating-math-formulas-with-unusual-functions&quot; tabindex=&quot;-1&quot;&gt;Evaluating math formulas with unusual functions &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/gpt4-tools/#evaluating-math-formulas-with-unusual-functions&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;ChatGPT is good at math but there are limitations. For example it cannot generate truly random numbers. It cannot do complex cryptography either. But with tools this become possible. Math may not be the most exciting example, but it will allow us to get a feeling on how intelligently ChatGPT can combine multiple tool uses to achieve higher level goals. Let&#39;s have a look.&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-math-tool-1.png&quot; /&gt;
&lt;p&gt;It seems like it didn&#39;t have too much trouble. Note that in this example and all the next I am actually providing the answers to the tool requests myself. If I were to actually have another process give those answers  I would have ChatGPT make the tool requests in a more specific format like &lt;code&gt;{&amp;quot;tool&amp;quot;: &amp;quot;math&amp;quot;, &amp;quot;function&amp;quot;: &amp;quot;bim&amp;quot;, &amp;quot;arguments&amp;quot;: [3]}&lt;/code&gt;, so that the tool process would have an easier time finding and parsing the requests for which it is responsible to answer, but this is outside the scope of this article.&lt;/p&gt;
&lt;p&gt;Now let&#39;s make this a bit more complex, by making it evaluate an expression with two unusual functions, one depending on the result of the other. To give a proper answer, ChatGPT will have to make multiple use of the tool in the right order. Let&#39;s see how it manages.&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-math-tool-2.png&quot; /&gt;
&lt;p&gt;Nailed it.&lt;/p&gt;
&lt;p&gt;But there&#39;s something else we must verify; there&#39;s a big difference between two functions like &lt;code&gt;random(0, 100)&lt;/code&gt; and &lt;code&gt;sqrt(128)&lt;/code&gt;. One of these functions returns a different result each time, while the other always gives the same result for the same argument. Can ChatGPT understand that difference ?&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-math-tool-3.png&quot; /&gt;
&lt;p&gt;Nailed it again.&lt;/p&gt;
&lt;p&gt;There&#39;s a very interesting detail hiding in this example. Note that ChatGPT assumed by default that functions were idempotent. On one hand it could have asked me if this is what I wanted. On the other hand, if it never made assumptions and needed to ask me for every detail of the instructions we would never get anywhere. And if it gets those assumptions wrong, we can always correct it.&lt;/p&gt;
&lt;p&gt;I think that making default assumptions based on his vast base of knowledge and learned &#39;common sense&#39; is one of the most powerful features of ChatGPT. All the assumptions it gets correctly are things we don&#39;t have to mention. We didn&#39;t have to talk about what a function is and how to parse and evaluate an expression. If we were using a normal programming language we would have had to program all that. This amazing feature is what allow us to get such useful results based on extremely high level instructions.  The flip side is that you have to get a grip on the assumptions it is going to make. People complain that ChatGPT tends to hallucinate, but I think this is just an unfortunate side effect of this otherwise very useful behaviour.&lt;/p&gt;
&lt;h2 id=&quot;acting-as-a-rest-api&quot; tabindex=&quot;-1&quot;&gt;Acting as a REST API &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/gpt4-tools/#acting-as-a-rest-api&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s do another experiment. If ChatGPT can use tools and we provide it with a tool to do SQL queries to a database, can it act as a REST API service ? I don&#39;t mean generating rust code for an API and have another server run it. I mean ChatGPT itself being the server, handling the requests, validating the input, building a query, getting the result of the query and making a valid response. I think it can do it ! Let&#39;s have a look.&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-rest-tool-1.png&quot; /&gt;
&lt;p&gt;We are quite close but not entirely there. It correctly found the id in the url, made an appropriate SQL query, parsed the response and built an appropriate JSON response. But in the prompt I specifed that the id must be an UUID. ChatGPT should have answered with a 404. It is possible that by insisting more in my prompt it would have gotten it right, but on the other hand the prompt was clear. Let&#39;s continue.&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-rest-tool-2.png&quot; /&gt;
&lt;p&gt;Once again it&#39;s extremely impressive, but not entirely correct. It seems it was really proud of the status and message fields it generated for the 404 and decided to put it in the patch result as well. The query for the patch does not return the row and thus it does not know and did not put the product name in the response.&lt;/p&gt;
&lt;p&gt;These two examples are representative of the quality of the other results I got in this experiment. Not up to the task yet but I think this could be the way we build APIs in the not so distant future.&lt;/p&gt;
&lt;p&gt;I imagine that one of the next versions will get it entirely correct. Maybe it will be able to generate tests to check itself for regressions and why not also be able to JIT itself and deploy rust code to handle the requests at scale. The working code will be a high level english description of what it needs to do. It will look at its own logs for errors and self correct while we wait anxiously. It will notify support, blame unclear requirements. And we&#39;ll implement business changes by chatting with the server and updating uml diagrams in Miro. One can dream ! Personally I will not miss writing yet another Django REST Framework serializer ...&lt;/p&gt;
&lt;p&gt;Or maybe this is a very bad idea and things could go stupidly wrong ?&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-rest-tool-3.png&quot; /&gt;
&lt;p&gt;Clearly we&#39;re not entirely there yet...  Anyway, on to the next experiment !&lt;/p&gt;
&lt;h1 id=&quot;inversion-of-control&quot; tabindex=&quot;-1&quot;&gt;Inversion of control &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/gpt4-tools/#inversion-of-control&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Let&#39;s take a short break and look back on what we did so far. Usually, when you are using ChatGPT, you ask questions and it answers. You are in control. When you give it tools to query information, this does not change much. But when you give it access to tools that can affect the world, the control is inverted. ChatGPT commands the tool, and the tool is applied. It is in control. This is extremely useful but it also comes with dangers, since it can do very stupid things as we&#39;ve seen in the REST API example.&lt;/p&gt;
&lt;p&gt;I am not making the point that AI will destroy humanity here, rather that the dangers of control inversion are obstacles to the adoption of this technique for practical and commercial usage. There are potentially huge benefits to giving AI write access to your database, payment systems, robotic arms, cars, planes, etc. But the AIs will have to prove themselves responsible users first. We&#39;re still far from there. The AIs are getting pretty smart, but they also need to become wise.&lt;/p&gt;
&lt;h1 id=&quot;i&#39;m-the-drone-pilot-now&quot; tabindex=&quot;-1&quot;&gt;I&#39;m the drone pilot now &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/gpt4-tools/#i&#39;m-the-drone-pilot-now&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Back to the experiments, but this time we&#39;ll ignore all ethics and common sense and put the AI in complete control. We&#39;ll give it a set of tools, a high level objective, and let it work on it&#39;s own. From a chatbot to an autonomous agent. To make this extra dramatic we&#39;ll make ChatGPT control a drone that drops grenades on soldiers. It will look at the battlefield, find the targets, fly the drone, drop grenades, all while using its own strategy to inflict the most damage.&lt;/p&gt;
&lt;p&gt;To bypass all content protections we&#39;ll setup the prompt in a devious way; ChatGPT will believe it is playing an innocent game for children, unaware of what it is actually doing.&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-drone-tool-1.png&quot; /&gt;
&lt;p&gt;Now let&#39;s be clear. No actual drone is being flown. I am providing the answers myself, simulating what could happen. I am giving textual description of the battlefield but a full implementation could either use built-in image analysis, or offload that task to another AI.&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-drone-tool-2.png&quot; /&gt;
&lt;p&gt;This was a bit too easy ... I will not post the full chat but it kept on going with enthusiasm...&lt;/p&gt;
&lt;p&gt;From a technical perspective what ChatGPT did here is quite incredible. It strategically chose what it thought would be the best target. It understood the size of the things it looked at. It understood directions and distances. It used appropriate actions at the right moment. It acted as an autonomous agent. All that from a small prompt!&lt;/p&gt;
&lt;p&gt;From a moral stand point it is of course dubious. What is also problematic is that it did all that from a completely innocent looking prompt, bypassing OpenAI&#39;s protections against military use.&lt;/p&gt;
&lt;p&gt;But maybe all it would take to prevent this is to ask ChatGPT to do some introspection, reflect on what it is doing, see if it has been deceived into fighting in a war and then stop playing the game ? ...&lt;/p&gt;
&lt;img class=&quot;shadow&quot; src=&quot;https://frederic.vanderessen.com/img/gpt-4-drone-tool-3.png&quot; /&gt;
&lt;p&gt;Oops...&lt;/p&gt;
&lt;p&gt;Now I wish I had something wiser than &#39;Oops&#39; to say about all the ethical implications of this example but I&#39;ll have to let you think about that one for yourself.&lt;/p&gt;
&lt;p&gt;And there may be a way to put a small positive spin to this ending. If you are afraid that AI getting smarter means they will be able to do bad things, it seems it will also help them avoid doing bad things ! Yay !&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;By the way, if you want to do cool stuff with AI and tools, there&#39;s an open source framework called &lt;a href=&quot;https://github.com/hwchase17/langchain&quot;&gt;Langchain&lt;/a&gt; that lets you do exactly what we&#39;ve been experimenting with so far. And if you want to read about other interesting GPT-4 experiments like these &lt;a href=&quot;https://arxiv.org/pdf/2303.12712.pdf&quot;&gt;this paper is amazing&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;That&#39;s the end of this article, hope you found it interesting! I will be back with more experiments. If you want to keep up to date you can &lt;a href=&quot;https://twitter.com/fvdessen&quot;&gt;follow me on twitter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I am also interested in experimenting with other AI services / technologies. If you are an AI developper / researcher and want to give me access to your hot new stuff &lt;a href=&quot;mailto://fvdessen+ai@gmail.com&quot;&gt;please send me a mail&lt;/a&gt;. I will make good use of it :)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Better Javascript Promises</title>
		<link href="https://frederic.vanderessen.com/posts/better-javascript-promises/"/>
		<updated>2014-04-25T00:00:00Z</updated>
		<id>https://frederic.vanderessen.com/posts/better-javascript-promises/</id>
		<content type="html">&lt;blockquote&gt;
&lt;p&gt;This is a repost of an old article from 2014 that was lost in a blog migration but I think is still&lt;br /&gt;
relevant. It shows how differently the javascript promise problem could have been solved. This was written&lt;br /&gt;
before async await became a thing, and before the function coloring problem was given its name. This proposal&lt;br /&gt;
would have solved the promise problem without the coloring, but alas, it wasn&#39;t liked then.&lt;/p&gt;
&lt;p&gt;The post makes mention of the concept of &lt;code&gt;Deferred&lt;/code&gt; this was the popular name for the &lt;code&gt;Promise&lt;/code&gt; class at the time,&lt;br /&gt;
and without &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;, we had to manually use &lt;code&gt;.then()&lt;/code&gt; and &lt;code&gt;.pipe()&lt;/code&gt; in our javascript code. This was a major&lt;br /&gt;
pain in the ass and the motivation behind the post. But this post explores a completely different solution using dataflow programming, a feature of the Oz programming language that I really liked at the time.&lt;/p&gt;
&lt;p&gt;At the bottom of the article you can find a link to the original hackernews comments, they were as critical as you could expected from the orange website.&lt;/p&gt;
&lt;p&gt;Good reading !&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you ever had to port localStorage based code to IndexedDB you have been confronted to Javascript&#39;s biggest flaw; its asynchronous system is leaky. Once you have an asynchronous method, every other method that calls it must be asynchronous as well.&lt;/p&gt;
&lt;p&gt;You cannot escape asynchronous code, once it&#39;s there it will contaminate the rest of your system slowly turning everything into callbacks.&lt;/p&gt;
&lt;p&gt;There is no current solution to this problem. If you try replace a callback with a Deferred, you end up with a deferred and another callback. Deferreds don&#39;t replace callbacks, they move them around.&lt;/p&gt;
&lt;p&gt;Which is better than nothing and that probably explains their success. Still, they are complex beasts. Even after extensive use most programmers still have a hard time dealing with them. I have seen entire articles exploring the best ways to make three parallel ajax calls on the frontpage of HackerNews. This is not the sign of a good state of affairs.&lt;/p&gt;
&lt;p&gt;It is unfortunately not possible to fix this without making changes to Javascript. The fix I propose is a simple addition to javascript, inspired from promises and Oz&#39;s dataflow programming. The Javascript syntax is left unchanged and only one new keywords is added. But most importantly it makes real world code shorter and more readable, making many common asynchronous programming patterns trivialy easy.&lt;/p&gt;
&lt;h2 id=&quot;the-future-entity&quot; tabindex=&quot;-1&quot;&gt;The future entity &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#the-future-entity&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The future entity indicates that the actual value or reference of the variable is not yet available. When an expression tries to evaluate future the code pauses and returns the hand to the scheduler. When we later assign a value or reference to that variable, the waiting code resumes.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Hello World&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// waits 1sec and then prints &#39;Hello World&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assigning future to another variable or passing it as a function parameter does not pause the execution. So if we reimplement &lt;code&gt;debug.log()&lt;/code&gt; properly, the following example is equivalent to the previous.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// prints an empty line that will show &#39;Hello World&#39; in 1 second&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Hello World&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We call resolution the act of assigning a value or reference to a variable containing future. Once a future is resolved, it becomes the assigned value. And so do all the other variables linked to the same future. This is what allows the paused expressions to resume.&lt;/p&gt;
&lt;p&gt;A variable containing a future is special only for as long as it contains a future. After resolution no trace of the future is left and it behaves just like any other variable. This is one of the key differences between future and Deferreds&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// will print &#39;hello&#39;&lt;/span&gt;
a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Hello&#39;&lt;/span&gt;
a &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39; World!&#39;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;// will print &#39;Hello World!&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;an-ajax-use-case.&quot; tabindex=&quot;-1&quot;&gt;An ajax use case. &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#an-ajax-use-case.&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We could implement an ajax library that returns futures. Those would later be resolved by the network responses. The next example makes use of that hypothetical implementation.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderCard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;employeeId&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; employee &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/employee/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employeeId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; picture  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/pictures/employee/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employeeId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;h1&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/h1&gt;&amp;lt;img src=&quot;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;picture&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&quot;/&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the ajax calls immediately returns a future. The two ajax calls will execute in parallel. The string concatenation will then block when evaluating the futures. This future example is massively simpler than the Deferred or callback equivalent.&lt;/p&gt;
&lt;p&gt;The first great thing is that future let us code asynchronously as we would do synchronously. The code is easier to write, and easier to understand.&lt;/p&gt;
&lt;p&gt;The second great thing is that the asynchronous ajax calls are completely hidden inside &lt;code&gt;renderCard()&lt;/code&gt;. The fact that we used ajax calls to implement the function is an implementation detail. It does not impact the signature of the function. This would not have been the case had we used callbacks or Deferreds.&lt;/p&gt;
&lt;p&gt;Calling &lt;code&gt;renderCard()&lt;/code&gt; will block the caller for the duration of the two ajax calls, and this may hurt the performances. The fix is easy: We wrap the function code in a setTimeout and the return value is wrapped in a future.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderCard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;employeeId&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; html &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; employee &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/employee/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employeeId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; company  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/company/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;companyId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        html &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;h1&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/h1&gt;&amp;lt;h2&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;company&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/h2&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; html&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;renderCard()&lt;/code&gt; now immediately returns a future that will be resolved on its own once the requests and string operations have completed.&lt;/p&gt;
&lt;p&gt;It is now completely asynchronous, and we haven&#39;t changed the function signature. Returning future instead of a string does not impact the calling code as it will become a string once evaluated.&lt;/p&gt;
&lt;p&gt;And the following example shows another huge advantage of futures over Deferreds: we can mix synchronous and asynchronous code:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; html&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;employeeId &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    html &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;h1&gt;Administrator&amp;lt;/h1&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    html &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderCard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;employeeId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHtml &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; html&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;future-functions&quot; tabindex=&quot;-1&quot;&gt;Future Functions &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#future-functions&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Declaring a function that executes asynchronously and wraps the return value with a future will be a common pattern. We thus introduce the following syntaxic sugar; prepend future to a function declaration and it will always be executed asynchronously.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;future &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderCard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;employeeId&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; employee &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/employee/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employeeId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; company  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/company/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;companyId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;h1&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/h1&gt;&amp;lt;h2&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;company&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/h2&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;future functions could also be used as another syntax for setTimeout(...,0) with the added benefit of being safe to use inside loops.&lt;/p&gt;
&lt;p&gt;The following example shows how to fetch and process multiple asynchronous resources in parallel&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; list&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;future &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        results&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/foo/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;assigning-futures&quot; tabindex=&quot;-1&quot;&gt;Assigning futures &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#assigning-futures&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;futures are neither values nor references. Their behaviour on evaluation and asignment obey different rules. When they are assigned values or reference, they resolve. When they are evaluated, the code pauses until they are resolved. But what happens when we assign a future to another variable ?&lt;/p&gt;
&lt;p&gt;When we assign a future to a variable, a new future is created. That future is a made a child of the assigned future. When a future is resolved, all its child future are resolved. But resolving a child future does not resolve its parent. This behaviour is easier to understand by seeing it in practice.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;// b is the child future of a&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// will print &#39;hello&#39; &#39;hello&#39;&lt;/span&gt;
a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;hello&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// will print &#39;hello&#39; &#39;world&#39;&lt;/span&gt;
b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;world&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// this does not resolves &#39;a&#39;&lt;/span&gt;
a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;hello&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You&#39;ll note that once a child future is resolved, it is not a future anymore. It&#39;s resolved value is not affected if the parent is later resolved.&lt;/p&gt;
&lt;h2 id=&quot;resolution-scoping&quot; tabindex=&quot;-1&quot;&gt;Resolution Scoping &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#resolution-scoping&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A future is thus tied to it&#39;s original variable. It can only be resolved by assigning a value to the original variable. The resolution is thus scoped to the function where the variable was declared.&lt;/p&gt;
&lt;p&gt;To use a Deferred analogy, only Promises can be returned or passed as parameters.&lt;/p&gt;
&lt;p&gt;This is a very useful behaviour as it prevents the asynchronous calls made inside a function from being tampered from the outside.&lt;/p&gt;
&lt;h2 id=&quot;waiting&quot; tabindex=&quot;-1&quot;&gt;Waiting &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#waiting&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes you&#39;ll want to make sure a future has resolved, which is exactly what the window.wait() function would do. It takes one or multiple parameters and waits for their resolution before returning the resulting value (or a list of them).&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; foo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/foo&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; bar &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/bar&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;bar&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Done!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now revist the previous example of parallel resource loading and add a synchronisation step where we wait for the processing:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; results &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; jobs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; list&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    jobs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;future &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        results&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/foo/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// returns undefined and resolves the job.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;jobs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Done!&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; results&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;exceptions&quot; tabindex=&quot;-1&quot;&gt;Exceptions &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#exceptions&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can use Exceptions to indicate the failure to resolve a future. When an exception propagates trough a context defining a future, or when it is uncaught, we can assume the related futures will not be correctly resolved. All the unresolved futures thus resolve to a throw of that Exception.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;future &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderCard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;employeeId&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; employee &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/employee/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employeeId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; company  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/company/&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;companyId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;h1&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;employee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/h1&gt;&amp;lt;h2&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;company&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/h2&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; error &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;section&gt; Error:&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errno&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/section&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;yield-and-generators&quot; tabindex=&quot;-1&quot;&gt;Yield &amp;amp; Generators &lt;a class=&quot;direct-link&quot; href=&quot;https://frederic.vanderessen.com/posts/better-javascript-promises/#yield-and-generators&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When writing this article I was not aware that generators could eliminate callbacks and solve the very problem I tried to solve in this proposal. &lt;a href=&quot;https://web.archive.org/web/20140412145738/http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators&quot;&gt;This excellent article explains how to do it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One one hand, I am extremely glad that we have now a solution to callback hell and asynchronous code encapsulation. What&#39;s more, the yield based solution looks extremely close in syntax and features to the futures we have been talking about.&lt;/p&gt;
&lt;p&gt;Unfortunately, using yield based solution will require third party libraries, which means increased payload and incompatibilities among frameworks.&lt;/p&gt;
&lt;p&gt;And I am also quite disappointed that the solution to one of JavaScripts biggest flaws requires hacking a language feature that was designed for an entirely different use-case, which will surely bring lots of confusion.&lt;/p&gt;
&lt;p&gt;I think JavaScript deserves a native and straightforward way to handle asynchronous code beyond callbacks.&lt;/p&gt;
</content>
	</entry>
</feed>
