<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>Serialized Gedanken</title>
	<subtitle>Serialized thoughts of a developer ahead of time</subtitle>
	
	<link href="https://valentin.willscher.de/feed/feed.xml" rel="self"/>
	<link href="https://valentin.willscher.de/"/>
	<updated>2024-05-19T00:00:00Z</updated>
	<id>https://valentin.willscher.de/</id>
	<author>
		<name>Valentin Willscher</name>
		<email>valentin@willscher.com</email>
	</author>
	
	<entry>
		<title>Fundamental estimation problems</title>
		<link href="https://valentin.willscher.de/posts/fundamental-estimation-problems/"/>
		<updated>2024-05-19T00:00:00Z</updated>
		<id>https://valentin.willscher.de/posts/fundamental-estimation-problems/</id>
		<content type="html">&lt;p&gt;There are so many articles about the topic of estimations in software-development, I can&#39;t even count anymore how many of them I read.&lt;/p&gt;
&lt;p&gt;Even though, almost everyone still estimates effort or time by breaking down work into tasks and then assigning &lt;em&gt;a single number&lt;/em&gt; to each of them.&lt;br /&gt;
It&#39;s really beyond me why this is still the standard. Maybe because methodologies like Scrum and tools like Jira encourage it?&lt;/p&gt;
&lt;p&gt;But to understand why this is such a big problem, a fundamental problem of estimations needs to be understood first, not only by developers but also by managers and other stakeholders.&lt;/p&gt;
&lt;h2 id=&quot;estimations&quot; tabindex=&quot;-1&quot;&gt;Estimations &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#estimations&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s get one thing out of the way: estimations are generally important and useful. They improve decision-making about prioritization, timing, deadlines and resource-planning.&lt;/p&gt;
&lt;p&gt;Well, at least if everyone works together in good faith. The estimation process can also be abused and become a form of (corporate) power-play.&lt;br /&gt;
In those cases, there&#39;s no point in discussing about the &lt;em&gt;how&lt;/em&gt;, so I&#39;m going to focus on the happy-case here.&lt;/p&gt;
&lt;h3 id=&quot;single-number-estimations&quot; tabindex=&quot;-1&quot;&gt;Single number estimations &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#single-number-estimations&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I said that it&#39;s a problem to estimate work by assigning just a single number per task. Even if it&#39;s t-shirt-size estimations.&lt;/p&gt;
&lt;p&gt;Why is that?&lt;/p&gt;
&lt;p&gt;Imagine you are a manager (or maybe you just are one) and your developers are always giving you precise estimates like &lt;em&gt;5 days&lt;/em&gt; or &lt;em&gt;3 months&lt;/em&gt; of work for a bunch of tasks or a project.&lt;br /&gt;
And then they always deliver on time. That sounds great right? The developers seem to know what they are doing. Makes it easy to rely on them and plan things.&lt;/p&gt;
&lt;p&gt;Maybe surprisingly, this is actually not good. Here is how reality usually looks like:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Developers estimates are...&lt;/th&gt;
&lt;th&gt;Behind the scenes...&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Almost always accurate&lt;/td&gt;
&lt;td&gt;1. The developers are adding way too much &amp;quot;buffer time&amp;quot;&lt;br /&gt;       &lt;strong&gt;or&lt;/strong&gt;&lt;br /&gt; 2. The developers are incompetent and repeat work instead of automating it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Almost always too low&lt;/td&gt;
&lt;td&gt;Communication issues, incompetent management (often: top down pressure)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Almost always too high&lt;/td&gt;
&lt;td&gt;Does not happen, your data is wrong :-)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50% too high and 50% too low&lt;/td&gt;
&lt;td&gt;🦄 You found a unicorn&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Okay, fine, it&#39;s a bit exaggerated - but maybe less than you think.&lt;/p&gt;
&lt;h3 id=&quot;estimations-are-no-divinations&quot; tabindex=&quot;-1&quot;&gt;Estimations are no divinations &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#estimations-are-no-divinations&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A common misunderstanding in the field of software-development is to think that with experience estimations must get better.&lt;br /&gt;
And it sounds logical at first because that&#39;s how it works in other fields: someone who has to build a house for the first time will have a hard time to estimate how long the whole thing takes. But after building houses for decades, their estimations will eventually become spot on.&lt;/p&gt;
&lt;p&gt;Unfortunately, software-development is one of the very few professions where this is &lt;em&gt;inherently different&lt;/em&gt;.&lt;br /&gt;
Software-development is ultimately the process of creating automations. Every piece of work that has to be repeated over and over again will sooner or later be automated.&lt;br /&gt;
Once that has happened, it can be used or produced so quickly that &lt;u&gt;it is not even worth to include it into the estimation process anymore&lt;/u&gt;.&lt;/p&gt;
&lt;p&gt;In consequence, the only tasks that actually make it into the estimation process are those that have not been automated yet - because they have not been built in this way so far. Thinking of it from that perspective, it&#39;s not a surprise why those estimations are comparably difficult.&lt;/p&gt;
&lt;p&gt;But it&#39;s not only that. There are also many factors that simply cannot be estimated precisely when starting. For instance, a technical dependency that is required for the task at hand has an unexpected bug that needs to be worked around.&lt;br /&gt;
All in all, even if we try hard to estimate a task as precisely as possible, we inevitably end up with a &lt;em&gt;probability distribution&lt;/em&gt;; and most likely a rather complicated one.&lt;br /&gt;
And since there are many factors which all vary in their own way, it is not unreasonable to assume that the outcome will often follow something that is not far from a normal distribution.&lt;br /&gt;
So it might actually look something like this:&lt;/p&gt;
&lt;img src=&quot;https://valentin.willscher.de/posts/img/simple_example_estimation_distribution.png&quot; alt=&quot;Graph: Example estimation with simple probability distribution&quot; style=&quot;max-width:100%;&quot; /&gt;
&lt;p&gt;The graph shows how likely it is (in percent) that the task will be finished in a given amount of time on the X-axis (in days or weeks or months - it doesn&#39;t matter here).&lt;/p&gt;
&lt;p&gt;To come back to the table from the beginning - what would the developer give as a single number based on that distribution?&lt;br /&gt;
Due to the symmetry it clearly looks like a 4 on average.&lt;br /&gt;
However, the chance for the task to be finished after &lt;em&gt;exactly&lt;/em&gt; 4 days is extremely low; it will sometimes be a bit more and sometimes a bit less, maybe 3 or 5 days.&lt;br /&gt;
One day difference might not sound like a problem but what if those are months not days? What if it&#39;s a law that we are supposed to follow with a given deadline?&lt;/p&gt;
&lt;p&gt;Looking at it from another perspective: when using such a technique for estimations to decide on deadline dates, &lt;em&gt;half of all deadlines will be missed&lt;/em&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;By now it should be clear why single-number-estimations are very limited.&lt;br /&gt;
But I will add another example to make it even more obvious.&lt;/p&gt;
&lt;p&gt;Let&#39;s imagine there is a complicated feature that needs to be implemented by a single developer Alice.&lt;br /&gt;
The feature requires interoperation between multiple systems, including a system that Alice is unfamiliar with.&lt;br /&gt;
However, there is another developer, Bob, who knows all about the system and can share that knowledge to decrease development time drastically.&lt;br /&gt;
But Bob is busy with another urgent and critical project and it is yet unclear if he will be able to provide any support at all.&lt;/p&gt;
&lt;p&gt;How does the probability distribution look like in this case?&lt;/p&gt;
&lt;img src=&quot;https://valentin.willscher.de/posts/img/bimodal_example_estimation_distribution.png&quot; alt=&quot;Graph: Example estimation with bimodal probability distribution&quot; style=&quot;max-width:100%;&quot; /&gt;
&lt;p&gt;There are two peaks, one at a low effort (~4 days) when receiving a bit of help by the other developer and one without their help (~12 days).&lt;/p&gt;
&lt;p&gt;Just estimating the mean value here is even more misleading than in the previous example. The mean of this distribution here is 7.2, but when looking at the graph we can see that the chance of the outcome to actually be 7.2 or even close to it is pretty much zero.&lt;/p&gt;
&lt;p&gt;Using the mean alone is obviously a terrible idea.&lt;/p&gt;
&lt;p&gt;Unfortunately it&#39;s unrealistic to model the effort with a precise mathematical distribution like above for every single task, let alone projects that consist of hundreds or thousands of subtasks.&lt;/p&gt;
&lt;h3 id=&quot;tackling-the-shortcomings&quot; tabindex=&quot;-1&quot;&gt;Tackling the shortcomings &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#tackling-the-shortcomings&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In reality, simple mean values are mostly used when doing estimations.&lt;br /&gt;
And since they are lacking, how do the estimating developers usually attempt to work around this problem in various ways?&lt;br /&gt;
Let&#39;s look at a couple of the common ones:&lt;/p&gt;
&lt;h4 id=&quot;buffers&quot; tabindex=&quot;-1&quot;&gt;Buffers &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#buffers&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;After being yelled at by their manager for a missed deadline, &amp;quot;buffers&amp;quot; will be added to the estimation values. This is very common.&lt;br /&gt;
Doing so is usually based on gut-feeling, or at least I&#39;ve never seen a guideline for it or even a standard.&lt;br /&gt;
Sometimes the deadline is communicated through multiple layers and every person adds their own buffer to protect themselves until all meaning is lost.&lt;/p&gt;
&lt;p&gt;All of that does not help in cases like the Alice/Bob example. Even fairly big buffers possibly won&#39;t really help if the second probability-peak isn&#39;t covered.&lt;/p&gt;
&lt;p&gt;In the end, buffers lead to suboptimal planning and resource allocation and for example significantly increase the time-to-market.&lt;/p&gt;
&lt;h4 id=&quot;splitting-tasks&quot; tabindex=&quot;-1&quot;&gt;Splitting tasks &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#splitting-tasks&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Another classic. Once it is understood that single-number estimations don&#39;t work well, the size or scale of the estimated tasks is made out to be the root of the problem.&lt;br /&gt;
Those tasks are just all too big and can&#39;t be estimated precisely! Hence, tasks that are too big are must be split into a smaller tasks and so on until the estimation for every task is below a certain threshold.&lt;/p&gt;
&lt;p&gt;There are indeed some benefits in splitting big tasks, it&#39;s not like this is a bad idea in general. But it comes with problems. Estimation is a time intense process and the more granular the tasks become the more friction and bureaucratic process is added to manage them.&lt;br /&gt;
In addition, the effort to actually combine the tasks into an end result is often missed or underestimated, making it so that the sum of the child tasks does not match the whole project.&lt;br /&gt;
Finally, sometimes it&#39;s just not possible to meaningful split tasks further.&lt;/p&gt;
&lt;p&gt;Ultimately, it is not a solution to the single-number estimation problem; though it can aid in other ways, such as improving the common understanding of every task within the team.&lt;/p&gt;
&lt;h4 id=&quot;side-channels&quot; tabindex=&quot;-1&quot;&gt;Side channels &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#side-channels&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;There are more workarounds, but the last one I&#39;d like to mention here is the communication via other channels.&lt;br /&gt;
If tools or processes force to enter single number, people sometimes step up and communicate that the estimation might be value X but that the confidence into that estimation is low.&lt;br /&gt;
This is a reasonable approach and better than nothing, but it is also unstructured and unsuitable as a professional solution in general.&lt;/p&gt;
&lt;h2 id=&quot;confidentiality-intervals&quot; tabindex=&quot;-1&quot;&gt;Confidentiality intervals &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#confidentiality-intervals&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My preferred practical but effective solution to improve the situation without making it too complicated is the use of confidentiality intervals.&lt;/p&gt;
&lt;p&gt;The idea is to describe two numbers instead of one: the lower and upper bound which capture 90% of the expected outcomes. For example, if the interval is defined as [2, 5] and we measure in days, then that would mean that the chance is 90% that the task will take between 2 and 5 days. And only 10% chance that it will take less than 2 or more than 5 days.&lt;/p&gt;
&lt;p&gt;It doesn&#39;t really matter what percentage we choose - 90% or maybe 80% or 75% are all fine. What matters is that we have introduced a way to indicate the trust we have in the precision of the estimation.&lt;/p&gt;
&lt;p&gt;(Note: the classical way would be to use the mean and the variance or standard derivation to describe a probability function. However confidence intervals are a bit more intuitive in their usage when it comes to most estimation processes)&lt;/p&gt;
&lt;h3 id=&quot;how-to-use-confidentiality-intervals&quot; tabindex=&quot;-1&quot;&gt;How to use confidentiality intervals &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#how-to-use-confidentiality-intervals&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;1.) We decide on a timeframe and ask the developer to estimate the probability that the feature will be completed within that timeframe.&lt;/p&gt;
&lt;p&gt;2.) We ask the developer what the deadline would have to be so that it will only be missed with a chance of 10% (or some other percentage)&lt;/p&gt;
&lt;p&gt;Approach 1.) is useful in cases where a timeframe is set by a 3rd party and we can&#39;t control it.&lt;br /&gt;
For instance, a legal requirement that needs to be complied with by a certain date.&lt;br /&gt;
In that case, we can gain information about how likely it is that the deadline won&#39;t be met. And by knowing that, we can react to it, for example by assigning more resources or preparing for the consequences of missing the deadline.&lt;/p&gt;
&lt;p&gt;Approach 2.) is more useful in cases where we can control the deadline. We might want to release a feature and we need to communicate it in advance, for instance so that the marketing department can prepare, book and release and advertisement campaign.&lt;br /&gt;
In this case we can decide on how much of a problem a delay would be and in consequence set the appropriate confidentiality level. We then ask the developer to tell us about the deadline.&lt;/p&gt;
&lt;h1 id=&quot;bonus&quot; tabindex=&quot;-1&quot;&gt;Bonus &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/fundamental-estimation-problems/#bonus&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I hope that I could shed some light into why there are often problems with estimations in software-development and also how to improve on it - for both technical and non-technical folks.&lt;/p&gt;
&lt;p&gt;If you made it that far, here&#39;s another question: why is usually only the time/effort estimated that is required to complete a task or project, but not the time/effort to maintain things?&lt;/p&gt;
&lt;p&gt;I believe that this is one of the reasons why companies or teams eventually get stuck and become unable to deliver anything new. But this is for another article. :-)&lt;/p&gt;
&lt;p&gt;Should you have solved this mystery then please let me know in the comments. Also, I would be happy to learn if you found an even better practical solution for estimation than confidence intervals.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>SQL as API</title>
		<link href="https://valentin.willscher.de/posts/sql-api/"/>
		<updated>2023-12-25T00:00:00Z</updated>
		<id>https://valentin.willscher.de/posts/sql-api/</id>
		<content type="html">&lt;h2 id=&quot;sql-in-the-api&quot; tabindex=&quot;-1&quot;&gt;SQL in the API??? &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#sql-in-the-api&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I know what you are thinking: Exposing an API that accepts SQL is crazy. It&#39;s a terrible idea.&lt;br /&gt;
Especially if the API is exposed on the internet. Doing that is insecure and will lead to SQL injection attacks, it is a nightmare to maintain and it will lock the backend implementation into a specific technology (some ANSI SQL database).&lt;/p&gt;
&lt;p&gt;But is that really true? Time to re-evaluate!&lt;/p&gt;
&lt;h3 id=&quot;there-is-always-an-exception&quot; tabindex=&quot;-1&quot;&gt;There is always an exception &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#there-is-always-an-exception&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Engineering is about making trade-offs. There is no one fits it all solution. Therefore, here I&#39;ll present the kind of scenario in which SQL is in fact the best choice to make a backend API work out.&lt;/p&gt;
&lt;p&gt;But let&#39;s take a step back first. Many APIs can be simple. Often, a CRUD API that allows for fetching, creating, updating and deleting entities by some ID is all that is needed to get the job done.&lt;br /&gt;
No arguing with that. And there is no reason to over-engineer things if this is really the case.&lt;/p&gt;
&lt;p&gt;On the other hand, there is a considerable number of applications where the business will want to expand its features in a way that forces the API to become more and more complex over time.&lt;/p&gt;
&lt;p&gt;Even just a basic web-shop can be a sufficient example for that kind of scenario. Let&#39;s say there is this web-shop which sells bicycles. Having a classical CRUD API already gets us very far in the sense that we can add, delete and update items (bicycles). We can also list them and show them to a user. But what about allowing the user to filter the various bicycles by their properties? Like color, size, price, etc.&lt;/p&gt;
&lt;p&gt;Sounds simple at first. Just add some filters-field to the request. In the HTTP / REST world it might like look this:&lt;br /&gt;
&lt;code&gt;GET /bicycles?color=red&amp;amp;size=large&amp;amp;price=1000-2000&lt;/code&gt;&lt;br /&gt;
Problem solved.&lt;/p&gt;
&lt;p&gt;But faster than you can imagine, the next requirement comes in: &lt;code&gt;OR&lt;/code&gt; filters!&lt;br /&gt;
Maybe they should be combined with &lt;code&gt;AND&lt;/code&gt; filters so that we can express constraints like &lt;em&gt;bicycles that are (made of steel AND weigh from 10 to 20kg) OR (made of carbon AND weigh from 5 to 10kg)&lt;/em&gt;.&lt;br /&gt;
Dealing with &lt;em&gt;unknown&lt;/em&gt; values (typically represented by &lt;code&gt;null&lt;/code&gt; in databases) and other subtleties will quickly creep into the codebase as well.&lt;/p&gt;
&lt;p&gt;And before long there is some complex, custom-made spaghetti-ball of filter logic, even for a simple shop website. Sounds familiar? If not, lucky you. :-)&lt;/p&gt;
&lt;p&gt;Usually, at some point, developers start to structure those filters and start to use e.g. json for more complicated requests. It might look like this:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;&quot;filters&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;&quot;or&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token property&quot;&gt;&quot;and&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;property&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;material&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;operator&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;equals&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;steel&quot;&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;property&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;weight&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;operator&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;between&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;value&quot;&lt;/span&gt;&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 number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token property&quot;&gt;&quot;and&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;property&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;material&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;operator&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;equals&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;carbon&quot;&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;property&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;weight&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;operator&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;between&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token property&quot;&gt;&quot;value&quot;&lt;/span&gt;&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 number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At the latest at that point your nose should notify you that this is a design smell.&lt;br /&gt;
Why? Because we are essentially inventing our own query language here. And inventing a custom language should be pretty much the last resort, I hope we agree on that.&lt;/p&gt;
&lt;h3 id=&quot;sql-to-the-rescue&quot; tabindex=&quot;-1&quot;&gt;SQL to the rescue? &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#sql-to-the-rescue&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Since this article is about SQL in APIs, how does SQL help us here? We surely don&#39;t want to have the webshop-frontend send database queries to the backend to get the results.&lt;br /&gt;
Well, to be honest, that &lt;em&gt;already&lt;/em&gt; has become a thing nowadays. &lt;a href=&quot;https://hasura.io/&quot;&gt;Hasura&lt;/a&gt; and alternatives are doing pretty much that - they generate a fully fledged graphql API based on the SQL schema of the database.&lt;/p&gt;
&lt;p&gt;But besides being pricey and requiring specific database technology and locking you into that technology and having limited customizability, there is also just a much more lightweight alternative: &lt;strong&gt;Exposing a &lt;em&gt;subset&lt;/em&gt; of SQL in your API.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The beauty of doing so is threefold:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;SQL is well-known language with plenty of documentation to learn it as well as support for it in almost every programming language. No need to write your own SQL parser or anything, whereas with your &amp;quot;own&amp;quot; language you need to write one. (Actually: it doesn&#39;t even have to be SQL, as long as it is a well understood and standardized query language. But SQL is probably the best choice in most cases)&lt;/li&gt;
&lt;li&gt;We can expose subsets of SQL and add more and more functionality over time and when needed, to fulfill the business requirements - without breaking existing queries and tooling.&lt;/li&gt;
&lt;li&gt;We remove a whole layer of confusion because of conversions from and to SQL (if the backend uses an SQL database anyways). Also, SQL is compact and easy to read for everyone.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But isn&#39;t that unsafe? Don&#39;t we execute SQL provided by the frontend directly against the database? That sounds like a security nightmare. And indeed, people have tried that and it has gone horribly wrong. So don&#39;t do that!&lt;/p&gt;
&lt;p&gt;Instead, for such a system to work properly, we have to do the same that we do for any other API:&lt;br /&gt;
validate the input and sanitize it before executing it. And by that I&#39;m talking about a white-list approach.&lt;br /&gt;
We only accept SQL from the request that we specifically allow. Everything else is rejected.&lt;/p&gt;
&lt;p&gt;Mind that we &lt;em&gt;don&#39;t&lt;/em&gt; do that by validating the SQL &lt;strong&gt;string&lt;/strong&gt;! We will first &lt;em&gt;parse&lt;/em&gt; the SQL string into a &lt;em&gt;data structure&lt;/em&gt;, then validate this structure and finally &lt;em&gt;convert&lt;/em&gt; the structure back into SQL.&lt;br /&gt;
In other words: the SQL executed against the database might look a little different than the one we received from the API.&lt;br /&gt;
And this is good. It allows us to do modifications to the SQL structure if necessary (such as adding constraints and transforming identifiers like column names) and make our API even work with non-SQL databases!&lt;br /&gt;
Yes, you heard it right: using SQL in the API doesn&#39;t mean we also need to actually &lt;em&gt;run&lt;/em&gt; it against an (ANSI-) SQL database. We could choose to generate an elasticsearch query instead, for example.&lt;/p&gt;
&lt;p&gt;Okay, enough talk about concepts. How does this look in practice in terms of actual code?&lt;/p&gt;
&lt;p&gt;I hope for you, dear reader, that you are having the luxury of working with a programming language that allows to model &lt;a href=&quot;https://en.wikipedia.org/wiki/Abstract_data_type&quot;&gt;ADTs&lt;/a&gt; in a nice way and offers a builtin technique such as pattern matching for decomposition. If you don&#39;t... well, I suggest to learn a few new languages that do support those features, it&#39;s 2023 after all. (sorry to all Go developers out there)&lt;br /&gt;
I&#39;m going to use Scala for the following code examples but you should be able to understand the code without knowing Scala.&lt;/p&gt;
&lt;h3 id=&quot;defining-the-data-structure&quot; tabindex=&quot;-1&quot;&gt;Defining the data structure &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#defining-the-data-structure&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let&#39;s stick to our bicycle example above. To keep it simple, we will only want to use SQL for the filtering part.&lt;/p&gt;
&lt;p&gt;How would such an SQL filter look like? As a full SQL query it would look like that:&lt;/p&gt;
&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; bicycles&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;material &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;steel&#39;&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;AND&lt;/span&gt; weight &lt;span class=&quot;token operator&quot;&gt;BETWEEN&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token operator&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;material &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;carbon&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;AND&lt;/span&gt; weight &lt;span class=&quot;token operator&quot;&gt;BETWEEN&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;  &lt;span class=&quot;token operator&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we care about is the where-expression only:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;(material = &#39;steel&#39; AND weight BETWEEN 10 AND 20) OR (material = &#39;carbon&#39; AND weight BETWEEN 5 AND 10)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In our code we typically model such a structure with a recursive tree-structure:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Column&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 builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; And&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;left&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; right&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Or&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;left&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; right&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Between&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lower&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; IntegerValue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; upper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; IntegerValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Parenthesis&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Equals&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;column&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Column&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; ValueExpr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Expr&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// ... more expressions here for other SQL features&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; Value&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; StringValue&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Value&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; IntegerValue&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Value&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// ... more value types here for other types of values in SQL&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is all we need to describe the filter above - and other even more complicated filters as well.&lt;br /&gt;
Usually, we will not define the above data structure by ourselves. We should use a library that already gives us those definitions.&lt;/p&gt;
&lt;h3 id=&quot;processing-the-sql&quot; tabindex=&quot;-1&quot;&gt;Processing the SQL &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#processing-the-sql&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Such a library will also help us to parse the SQL, so all we really have to do is this:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; testSqlStringFromAPI&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;(material = &#39;steel&#39; AND weight BETWEEN 10 AND 20) OR (material = &#39;carbon&#39; AND weight BETWEEN 5 AND 10)&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; filterExpression&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Either&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Error&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;br /&gt;  sql_library&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parse&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;testSqlStringFromAPI&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;filterExpression &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Left&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 keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;    println&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;The SQL was invalid!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// return error 400 to the frontend here&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Right&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sqlExpression&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// This is where it gets interesting! Process the SQL here&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The last thing we have to do now is to decide, which features of SQL we want to allow in our API and also what we want to generate based on the given SQL. In the easiest case, we actually are working with an SQL database. Then we can just generate SQL again. If we were to work against an elasticsearch instance, we would generate an ES query instead.&lt;/p&gt;
&lt;p&gt;Let&#39;s assume for now, that we are not allowing or-clauses in our API yet.&lt;br /&gt;
And to keep the example small, we will just recreate the SQL as a string. In reality, we would of course build the SQL using the same library again.&lt;/p&gt;
&lt;p&gt;In the following code we traverse the SQL structure and validate/transform it in the way we need:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; columns &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; List&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;material&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;weight&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Some columns we use/allow in the API&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Recursive function to traverse the structure&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; processSqlExpr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Expr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; expr &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Column&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;columns&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contains&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        name&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; Exception&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;Column $name is unknown and not supported!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; And&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; right&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;      s&lt;span class=&quot;token string&quot;&gt;&quot;(${processSqlExpr(left)} and ${processSqlExpr(right)})&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Or&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; right&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; Exception&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Or-clauses are not supported yet!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Between&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lower&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; upper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;      s&lt;span class=&quot;token string&quot;&gt;&quot;${processSqlExpr(expr)} between ${processSqlValue(lower)} and ${processSqlValue(upper)}&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;// the following one removes double parenthesis! :-)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Parenthesis&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Parenthesis&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expr&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;=&gt;&lt;/span&gt;&lt;br /&gt;      s&lt;span class=&quot;token string&quot;&gt;&quot;(${processSqlExpr(expr)})&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Parenthesis&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;      s&lt;span class=&quot;token string&quot;&gt;&quot;(${processSqlExpr(expr)})&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Equals&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;column&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;      s&lt;span class=&quot;token string&quot;&gt;&quot;${column.name} = ${processValue(value)}&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; ValueExpr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;      processSqlValue&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; processSqlValue&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; value &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; StringValue&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;    s&lt;span class=&quot;token string&quot;&gt;&quot;&#39;$value&#39;&quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; IntegerValue&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt;&lt;br /&gt;    value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;toString&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is all we need to handle arbitrary complex filters. Let&#39;s try it out:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;processSqlExpr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;(material = &#39;steel&#39; AND weight BETWEEN 10 AND 20) OR (material = &#39;carbon&#39; AND weight BETWEEN 5 AND 10)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Error: Or-clauses are not supported yet!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;processSqlExpr&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;((material = &#39;steel&#39; AND weight BETWEEN 10 AND 20))&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Output: (material = &#39;steel&#39; and weight between 10 and 20)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// ^^^ Note how the spelling of the SQL is slightly different from the input and that we removed the double parenthesis.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we later want to add support for OR-clauses, it&#39;s as simple as changing&lt;/p&gt;
&lt;p&gt;&lt;code&gt;throw new Exception(&amp;quot;Or-clauses are not supported yet!&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;into&lt;/p&gt;
&lt;p&gt;&lt;code&gt;s&amp;quot;(${processSqlExpr(left)} or ${processSqlExpr(right)})&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In fact, we now have the ability to expose pretty much every SQL feature to our API users with almost no effort.&lt;/p&gt;
&lt;h3 id=&quot;wrapping-up&quot; tabindex=&quot;-1&quot;&gt;Wrapping up &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#wrapping-up&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Since SQL has more features and syntax than shown in the example, &lt;code&gt;processSqlExpr()&lt;/code&gt; will be a bit longer, since it has to handle more cases (or alternatively have a catch-all case that throws an error if an unsupported feature is used).&lt;/p&gt;
&lt;p&gt;As you can hopefully see here, this approach is very different from any kind of ancient string-manipulation of SQL, which is despised for good reasons.&lt;br /&gt;
Since in reality we would not really create SQL strings but build the SQL using a library, there is also no way that we would accidentally create invalid SQL or SQL that is insecure and allowing for SQL injections (e.g. by forgetting to escape strings or removing comments from the SQL).&lt;/p&gt;
&lt;p&gt;If we later want to enable more features of SQLs power, we can easily do that: and existing queries will keep working. And that also includes more complicated features like different kinds of pagination, limits, ordering, grouping, etc.&lt;/p&gt;
&lt;p&gt;Also note that we can still change the database-schema without problems, as long as we keep the &amp;quot;column-names&amp;quot; that we expose in the API the same. We will just have to map them to the new schema during our processing.&lt;/p&gt;
&lt;h2 id=&quot;hold-on!&quot; tabindex=&quot;-1&quot;&gt;Hold on! &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#hold-on!&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By now you should have a good mental model about how that approach can play out in technical terms. But it is important to understand that it is still a niche solution. It comes with some drawbacks that better be well understood!&lt;/p&gt;
&lt;h3 id=&quot;documentation-and-error-handling&quot; tabindex=&quot;-1&quot;&gt;Documentation and error-handling &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#documentation-and-error-handling&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The first one is documentation. While SQL is widely understood in general, we commonly only need a subset of SQL in the API. Which subset exactly and the restrictions that apply need to be documented well, otherwise it won&#39;t be clear from the API endpoints how the API can be used.&lt;br /&gt;
This will be less of a problem if there is only one or a few selected consumers of the API, but it&#39;s different if it is a public API or even a free public API. For the latter types of API, this approach is probably not a great solution.&lt;/p&gt;
&lt;p&gt;On top of that, if wrong/invalid SQL is provided, the error messages provided by the backend should be helpful.&lt;br /&gt;
Since the request will usually contain the SQL as a string, there is no additional structure, which means that there is little tooling support for the one who makes the request.&lt;/p&gt;
&lt;p&gt;On the good side, reading and parsing SQL is usually easier than reading and parsing big json structures. And SQL can easily be copied into an sql editor to get formatting and syntax support if needed.&lt;/p&gt;
&lt;h3 id=&quot;performance-considerations&quot; tabindex=&quot;-1&quot;&gt;Performance considerations &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#performance-considerations&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Parsing the SQL can be simple and if done right will probably have only a negligible impact on the performance of the API. But for cases where latency is critical or the mass of requests is so high that every last drop of performance matters, SQL should probably not be used.&lt;/p&gt;
&lt;p&gt;Also, just like it is a problem for graphql APIs, the possibility of DDoS attacks needs to be considered. Since SQL (in the way implemented above) allows arbitrary nesting by default, without any countermeasures (such as limiting nesting levels or the number of conditions) it can easily be abused to cause high load on the server with just a small number of requests.&lt;/p&gt;
&lt;h3 id=&quot;vendor-lock-in&quot; tabindex=&quot;-1&quot;&gt;Vendor lock-in &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#vendor-lock-in&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Even though SQL is a standard, if database specific features or functions can are exposed in the API, it will be harder to switch to a different database technology on the backend later.&lt;br /&gt;
However, this also applies to a non-SQL kind of API in the same way, so it&#39;s not strictly a drawback of SQL in the API. The difference is though that it might be tempting to allow more SQL features if the API already uses SQL and it&#39;s easy to add them.&lt;/p&gt;
&lt;h2 id=&quot;last-words&quot; tabindex=&quot;-1&quot;&gt;Last words &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/sql-api/#last-words&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Usually, I would expect that most APIs don&#39;t require the flexibility that SQL offers. And using SQL has been despised by people for the longest time, probably for good reasons at the time.&lt;br /&gt;
On the other hand, not using a solution that is as powerful and flexible as SQL is a recipe to reinvent the wheel and create a lot of accidental complexity in the code base &lt;em&gt;if&lt;/em&gt; the flexibility is required by the API users.&lt;br /&gt;
And with the techniques shown, it is safe and convenient to make use of its power.&lt;/p&gt;
&lt;p&gt;I hope this article has convinced you not to despise such a solution by default, but weight he pros and cons carefully when you have a situation at hand where the API is considerable complex.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Scala&#39;s great ecosystem</title>
		<link href="https://valentin.willscher.de/posts/scala-praise/"/>
		<updated>2023-12-22T00:00:00Z</updated>
		<id>https://valentin.willscher.de/posts/scala-praise/</id>
		<content type="html">&lt;h2 id=&quot;nothing-ever-work...-mostly&quot; tabindex=&quot;-1&quot;&gt;Nothing ever work... mostly &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-praise/#nothing-ever-work...-mostly&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I often feel I want to rant about how &amp;quot;nothing ever works&amp;quot; in tech.&lt;br /&gt;
But today is one of those rare days when I need to shout out to those people in tech who make my life so much easier: the creators of Scala and especially its great ecosystem, in particular &lt;a href=&quot;https://zio.dev/&quot;&gt;ZIO&lt;/a&gt;, &lt;a href=&quot;https://ghostdogpr.github.io/caliban/&quot;&gt;caliban&lt;/a&gt; and &lt;a href=&quot;https://http4s.org/&quot;&gt;http4s&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-challenge&quot; tabindex=&quot;-1&quot;&gt;The challenge &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-praise/#the-challenge&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Recently I&#39;ve been working on a web application for a client.&lt;br /&gt;
This application is a classical analytics tool that displays charts and tables.&lt;br /&gt;
What makes it stand out a bit from similar tools is the number of ways in which the user can explore the data, including selecting and combing various filters dynamically, applying grouping, time-ranges, drilling down, etc.&lt;br /&gt;
Furthermore, users can only see specific data depending on their roles, so there is no way the application can allow the user access to the underlying data directly (such as tools like tableau or looker do) which would makes things much simpler.&lt;/p&gt;
&lt;p&gt;In consequence, there is a backend system with a graphql API that allows the frontend to request the different kinds of data (called &amp;quot;metrics&amp;quot;) that the frontend needs and in which shape it needs them in.&lt;br /&gt;
For better or worse, the backend then takes such a request and smartly generates SQL queries which are executed by a Postgres database.&lt;/p&gt;
&lt;p&gt;The SQL queries that are generated depend on the request. But one thing is important: for performance reasons one request will contain multiple metrics.&lt;br /&gt;
And because similar metrics can be resolved by a single SQL query (e.g. because they use the same table), they will be grouped together in the SQL to improve performance and reduce database load.&lt;br /&gt;
Within the backend (but transparent to the frontend) the structure looks something like that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[metric1, metric2, metric4] -&amp;gt; sql1
[metric3, metric6]          -&amp;gt; sql2
[metric5, metric7, metric8] -&amp;gt; sql3
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In other words, multiple SQL queries will be executed for a single graphql request.&lt;/p&gt;
&lt;p&gt;Experienced developers can immediately tell what this means: if there are 10 SQL queries generated and 9 of them resolve really fast but the last query is slow, then this one slow query will delay everything since it has to be completed before the graphql request can be responded to by the backend.&lt;br /&gt;
This leads to a bad UX where the user waits for all their results for a long time, even though they could already see 90% of their requested numbers while waiting for the last 10%.&lt;/p&gt;
&lt;p&gt;This problem had to be tackled.&lt;/p&gt;
&lt;h3 id=&quot;graphql-subscriptions-to-the-rescue&quot; tabindex=&quot;-1&quot;&gt;Graphql subscriptions to the rescue &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-praise/#graphql-subscriptions-to-the-rescue&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There are certainly different ways to deal with that problem, including scaling up the database or even changing database technology completely.&lt;br /&gt;
However, if it were just possible to return the already finished partial results to the frontend, that would already improve the UX drastically with little effort.&lt;/p&gt;
&lt;p&gt;Luckily I&#39;m not the first one to deal with this kind of problem. Graphql has a solution builtin: &lt;a href=&quot;https://www.apollographql.com/docs/react/data/subscriptions/&quot;&gt;subscriptions&lt;/a&gt;.&lt;br /&gt;
It allows the backend to use websockets for asynchronous 2-way communication between backend and frontend. And that also means the backend can send data to the frontend in a streaming way. Just what I needed.&lt;/p&gt;
&lt;p&gt;Since I had never used websockets before, I was wondering how difficult it would be to get the backend to support it.&lt;br /&gt;
To do so, three parts where necessary:&lt;/p&gt;
&lt;p&gt;1.) I had to rewrite the backend code that was creating and executing the SQL and then turning it into a proper response for the frontend.&lt;br /&gt;
This code was already written with &lt;a href=&quot;https://zio.dev/&quot;&gt;ZIO&lt;/a&gt; in an async way, but it just awaited all SQL queries to finish before processing the results.&lt;br /&gt;
This had to be turned into a streaming approach using &lt;a href=&quot;https://zio.dev/reference/stream/&quot;&gt;ZIO Streams&lt;/a&gt; so that already finished SQL queries would be processed and returned to the frontend immediately without waiting for the other SQL queries.&lt;/p&gt;
&lt;p&gt;2.) The graphql API generated by &lt;a href=&quot;https://ghostdogpr.github.io/caliban/&quot;&gt;caliban&lt;/a&gt; had to be extended to support this kind of subscription. This essentially meant adapting the existing query and turning it into a streaming subscription by using the logic from step 1.).&lt;/p&gt;
&lt;p&gt;3.) The webserver configuration had to be changed to support websockets for the new graphql subscription and be made work together with the graphql library.&lt;br /&gt;
Of course existing features for regular http-requests such as authentication, logging, metrics etc. should also work for websockets.&lt;/p&gt;
&lt;h3 id=&quot;the-happy-surprise&quot; tabindex=&quot;-1&quot;&gt;The happy surprise &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-praise/#the-happy-surprise&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When it comes to dealing with a new technology that is rather niche while having to get multiple libraries to talk to each other and work together, I&#39;m usually quite skeptical. Those tasks often become a time sink.&lt;/p&gt;
&lt;p&gt;That&#39;s why I was very positively surprised when I managed to finish all 3 steps in just half a day. And that included having to downgrade the version of &lt;a href=&quot;https://http4s.org/&quot;&gt;http4s&lt;/a&gt; to the latest stable version (instead of the previously the &amp;quot;bleeding edge&amp;quot; milestone releases).&lt;br /&gt;
This forced a bigger refactoring, but it allowed me to use an integration between caliban and http4s so that I only had to write a few lines of code to get the websockets to work. Thanks to the caliban folks for providing that one!&lt;/p&gt;
&lt;p&gt;I then spent the rest of the day trying to get our already setup &lt;a href=&quot;https://github.com/graphql/graphiql&quot;&gt;graphiql&lt;/a&gt; to work with new websockets API... but that&#39;s a different story.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;For me, two things are really remarkable here.&lt;/p&gt;
&lt;p&gt;First, Scala&#39;s powerful type-system is often disregarded as academic and too complex with little practical benefit.&lt;br /&gt;
But here it shows it&#39;s power, because it enables such a great ecosystem in which libraries that know nothing of each other can be made to work together with just one line of imports and sometimes a few extra lines for configuration or a small separate dependency (which can be provided by a totally separate party).&lt;br /&gt;
This is often missed by people: the type of a programming language has a huge impact on the quality of its ecosystem.&lt;/p&gt;
&lt;p&gt;Second, I find it amazing that I can rewrite a crucial piece of the application logic to work in a lazily-streaming way, downgrade the http library, add a new project dependency and integrate it into the code, glue things together, then fix the millions of compile errors and then... it just works and runs all smoothly.&lt;br /&gt;
There was no manual or automated testing or other kind of trial&amp;amp;error during the whole process - just fixing compile errors and then on the first run it all worked exactly as expected and the data was streamed lazily just like I planned (which I could confirm after being able to fix graphiql).&lt;/p&gt;
&lt;p&gt;And while it&#39;s certainly not hard to set up some graphql subscription POC in almost any language / ecosystem from scratch, it is a whole different story to do that within an existing application and having to apply quite the refactoring for it while not breaking anything in the process.&lt;/p&gt;
&lt;p&gt;So for me, the Scala way of doing things is not only a huge time saver and makes me super productive.&lt;br /&gt;
It also just feels much better than running and fixing tests one by one or even running the application and testing it manually, just to find that something breaks at runtime.&lt;br /&gt;
Even just the pleasure of this way of working makes learning some harder concepts of the Scala language more than worth it.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Context-dependant code is better than its reputation</title>
		<link href="https://valentin.willscher.de/posts/contextual-syntax/"/>
		<updated>2023-02-11T00:00:00Z</updated>
		<id>https://valentin.willscher.de/posts/contextual-syntax/</id>
		<content type="html">&lt;p&gt;Should a programming language allow to overload operators? Should it allow to use symbols for method-names and variables? And is it okay if the same piece of code behaves differently in different places, depending on its surroundings/context?&lt;br /&gt;
Ask those questions and enjoy a never-ending flame war among software developers.&lt;/p&gt;
&lt;h2 id=&quot;contexts-outside-of-programming&quot; tabindex=&quot;-1&quot;&gt;Contexts outside of programming &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/contextual-syntax/#contexts-outside-of-programming&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To get right to the point: I believe it is a good thing if a language allows to have (explicit) contexts which can change semantics of code and give meaning to symbols and even &amp;quot;overload&amp;quot; them. My reasoning is that we, as humans, are used to act differently depending on our context all the time. And we can take advatange of this built-in optimization of our brains to increase productivity.&lt;/p&gt;
&lt;p&gt;We already do that outside of programming. Uniforms are an example. They don&#39;t just allow everyone to recognize someone&#39;s function or position; they also remind the wearer of the context they are currently operating in. A judge is reminded that they are now supposed to act as a judge and not just as themselves, reinforcing fair decision-making.&lt;/p&gt;
&lt;p&gt;Something that maybe hits closer to home are pyjamas. At least for me, when wearing them I get into a very different mood than when wearing stiff and formal clothes. It makes it easier for me to fall asleep as well. On the other hand, working in pyjama feels just wrong. Music and scents are yet another feature that can have similar impacts. And the list goes on.&lt;/p&gt;
&lt;h2 id=&quot;contexts-in-programming&quot; tabindex=&quot;-1&quot;&gt;Contexts in programming &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/contextual-syntax/#contexts-in-programming&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So how is this relevant in programming? Well, when programming we do two things. We express our intent/thoughts as code in a way that 1.) the computer understands it but also 2.) ourselves and others can understand it later. The more concise and precise we describe the &lt;em&gt;real thing&lt;/em&gt; the easier it is to understand and change the code.&lt;/p&gt;
&lt;p&gt;In the real world there are many symbols have different meaning depending on the context.&lt;/p&gt;
&lt;p&gt;For instance, what does &lt;code&gt;5 ± 2&lt;/code&gt; mean? Without context that&#39;s hard to tell. Does it mean &lt;code&gt;3 or 7&lt;/code&gt;? Does it mean &lt;code&gt;5 with a tolerance of 2&lt;/code&gt; or does it maybe mean &lt;code&gt;A mean of 5 with a deviation of 2&lt;/code&gt;? The &lt;a href=&quot;https://en.wikipedia.org/wiki/Plus%E2%80%93minus_sign&quot;&gt;plus-minus sign has many meanings&lt;/a&gt;, depending on the context.&lt;/p&gt;
&lt;p&gt;The same is true for many other domains, not just mathematical notations, but let&#39;s stick to that for now as an easy to understand example.&lt;/p&gt;
&lt;p&gt;Of course, as developers we don&#39;t necessarily have to follow all conventions and notations of the real world. And sometimes we deliberately choose not to. But &lt;em&gt;being able&lt;/em&gt; to stay very close to business-lingo in our code can definitely be very helpful. It reduces friction when encoding business requirements into code and can make code more concise in general.&lt;/p&gt;
&lt;h2 id=&quot;usage-in-practice&quot; tabindex=&quot;-1&quot;&gt;Usage in practice &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/contextual-syntax/#usage-in-practice&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;How does it look like if we try to make our code be context dependant?&lt;br /&gt;
Most programming languages actually don&#39;t support this or at least make it very hard and unergonomic. But there are some languages that are great for it. &lt;a href=&quot;https://www.scala-lang.org/&quot;&gt;Scala&lt;/a&gt; is such a language. It embraces contexts and makes them ergonomic to use while making it hard to shoot yourself into the foot.&lt;/p&gt;
&lt;p&gt;So for the following real-life examples, we&#39;re going to use Scala.&lt;/p&gt;
&lt;h3 id=&quot;using-to-describe-choices&quot; tabindex=&quot;-1&quot;&gt;Using ± to describe choices &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/contextual-syntax/#using-to-describe-choices&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let&#39;s say we are dealing with a business domain where we often have to deal with choices and our business experts use the ± in all their technical documents.&lt;br /&gt;
How can we make our code match the domain?&lt;/p&gt;
&lt;p&gt;First we define what a choice is&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;enum Choice&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Numbers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lower&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; upper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Choices&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lower&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; upper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A choice can be 2 numbers (e.g. &lt;code&gt;5 ± 2&lt;/code&gt; would be &lt;code&gt;3&lt;/code&gt; for lower or &lt;code&gt;7&lt;/code&gt; for upper).&lt;br /&gt;
But if we have a choice and work with it, we might end up with a choice of choices, e.g. &lt;code&gt;((5 ± 2) ± 1)&lt;/code&gt; would be either &lt;code&gt;3 ± 1&lt;/code&gt; or &lt;code&gt;7 ± 1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We are working with regular integer values (&lt;code&gt;Int&lt;/code&gt;) from the standard library. In our code we want to write &lt;code&gt;5 ± 2&lt;/code&gt; but the type &lt;code&gt;Int&lt;/code&gt; is already defined. Luckily Scala supports statically typed extension methods:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;extension &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; ±&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;diff&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Numbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Numbers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;    lower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; diff&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    upper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; diff&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This already let&#39;s us to write code that is valid and works as expected:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;print&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; ± &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// prints: Numbers(3,7)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make it a bit more interesting we also want to work on choices of choices, i.e. calling &lt;code&gt;±&lt;/code&gt; not only on numbers but on choices themselves. To allow that, we add another method:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;extension &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;choice&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; ±&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;diff&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Choices &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; choice &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Numbers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; upper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Choices&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;      lower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lower ± diff&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;      upper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; upper ± diff&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Choices&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lower&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; upper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Choices&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;      lower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lower ± diff&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;      upper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; upper ± diff&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could define this code top-level and just start using it in our project - but since we want to create an explicit business context, we move the whole logic into its own &amp;quot;context&amp;quot; object (or module):&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt; choiceContext &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  extension &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&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;br /&gt;&lt;br /&gt;  extension &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;choice&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&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;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The encapsulating object really just acts as a namespace that needs to be explicitly imported. If we just try to use the new syntax in a project then it will fail by default:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; choice &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; ± &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;br /&gt;print&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;choice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fails with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;value ± is not a member of Int
   val choice = 5 ± 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is good because without further information what does it mean when we use &lt;code&gt;±&lt;/code&gt;?&lt;br /&gt;
We should be clear about what we mean when we use &lt;code&gt;±&lt;/code&gt; and we can do so by telling the compiler (and thus other developers) that we are working within the &amp;quot;context of choice&amp;quot;. Then it will compile and behave as expected:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;choiceContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;_ &lt;span class=&quot;token comment&quot;&gt;// Make it explicit that we want to be working in the choice context&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; choice &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; ± &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;br /&gt; println&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;choice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// prints: Numbers(3,7)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; moreChoice &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; choice ± &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;br /&gt; println&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moreChoice&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// prints: Choices(Numbers(2,4),Numbers(6,8))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now work with a nice and concise mathematical notation and extend it with more functionality to match the lingo of our domain experts. Who knows, the code might get so close to what those experts are used that they can understand the source code or even write it themselves without the help of a developer. (Let me dream of it at least...)&lt;/p&gt;
&lt;h3 id=&quot;using-in-another-context&quot; tabindex=&quot;-1&quot;&gt;Using ± in another context &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/contextual-syntax/#using-in-another-context&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It probably does not happen very often, but what if we require to use &lt;code&gt;±&lt;/code&gt; in a second context, like the context of tolerance like in physical engineering?&lt;br /&gt;
We might want to write code like &lt;code&gt;val tolerance = (5 ± 2)&lt;/code&gt; and then &lt;code&gt;if( 42.exceeds(tolerance) )&lt;/code&gt; or similar, because that&#39;s what our domain exports do.&lt;/p&gt;
&lt;p&gt;We can do that in the same way as before:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; Tolerance&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;from&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt; toleranceContext &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  extension &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; ±&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;diff&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tolerance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Tolerance&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;      from &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; diff&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;      to &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; diff&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;toleranceContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;_&lt;br /&gt;&lt;br /&gt;print&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; ± &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// prints: Tolerance(3, 7)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first question that should pop up in your head is: can we use two contexts at the same time?&lt;br /&gt;
And sure, we can use both contexts or even more of them at the same time!&lt;/p&gt;
&lt;p&gt;But then what happens if we mess up? In this example we use &lt;code&gt;±&lt;/code&gt; in both contexts - so what will happen if we call &lt;code&gt;±&lt;/code&gt; on a number? Will the result mauybe depend on the order of imports?&lt;br /&gt;
Fortunately it won&#39;t (this would be insane anyways). The compiler will refuse to compile:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;choiceContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;_&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;toleranceContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;_&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; ± &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fails with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;value ± is not a member of Int.
An extension method was tried, but could not be fully constructed:

    toleranceContext.±(5)    failed with

        Reference to ± is ambiguous,
        it is both imported by import choiceContext._
        and imported subsequently by import toleranceContext._
val result = 5 ± 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Great! At least it&#39;s hard to make any mistakes by accidentally screwing up context imports.&lt;/p&gt;
&lt;p&gt;So what do we do if we have two contexts that just share one common symbol that we want to use at some point? Luckily we are not forced to shenanigans like splitting up our code and then using just a single context for a specific part.&lt;br /&gt;
Instead, we can tell the compiler explicitly to use the version of &lt;code&gt;±&lt;/code&gt; that we are interested in:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; choiceContext&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;5&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;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// a bit ugly but works&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are other ways to resolve this situation and make it more ergonomic, but let&#39;s not go down the rabbit hole here.&lt;/p&gt;
&lt;h3 id=&quot;a-word-about-naming&quot; tabindex=&quot;-1&quot;&gt;A word about naming &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/contextual-syntax/#a-word-about-naming&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;So far I think this looks all great, and I hope you agree me. But you might still be sceptical for a different reason, and rightfully so!&lt;/p&gt;
&lt;p&gt;Using symbols as names and identifiers in code is not allowed or discouraged in many programming languages and that has a history. And while I believe it is good to be able to use them, one should do so with great care.&lt;br /&gt;
With great power comes great responsibility. When using a symbol that is not widely used/understood then my strong recommendation is to always create a method with a readable name and make the symbolic name just an alias.&lt;/p&gt;
&lt;p&gt;For instance, in the case of &lt;code&gt;±&lt;/code&gt; I would write the following code in real life:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;extension &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Alias for plusminus&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; ±&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;diff&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Numbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; plusminus&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;diff&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; plusminus&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;diff&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Numbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Choice&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Numbers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;    lower &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; diff&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    upper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; diff&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows to use both &lt;code&gt;5 ± 2&lt;/code&gt; as well as &lt;code&gt;5.plusminus(2)&lt;/code&gt; and allows to easily find a name that can be searched for or pronounced more easily.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/contextual-syntax/#conclusion&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It will certainly stay a subjective matter, but if a programming language offers good support and is statically typed then it becomes possible to make code much more concise and readable while keeping it safe from accidental mistakes.&lt;br /&gt;
In such a case I find there is very little reason to restrict the usage of symbols and context-dependant code behaviour.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Functional error-handling with stack traces</title>
		<link href="https://valentin.willscher.de/posts/scala-errorhandling/"/>
		<updated>2022-12-17T00:00:00Z</updated>
		<id>https://valentin.willscher.de/posts/scala-errorhandling/</id>
		<content type="html">&lt;p&gt;Over the time I have developed a go-to approach for error-handling in my pure functional Scala projects.&lt;/p&gt;
&lt;p&gt;I&#39;ve seen developers thinking that exceptions and their benefits don&#39;t play well together with a (pure) functional programming style. But this is a wrong assumption. Functional error-handling and exceptions can be combined to get the best of both worlds and here I&#39;ll show how.&lt;br /&gt;
In my examples I use the &lt;a href=&quot;https://zio.dev/&quot;&gt;ZIO&lt;/a&gt; library, but it works similar with &lt;a href=&quot;https://typelevel.org/cats-effect&quot;&gt;Cats-Effect&lt;/a&gt; or other async/effect libraries.&lt;/p&gt;
&lt;h2 id=&quot;why-exceptions&quot; tabindex=&quot;-1&quot;&gt;Why exceptions? &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#why-exceptions&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some developers use an error-handling approach that relies on custom defined classes/types which are unrelated to Exceptions. They return those errors using a &lt;em&gt;Result&lt;/em&gt; type such as Scala&#39;s builtin &lt;code&gt;Either&lt;/code&gt;. While this works, it commonly has the severe drawback of losing the ability to inspect the stack trace when debugging an error.&lt;/p&gt;
&lt;p&gt;Having a meaningful stack trace can make the difference between reading the logs for a minute or having to dig into a problem for days. They are just too valuable not to use them, so I always use exceptions for my error-types.&lt;/p&gt;
&lt;p&gt;I start with a common exception-class for the whole project. It gets a unique name, is easy to create and spot in logs / stack traces.&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Exception&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt; GeneralException &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using it is simple.&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;boom&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or, in a pure functional style using ZIO as the &lt;em&gt;Result&lt;/em&gt; type:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;condition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  ZIO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fail&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;boom&quot;&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;br /&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;&lt;br /&gt;  ZIO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;succeed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is generally much better to define and use semantically meaningful error-types. But everyone is lazy sometimes. In those cases, using &lt;code&gt;GeneralException&lt;/code&gt; directly is still much better than relying on Java&#39;s builtin &lt;code&gt;Exception&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The next step is therefore to specific errors for all the things that can go wrong. Those help to make code easier to read and also allow to catch and handle only specific errors while passing along others.&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; Error &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; UserNotFound&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;User with id $id not found&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; Error&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; SendingEmailFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;Sending email to $email failed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; Error&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; SendingSmsFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;phoneNumber&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PhoneNumber&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;Sending SMS to $phoneNumber failed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; Error&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; SendingNotificationFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;Notifying user with id $id failed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; Error&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example I am defining just a flat list of errors, but this can totally become a complex hierarchy with multiple common error-traits. You might have noticed that the &lt;code&gt;cause&lt;/code&gt; parameter is set to null by default - something we usually try to avoid in the Scala world. However, in this case I make an exception for improved ergonomics. Error-handling is really one of those things that need to be as easy as possible. Otherwise, people tend to take shortcuts.&lt;/p&gt;
&lt;h2 id=&quot;using-it-in-code&quot; tabindex=&quot;-1&quot;&gt;Using it in code &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#using-it-in-code&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is how it looks when I write my business logic using different methods that throw the errors above.&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; notifyUser&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; notificationResult &lt;span class=&quot;token operator&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;br /&gt;    user &lt;span class=&quot;token keyword&quot;&gt;&amp;lt;-&lt;/span&gt; getUser&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    notificationSentTimestamp &lt;span class=&quot;token keyword&quot;&gt;&amp;lt;-&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;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;preferences&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prefersEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      sendEmail&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&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;&lt;br /&gt;      sendSms&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phoneNumber&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; notificationSentTimestamp&lt;br /&gt;&lt;br /&gt;  notificationResult&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mapError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e &lt;span class=&quot;token keyword&quot;&gt;=&gt;&lt;/span&gt; SendingNotificationFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I find this pure-functional monadic approach of error-handling quite elegant.&lt;/p&gt;
&lt;p&gt;In the example, &lt;code&gt;getUser&lt;/code&gt; might fail with a &lt;code&gt;UserNotFound&lt;/code&gt;-error and &lt;code&gt;sendEmail&lt;/code&gt; and &lt;code&gt;sendSms&lt;/code&gt; might fail with &lt;code&gt;SendingEmailFailed&lt;/code&gt; and &lt;code&gt;SendingSmsFailed&lt;/code&gt; respectively.&lt;/p&gt;
&lt;p&gt;The different actions are executed and if an error occurred then I turn it into a &lt;code&gt;SendingNotificationFailed&lt;/code&gt;-error. Wrapping errors is optional. If I were to remove this line, the resulting error-type would just be a combination of all possible errors that can occur. But it&#39;s often nicer to hide the underlying errors and make the result more meaningful - and the method-signature shorter.&lt;/p&gt;
&lt;p&gt;So what exactly is the return type of the &lt;code&gt;notifyUser&lt;/code&gt; function?&lt;br /&gt;
If I keep the last line then it is:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; notifyUser&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;SendingNotificationFailed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; NotificationSentTimestamp&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I remove it becomes:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; notifyUser&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Text&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;UserNotFound &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; SendingEmailFailed &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; SendingSmsFailed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; NotificationSentTimestamp&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I do &lt;em&gt;not&lt;/em&gt; add an explicit return type to the method, it will be inferred for me by the compiler, including all possible errors. That means, when adding more functionality later (e.g. additionally sending a push notification to the smartphone) or changing the error-handling, I won&#39;t have to refactor the whole chain of methods that call each other.&lt;br /&gt;
This is very useful, because a small change can otherwise force to refactor dozens of method signatures.&lt;/p&gt;
&lt;p&gt;Note that IDEs like IntelliJ can still show the return type inline, so even if it is not explicitly annotated, it is still visible and can serve as documentation.&lt;/p&gt;
&lt;h2 id=&quot;the-resulting-logs&quot; tabindex=&quot;-1&quot;&gt;The resulting logs &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#the-resulting-logs&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using this approach proves me with a very nice stack trace when I log an error. Most developers in the JVM world should be familiar with that.&lt;br /&gt;
Let&#39;s assume that my call to &lt;code&gt;notifyUser&lt;/code&gt; failed because the SMS could not be sent. When looking into the logs, I will see something like this:&lt;/p&gt;
&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Exception in thread &quot;main&quot; SendingNotificationFailed: Notifying user with id xxx failed&lt;br /&gt;    at MyProject.method3(MyProject.scala:19)&lt;br /&gt;    at MyProject.method2(MyProject.scala:12)&lt;br /&gt;    at MyProject.method1(MyProject.scala:8)&lt;br /&gt;Caused by: SendingSmsFailed: Sending SMS to 123456789 failed&lt;br /&gt;    at MyProject.method5(Sms.scala:143)&lt;br /&gt;    at MyProject.method4(Sms.scala:77)&lt;br /&gt;Caused by: ConnectionError: Could not connect to SMS provider XXX&lt;br /&gt;    at org.example.SmsProvider.connect(Foo.scala:123)&lt;br /&gt;    ... 2 more&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And so on. It&#39;s a nice chain of errors which makes it very easy to understand both the high-level impact and the root cause.&lt;/p&gt;
&lt;h2 id=&quot;api-errors&quot; tabindex=&quot;-1&quot;&gt;API errors &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#api-errors&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If this is some internal process in my application then this kind of error-logging can already be good enough.&lt;/p&gt;
&lt;p&gt;But usually I need to expose errors to a third party such as an external system or an end-user. In that case I typically don&#39;t want to expose internal technical details.&lt;br /&gt;
I also want to keep my API stable. Therefore, I define another layer of error-types which are describing what my API exposes.&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; ApiError&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; ApiUserNotFound&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;The user with id $id was not found&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; ApiError&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; ApiSendingNotificationFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;Notifying user with id $id was not successfull&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; ApiError&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My internal errors are created at some point during the execution and before returning a response, I turn them into API errors.&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; toApiError&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ApiError &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; e @ UserNotFound&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&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;=&gt;&lt;/span&gt; ApiUserNotFound&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; e @ SendingNotificationFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&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;=&gt;&lt;/span&gt; ApiSendingNotificationFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// ... and so on&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This looks a bit redundant but has an advantage: I can now modify my internal errors in any way I want - if I modify them in a way that would impact my API then the compiler will make me aware of it because transforming internal errors into api errors will fail to compile.&lt;/p&gt;
&lt;h2 id=&quot;adding-references-and-codes&quot; tabindex=&quot;-1&quot;&gt;Adding references and codes &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#adding-references-and-codes&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On top of that, I find it useful to add two more things: error-references and error-codes.&lt;br /&gt;
Error-references are unique identifiers that allow me to find the error in the logs.&lt;br /&gt;
Error-codes are a well-defined list where each entry describe the type of error so that an external system can react to specific errors easily.&lt;/p&gt;
&lt;h3 id=&quot;error-codes&quot; tabindex=&quot;-1&quot;&gt;Error codes &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#error-codes&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let&#39;s start with error codes. I&#39;m extending each of my ApiError types with a specific error-code:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; ErrorCode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// for readability&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;trait&lt;/span&gt; ApiError&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; ApiUserNotFound&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorCode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ErrorCode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;EC_UserNotFound&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;The user with id $id was not found&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; ApiError&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; ApiSendingNotificationFailed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; UserId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorCode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ErrorCode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;EC_NotificationError&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;Notifying user with id $id was not successfull&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; ApiError&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have used different formats here - numbers, strings, whatever fits my needs, but if I have the choice I prefer to add a prefix and use easy to read names.&lt;br /&gt;
To keep the example simple I&#39;m using strings and default-arguments here, but optimally an enum is used here to ensure that error-codes are never reused by accident.&lt;br /&gt;
The &lt;code&gt;ValueEnum&lt;/code&gt; of &lt;a href=&quot;https://github.com/lloydmeta/enumeratum&quot;&gt;Enumeratum&lt;/a&gt; can be used to do so.&lt;/p&gt;
&lt;h3 id=&quot;error-references&quot; tabindex=&quot;-1&quot;&gt;Error references &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#error-references&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Error-codes are nice to indicate the type of error, but they won&#39;t make it very easy to debug a problem when getting an error report from a user. To make my life easier in such situations I add unique references whenever an error happens.&lt;/p&gt;
&lt;p&gt;For that, I extend the original &lt;code&gt;GeneralException&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class=&quot;language-scala&quot;&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; ErrorReference &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorReference&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ErrorReference &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createReference&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; Exception&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token string&quot;&gt;&quot;$message | error-reference: $errorReference&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt; GeneralException &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; apply&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Throwable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorReference&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ErrorReference &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createReference&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 operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; GeneralException&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cause&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errorReference&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; createReference&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 operator&quot;&gt;:&lt;/span&gt; ErrorReference &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ER_&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; scala&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;util&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;alphanumeric&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;take&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&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;mkString&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Be aware that this code is not pure functional and is executes an effect at the time of the error-creation (generating a random reference). Again I believe that this is a good trade-off for the ease of use.&lt;br /&gt;
Depending on the system it is worth to spend some time to come up with an identifier format that e.g. includes information about time and hence is sortable and has fewer collisions... just in case there are a lot of errors - I hope there aren&#39;t :^).&lt;/p&gt;
&lt;p&gt;Also note that the error-reference is automatically appended to the message, so it is guaranteed to appear in the stack trace when an error is logged.&lt;/p&gt;
&lt;p&gt;I usually add this reference to my API error-types and then expose it to the end-user in case they want to report an error.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/scala-errorhandling/#conclusion&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A few best practices are violated here, including class inheritance, usage of &lt;code&gt;null&lt;/code&gt; and non-pure-functional code to create references on error-creation.&lt;br /&gt;
But overall, with only a little extra effort I get the best of both worlds: clean error-handling for both reading and usage, as well as comprehensive stack traces that make debugging easy.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Types to replace parameter names</title>
		<link href="https://valentin.willscher.de/posts/types-as-parameters/"/>
		<updated>2022-10-07T00:00:00Z</updated>
		<id>https://valentin.willscher.de/posts/types-as-parameters/</id>
		<content type="html">&lt;p&gt;It&#39;s a classical mistake. You have defined a method that accepts some parameters and you forward them to another method.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is the order of arguments really correct? Or did we by accident mix up the user and the password?&lt;/p&gt;
&lt;p&gt;After causing a bug by mixing up the parameter order, we eventually use the typesystem to our advantage to prevent this from happening again.&lt;br /&gt;
Instead of using &lt;em&gt;stringly typed&lt;/em&gt; parameters, we define proper types:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Password&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s better. Now, if the order of parameters is different between our &lt;code&gt;createUser&lt;/code&gt; method and the repository we use, we will get a compile error.&lt;br /&gt;
At least if we used actually classes and not just type aliases - but this is more of typescript-specific problem not a general one.&lt;/p&gt;
&lt;p&gt;This is cool, but when applying this style broadly, we quickly end up with quite verbose code, repeating names for both identifiers and types all over the place.&lt;/p&gt;
&lt;p&gt;One might argue that this is okay, because we might want to use the same type multiple times. For instance, if the user where to also provide an email-address for recovery, the method might look like this:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recoveryEmail&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recoveryEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, now we are back to our original problem and might mix up the regular email with the one for recovery purposes.&lt;br /&gt;
Consequently, we should make our types more precise again and have specific types for the email addresses, e.g.:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DefaultEmail&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recoveryEmail&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; RecoveryEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recoveryEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But now we also have the same kind of verbose, duplicated code again.&lt;/p&gt;
&lt;h2 id=&quot;kill-all-the-identifiers&quot; tabindex=&quot;-1&quot;&gt;Kill all the identifiers &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/types-as-parameters/#kill-all-the-identifiers&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Which brings up a question: if we meticulously follow the pattern of creating distinct types for specific entities, do we then still need identifiers at all?&lt;br /&gt;
That&#39;s an interesting thought-experiment. What if we just were to remove those parameter-identifiers from language specification alltogether?&lt;/p&gt;
&lt;p&gt;Here is how that could look like:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DefaultEmail&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; RecoveryEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DefaultEmail&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; RecoveryEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The parameter names are gone and to call the repository, we simply pass them by referring to the type-name instead.&lt;/p&gt;
&lt;p&gt;Looks quite clean if you ask me. We also have the same type-safety guarantees as before.&lt;/p&gt;
&lt;p&gt;But what about the code that we usually write within a method. We need to manipulate data, create temporary variables and so on.&lt;/p&gt;
&lt;p&gt;Here&#39;s an example with the original code:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DefaultEmail&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recoveryEmail&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; RecoveryEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; normalizedEmail &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLowerCase&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normalizedEmail&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; recoveryEmail&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We certainly need variable names here to disambiguate between the price and the discount. Imagine this to be production-code.&lt;br /&gt;
Maybe you wonder about the meaning of the number for the discount. Is that a fixed value as in $2 or is it a percentage or something else?&lt;/p&gt;
&lt;p&gt;Since we are using a typesystem we should take advantage and improve our code with meaningful types:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;price&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; discount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OrderMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tax &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&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;It&#39;s not quite obvious what &lt;code&gt;Price&lt;/code&gt; and &lt;code&gt;Distount&lt;/code&gt; are exactly, but we can easily check how they are defined.&lt;br /&gt;
The type definitions might be defined like that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Price = Money
type Discount = Money
type Money = number
type OrderMode = &amp;quot;takeout&amp;quot; | &amp;quot;eatin&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now looking at the code, it appears that we don&#39;t really &lt;em&gt;need&lt;/em&gt; the variable names anymore.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OrderMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tax &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&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;Obviously that&#39;s illegal syntax in typescript, but let&#39;s go along with it for now.&lt;br /&gt;
The next question is how the implementation would look like.&lt;br /&gt;
Somehow we need to refer to the parameters. Here&#39;s how it could work:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OrderMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tax &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; base &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Price &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OrderMode &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&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;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; base &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&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 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OrderMode &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;eatin&quot;&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;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; base &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The parameter-values are accessed just by their typenames.&lt;/p&gt;
&lt;h2 id=&quot;conflicts&quot; tabindex=&quot;-1&quot;&gt;Conflicts &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/types-as-parameters/#conflicts&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This works in the example but what if we have a method where the types are just equal? For instance division:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;minus&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 builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually, if we try really hard to remember math classes back in the day, maybe we remember that there are already terms we can use:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;minus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Minuend&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Subtrahend&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Difference &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Minuend &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Subtrahend&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But programming languages need to be practical. We don&#39;t want to define a new type for such a case everytime we encounter such a situation.&lt;br /&gt;
Even if it maybe be &amp;quot;correct&amp;quot; to choose a distinct name in those cases, it is often just not practical and will make our code bloated since we need to define the types in addition to the method.&lt;/p&gt;
&lt;p&gt;So just like we can just create identifiers out of thin air, let&#39;s allow the same for types.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;minus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Minuend&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Subtrahend&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Minuend &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Subtrahend&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, that looks like we are back to parameter names.&lt;br /&gt;
But don&#39;t forget: we changed typescript the language and removed parameter names.&lt;br /&gt;
Instead, we have just created two new types inline, as if we had defined &lt;code&gt;type Minuend = number&lt;/code&gt; before.&lt;/p&gt;
&lt;p&gt;This means we can now mix predefined types and types that we need to create on the fly:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OrderMode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;eatin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tax &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&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;Price&lt;/code&gt; and &lt;code&gt;Discount&lt;/code&gt; have been defined in advance, but maybe &lt;code&gt;OrderMode&lt;/code&gt; wasn&#39;t. So we create it inline.&lt;/p&gt;
&lt;h2 id=&quot;the-call-side&quot; tabindex=&quot;-1&quot;&gt;The call-side &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/types-as-parameters/#the-call-side&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Until now, there isn&#39;t really a big advance.&lt;br /&gt;
The method signature gets a little bit shorter and it nudges us to use distinct, semantic types instead of generic types but that&#39;s about it.&lt;/p&gt;
&lt;p&gt;The real difference happens at the call-side.&lt;/p&gt;
&lt;p&gt;First of all, since our types are unique, the ordering stops mattering.&lt;br /&gt;
We can freely reorder our parameters both at call-side and at definition side.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; price&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Price &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; discount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Discount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// that&#39;s fine&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;// Just as good&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; discount&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you feel that it is inconsequent to remove parameter names but still use variables then I can only say that you have a very good gut feeling indeed.&lt;br /&gt;
I&#39;ll cover this later on, but let&#39;s keep on with this style for a bit.&lt;/p&gt;
&lt;p&gt;Of course, if we are in the context of another method, maybe price and discount are already parameters!&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calculateFinalPrice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; CustomerPreferences&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Money &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Price &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; CustomerPreferences&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;orderMode&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;Wait a second - how would the compiler know, that the result can be the &lt;code&gt;Money&lt;/code&gt; type?&lt;br /&gt;
And also, if we have a method defined with semantic types that are both numbers, how to turn numbers into those specific types at call-site?&lt;/p&gt;
&lt;h2 id=&quot;type-refinement-and-coercion&quot; tabindex=&quot;-1&quot;&gt;Type refinement and coercion &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/types-as-parameters/#type-refinement-and-coercion&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are two parts here. Let&#39;s look at the call-site first.&lt;/p&gt;
&lt;p&gt;If want to call our method with two hardcoded numbers in code, how would that look like?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;calculateTax(40, 15, &amp;quot;takeout&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This obviously won&#39;t do it.&lt;br /&gt;
In the current typescript world we could do something like that, but not in our new types-only world.&lt;br /&gt;
We have turn the values of type number into the correct types by converting them explicitly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;`calculateTax(40 as Price, 15 as Discount, &amp;quot;takeout&amp;quot; as OrderMode)`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are reusing typescript&#39;s &lt;code&gt;as&lt;/code&gt; keyword here. The compiler checks if &lt;code&gt;Price&lt;/code&gt; is a specialized type of &lt;code&gt;number&lt;/code&gt; and converts it.&lt;br /&gt;
This also gets us back to being able to reorder parameters as we wish without changing semantics.&lt;/p&gt;
&lt;p&gt;It should be noted that this is only necessary when going from a general type like &lt;code&gt;number&lt;/code&gt; to a more specialized like &lt;code&gt;Price&lt;/code&gt;.&lt;br /&gt;
Going from &lt;code&gt;Price&lt;/code&gt; to &lt;code&gt;Money&lt;/code&gt; or from one of those to &lt;code&gt;number&lt;/code&gt; would be automatic. Subtyping rules apply.&lt;/p&gt;
&lt;p&gt;This might seem annoying at first, but such conversions become quite rare in most code if types are well utilized and reused.&lt;br /&gt;
It is a good incentive to keep the defined types tidy and organized and is incredible for self-documenting code (even though it can&#39;t replace all documentation obviously).&lt;/p&gt;
&lt;h2 id=&quot;what-about-variables-and-return-types&quot; tabindex=&quot;-1&quot;&gt;What about variables and return types? &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/types-as-parameters/#what-about-variables-and-return-types&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So far we have made a thought-experiment mainly about changing method signatures. Why not extend this to variables as well? And also return types. I don&#39;t see why not.&lt;/p&gt;
&lt;p&gt;Going back to a previous example, which we have to refine now:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; price&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Price &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; discount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Discount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; OrderMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can also reduce this to:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Price &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Discount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; OrderMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we could reduce it even further:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Price&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Discount&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;calculateTax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; discount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;takeout&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; OrderMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;class-fields-and-names-and-method-names&quot; tabindex=&quot;-1&quot;&gt;Class fields and names and method names &lt;a class=&quot;direct-link&quot; href=&quot;https://valentin.willscher.de/posts/types-as-parameters/#class-fields-and-names-and-method-names&quot; aria-hidden=&quot;true&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Why stop here?&lt;/p&gt;
&lt;p&gt;Instead of defining a user as&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&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;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lastName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;we write it like that in our new world:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; FirstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; LastName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&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;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firstName &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; FirstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lastName &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; LastName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can probably see, this looks quite strange. And that is good! It is an indication of bad design.&lt;br /&gt;
Instead of doing the transformation ourselves, we should push the types out into the world!&lt;br /&gt;
In a class definition, the compiler would do that for us:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// We just created two new public and refined types&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; FirstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; LastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FirstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; LastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FirstName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; FirstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LastName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LastName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we create users and methods with those types:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;doe&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; FirstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;john&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; LastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; John&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;switchNames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; User &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FirstName &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; LastName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; User&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LastName &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; FirstName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;switchName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;john&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; CorrectedJohn&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
</feed>
