<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Exploring best practices]]></title><description><![CDATA[Exploring best practices]]></description><link>https://durre.se</link><generator>RSS for Node</generator><lastBuildDate>Thu, 21 May 2026 17:09:48 GMT</lastBuildDate><atom:link href="https://durre.se/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Query Splitting Magic: Tackling Multi-Topic Chatbot Conversations]]></title><description><![CDATA[One of the first problems you have to solve when building your first chatbot, is to create embeddings for your knowledge, store them in a database and find the relevant knowledge for the question.
That works well for a while, until you get users that...]]></description><link>https://durre.se/query-splitting-magic-tackling-multi-topic-chatbot-conversations</link><guid isPermaLink="true">https://durre.se/query-splitting-magic-tackling-multi-topic-chatbot-conversations</guid><category><![CDATA[AI]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[chatbot]]></category><category><![CDATA[claude.ai]]></category><dc:creator><![CDATA[Andreas Du Rietz]]></dc:creator><pubDate>Tue, 29 Apr 2025 20:24:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/eQ2Z9ay9Wws/upload/c45d8e30252c92bb1b61d735406fbfb8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the first problems you have to solve when building your first chatbot, is to create embeddings for your knowledge, store them in a database and find the relevant knowledge for the question.</p>
<p>That works well for a while, until you get users that pose multiple questions in one single message. <code>Hey! Do you happen to know what the weather is like in SF? Btw, when did WW2 end and why do I start crying when I peel an onion?</code></p>
<p>Three completely unrelated questions. It’s unlikely that you would find good matches of knowledge if you simply turn this entire message into an embeddings and do a vector search. Unless you extract all the different queries separately and get knowledge for each query.</p>
<p>Here’s one code example of doing just that. It uses Typescript, Vercel AI SDK and Claude 3.7 Sonnet as LLM.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> getPrompt = <span class="hljs-function">(<span class="hljs-params">
  targetLanguage: <span class="hljs-built_in">string</span>,
  chatHistory: CoreMessage[]
</span>) =&gt;</span> <span class="hljs-string">`Generate concise search queries for an embeddings database using cosine similarity based on this chat history:

&lt;chat_history&gt;
<span class="hljs-subst">${stringifyChatHistory(chatHistory)}</span>
&lt;/chat_history&gt;

Guidelines:
- Focus on most recent intent/topics
- Ignore previous irrelevant topics
- For "what is X" questions, NEVER include potential answers

Multiple queries (max 3) ONLY for COMPLETELY UNRELATED topics:
- One query for single topics with multiple aspects
- Combine related aspects (e.g., "studying tips", "study techniques") into ONE query

For each query:
- Keep very brief queries intact
- Summarize longer queries to core intent
- Focus on key terms representing the topic
- Write in <span class="hljs-subst">${targetLanguage}</span>
- NEVER include potential answers

Examples:
"User: What's the weather? Assistant: It's sunny. User: Great. How about movies?" → "popular movies current releases"
"User: Tell me about quantum computing and banana bread?" → Two queries: "quantum computing basics" and "banana bread recipe ingredients" 
"User: What is the capital of Sweden?" → "huvudstad Sverige" (NOT "Stockholm huvudstad Sverige")
"User: How do I start a business with registration, marketing, and funding?" → "how to start a business registration marketing funding steps"`</span>;

<span class="hljs-keyword">const</span> QuerySchema = z.object({
  queries: z
    .array(z.string())
    .min(<span class="hljs-number">1</span>)
    .max(<span class="hljs-number">3</span>)
    .describe(
      <span class="hljs-string">"The search queries to be used doing the embeddings search. Return between 1-3 queries for each different topic. Only one query per topic."</span>
    ),
});

<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> generateObject({
    model,
    prompt: getPrompt(targetLanguage, [ role: <span class="hljs-string">"user"</span>, content: <span class="hljs-string">"Hey! Do you happen to know what the weather is like in SF? Btw, when did WW2 end and why do I start crying when I peel an onion?"</span>]),
    schema: QuerySchema,
  });

<span class="hljs-comment">// Example result</span>
<span class="hljs-comment">//[</span>
<span class="hljs-comment">//    'current weather in San Francisco',</span>
<span class="hljs-comment">//    'when did World War 2 end',</span>
<span class="hljs-comment">//    'why onions make people cry'</span>
<span class="hljs-comment">//]</span>

<span class="hljs-comment">// Get search results for each of the queries</span>
<span class="hljs-keyword">const</span> knowledge = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(result.object.queries.map(findKnowledge))
</code></pre>
<p>Some key remarks here:</p>
<ul>
<li><p>We use a <code>targetLanguage</code> for the queries. The language would be the same as we write the content in. There are embeddings models that handle multiple languages, but I feel I get a better result when I keep the original content and the search queries in the same language.</p>
</li>
<li><p>If you’re not careful the LLM will likely produce multiple queries on the same topic, which is counter productive to what we want to achieve.</p>
</li>
</ul>
<h2 id="heading-the-takeaway">The Takeaway</h2>
<p>By implementing intelligent query extraction, your chatbot transforms from a one-dimensional responder into a conversation partner that understands context and handles complexity. This approach not only improves the accuracy of responses but also creates a more natural user experience - even when your users jump between asking about the weather in San Francisco, World War II facts, and the science of onion-induced tears in a single breath.</p>
<p>Having a large knowledge base is of no use, if you don’t find the relevant parts for each query.</p>
]]></content:encoded></item><item><title><![CDATA[You dont need to fear recursion]]></title><description><![CDATA[All though, If I'm being honest. The concept of recursion was an aqcuired taste for me. It took a class of functional programming, where at least half of the assignements involved recursion for it to "click". Today I can find recursion to be concise ...]]></description><link>https://durre.se/you-dont-need-to-fear-recursion</link><guid isPermaLink="true">https://durre.se/you-dont-need-to-fear-recursion</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Andreas Du Rietz]]></dc:creator><pubDate>Thu, 11 Jan 2024 17:25:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/YmULswIbc3I/upload/3b2903ad5ded7d39efcc73bcc87357de.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>All though, If I'm being honest. The concept of recursion was an aqcuired taste for me. It took a <a target="_blank" href="https://www.coursera.org/specializations/scala">class of functional programming</a>, where at least half of the assignements involved recursion for it to "click". Today I can find recursion to be concise and elegant way of solving certain problems.</p>
<p>Today I came across such a problem. This is similar to what I came across. <strong>getAllItems</strong> is a function that should fetch 100 items at a time, until there are no more items to fetch.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> getAllItems = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">let</span> maxItems = <span class="hljs-number">100</span>;
  <span class="hljs-keyword">let</span> page = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">let</span> allItems = [];

  <span class="hljs-keyword">while</span> (maxItems === <span class="hljs-number">100</span>) {
    <span class="hljs-keyword">const</span> items = <span class="hljs-keyword">await</span> getItemsPage(page, maxItems);
    <span class="hljs-keyword">if</span> (items.length &lt; <span class="hljs-number">100</span>) {
      maxItems = items.length;
    }
    allItems.push(items);
    page++;
  }

  <span class="hljs-keyword">return</span> allItems;
};
</code></pre>
<p>While I've probably written a ton of code like this in my day, but there are a couple of things that bothers me today.</p>
<ol>
<li><p>We mutate state. <strong>page</strong>, <strong>maxItems</strong> and <strong>allItems</strong> are all being mutated in the function. State mutation for me adds cognitive load and leads to less predictable code.</p>
</li>
<li><p>The intent of <strong>maxItems</strong> is not to control the while loop, but number of items we should fetch for each page. Here it's used for both.</p>
</li>
<li><p>All though it's almost always subjective, I don't find the code very readable.</p>
</li>
</ol>
<p>Apart from fixing a bug in the function, I decided to refactor the function using recursion. The updated solution looked something like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> getAllItems = <span class="hljs-keyword">async</span> (allItems = [], page = <span class="hljs-number">1</span>) =&gt; {
  <span class="hljs-keyword">const</span> items = <span class="hljs-keyword">await</span> getItemsPage(page, <span class="hljs-number">100</span>);
  <span class="hljs-keyword">if</span> (items.length &lt; <span class="hljs-number">100</span>) {
    <span class="hljs-keyword">return</span> [...allItems, ...items];
  }

  <span class="hljs-keyword">return</span> getAllItems([...allItems, ...items], page + <span class="hljs-number">1</span>);
};
</code></pre>
<p>In my opinion, this addresses all concerns of the first implementation. No mutation of state and more concise code.</p>
<p>There are times when I'm reluctant to reach for recursion. For example when I know I have a very large dataset that I need to traverse. I don't want to run into stack overflow issues.</p>
<p>When the function is long and complex or when performance is really important, are also examples where I might reach for another approach.</p>
<p>Recursion <strong>is</strong> vastly different to the "normal" iterations that most are used to. A function that calls itself? Sounds like witchcraft to me! However I'm here to tell you that you should invest time in getting familiar with the technique. It can make your code more robust and more readable. Just remember that with great power, comes great responsibility...</p>
]]></content:encoded></item><item><title><![CDATA[You might not need Javascript classes]]></title><description><![CDATA[With so many programmers coming from a background of writing code in languages like Java or C# it's not hard to understand why a lot of Javascript code bases use classes. People are simply used to them.
Consider the following class.
class OrderServic...]]></description><link>https://durre.se/you-might-not-need-javascript-classes</link><guid isPermaLink="true">https://durre.se/you-might-not-need-javascript-classes</guid><category><![CDATA[Functional Programming]]></category><category><![CDATA[Object Oriented Programming]]></category><category><![CDATA[Testing]]></category><dc:creator><![CDATA[Andreas Du Rietz]]></dc:creator><pubDate>Wed, 15 Nov 2023 20:48:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/uWoS2-7t1k4/upload/853fc3689ae2da8bd76878a1f7d46875.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>With so many programmers coming from a background of writing code in languages like Java or C# it's not hard to understand why a lot of Javascript code bases use classes. People are simply <strong>used</strong> to them.</p>
<p>Consider the following class.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OrderService</span> </span>{
  <span class="hljs-keyword">constructor</span>(
    productDao,
    orderDao,
    paymentService,
    emailService
  ) {
    <span class="hljs-built_in">this</span>.productDao = productDao
    <span class="hljs-built_in">this</span>.orderDao = orderDao
    <span class="hljs-built_in">this</span>.paymentService = paymentService
    <span class="hljs-built_in">this</span>.emailService = emailService
  }

  <span class="hljs-keyword">async</span> placeOrder(order, customerInfo) {
    <span class="hljs-keyword">const</span> products =
      <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.productDao.getByIds(
        order.productIds
      )
    <span class="hljs-keyword">const</span> totalPrice = products.reduce(
      <span class="hljs-function">(<span class="hljs-params">acc, product</span>) =&gt;</span> acc + product.price,
      <span class="hljs-number">0</span>
    )

    <span class="hljs-keyword">const</span> receipt =
      <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.paymentService.chargeCreditCard(
        totalPrice,
        customerInfo.creditCard
      )

    <span class="hljs-keyword">const</span> savedOrder = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.orderDao.save(
      order,
      receipt
    )

    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.emailService.sendEmail(
      customerInfo.email,
      <span class="hljs-string">`Your order <span class="hljs-subst">${savedOrder.id}</span> has been placed`</span>
    )
    <span class="hljs-keyword">return</span> savedOrder
  }

  <span class="hljs-comment">// More methods for handling orders in different</span>
  <span class="hljs-comment">// ways, like deleting, updating etc...</span>
}
</code></pre>
<p>This is totally fine and very common to see code like this. However, by using a concept called <a target="_blank" href="https://en.wikipedia.org/wiki/Higher-order_function">higher-order functions</a>, you can achieve basically the same thing but without classes. Let's see what that might look like in its simplest form.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createOrderService</span>(<span class="hljs-params">
  productDao,
  orderDao,
  paymentService,
  emailService
</span>) </span>{
  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">placeOrder</span>(<span class="hljs-params">order, customerInfo</span>) </span>{
    <span class="hljs-comment">// Same logic as before, but without the `this` keyword</span>
  }

  <span class="hljs-keyword">return</span> { placeOrder }
}
</code></pre>
<p>To some, this might be less readable. But remember. New concepts also take some getting used to. I used to write Java for a living, but today I find Object Oriented Programming less readable. Also, if you, like me, have been burnt by the <strong>this</strong> keyword. In this paradigm, you don't use it anymore.</p>
<p>Let's take this one step further, to make the placeOrder function more testable.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> sumTotalPrice = <span class="hljs-function">(<span class="hljs-params">products</span>) =&gt;</span>
  products.reduce(
    <span class="hljs-function">(<span class="hljs-params">acc, curr</span>) =&gt;</span> acc + curr.price,
    <span class="hljs-number">0</span>
  )

<span class="hljs-keyword">const</span> createPlaceOrder =
  <span class="hljs-function">(<span class="hljs-params">deps</span>) =&gt;</span> <span class="hljs-keyword">async</span> (order, customerInfo) =&gt; {
    <span class="hljs-keyword">const</span> {
      getProductsById,
      chargeCreditCard,
      saveOrder,
      sendEmail,
    } = deps

    <span class="hljs-keyword">const</span> products = <span class="hljs-keyword">await</span> getProductsById(
      order.productIds
    )

    <span class="hljs-keyword">const</span> receipt = <span class="hljs-keyword">await</span> chargeCreditCard(
      sumTotalPrice(products),
      customerInfo.creditCard
    )

    <span class="hljs-keyword">const</span> savedOrder = <span class="hljs-keyword">await</span> saveOrder(
      order,
      receipt
    )

    <span class="hljs-keyword">await</span> sendEmail(
      customerInfo.email,
      <span class="hljs-string">`Your order <span class="hljs-subst">${order.id}</span> has been placed`</span>
    )
    <span class="hljs-keyword">return</span> savedOrder
  }
</code></pre>
<p>We did a couple of things here:</p>
<ul>
<li><p>We extracted the price calculation into its own function. The function is pure, making it very easy to test.</p>
</li>
<li><p>We separated dependencies from the business logic using a higher-order function. This makes it easy to see where they're coming from and it's also very easy to mock &amp; test.</p>
</li>
<li><p>We explicitly pass exactly what dependencies the function needs. We could have passed in productDao, paymentService etc, but here we only pass in exactly which functions we will use.</p>
</li>
</ul>
<p>The code examples in this article are very brief to give an idea of what it might look like. If you're interested in a bit more elaborate example I added a <a target="_blank" href="https://gist.github.com/durre/e1781dc56fd7591859394db918a81b8e">gist</a> for you to look at.</p>
<p>In summary, while JavaScript classes have their place, exploring the use of higher-order functions and pure functions opens up a world of simplicity, testability, and clarity in your code. As with any programming paradigm, the key is to find the right balance that works for your specific context. Whether you choose classes, functional programming, or a mix of both, always aim for code that is readable, testable, and adaptable to change.</p>
]]></content:encoded></item><item><title><![CDATA[5 principles for writing good functions]]></title><description><![CDATA[They are not hard rules that must never be broken, but simply helpful guidance.
It may sound like a trivial topic. Everybody can write a function, but to me, this is what separates good code from bad code. By bad code, I mean code that it's hard to r...]]></description><link>https://durre.se/5-principles-for-writing-good-functions</link><guid isPermaLink="true">https://durre.se/5-principles-for-writing-good-functions</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Andreas Du Rietz]]></dc:creator><pubDate>Tue, 14 Nov 2023 20:27:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/XJXWbfSo2f0/upload/ea30094bb9217758d62e06b3fbd76298.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>They are not hard rules that must never be broken, but simply helpful guidance.</p>
<p>It may sound like a trivial topic. Everybody can write a function, but to me, this is what separates good code from bad code. By bad code, I mean code that it's hard to read, hard to test, hard to change and hard to maintain. Writing a good function can also be very hard to do, so it takes a lot of practice.</p>
<h3 id="heading-take-what-you-need-leave-what-you-dont">Take what you need, leave what you don't</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// 😱</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserPosts</span>(<span class="hljs-params">user</span>) </span>{ 
    <span class="hljs-keyword">return</span> service.getPosts(user.id)
}
<span class="hljs-comment">// 😍</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserPosts</span>(<span class="hljs-params">userId</span>) </span>{ 
    <span class="hljs-keyword">return</span> service.getPosts(userId)
}
</code></pre>
<p>Don't pass in more than what the function needs. In this example, we pass in the user object, even though we're only using the id. In a test, you will have an easier time just passing in the id, and not having to pass in an entire user to convince Typescript your code is correct. Also, the naming will become more explicit.</p>
<h3 id="heading-pass-in-everything-the-function-needs">Pass in everything the function needs</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// 😱</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserPosts</span>(<span class="hljs-params">userId</span>) </span>{ 
    <span class="hljs-keyword">return</span> service.getPosts(userId)
}
<span class="hljs-comment">// 🙂</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserPosts</span>(<span class="hljs-params">service, userId</span>) </span>{ 
    <span class="hljs-keyword">return</span> service.getPosts(userId)
}
<span class="hljs-comment">// 🥹😍</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createGetUserPosts</span>(<span class="hljs-params">getPosts</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">userId: string</span>) </span>{
        <span class="hljs-keyword">return</span> getPosts(userId)
    }
}
<span class="hljs-keyword">const</span> getUserPosts = createGetUserPosts(service.getPosts)
</code></pre>
<p>In the first example, where did the service come from? Maybe we're in a class and the service is passed to the constructor way up in the file. Maybe it's one of five dependencies. <mark>You're going to enjoy testing a lot more if you write it in one of the latter examples.</mark> The third example is using a concept of <em>higher-order functions</em> for achieving dependency injection. This in itself deserves its own article, so be on the lookout for that.</p>
<h3 id="heading-avoid-having-too-many-parameters">Avoid having too many parameters</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// 😱</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserPosts</span>(<span class="hljs-params">userId, category, date, archived</span>) </span>{ 
    <span class="hljs-keyword">return</span> service.getPosts(userId, category, date, archived)
}
<span class="hljs-comment">// 🙏</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserPosts</span>(<span class="hljs-params">getPosts</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">searchParams</span>) </span>{
        <span class="hljs-keyword">return</span> getPosts(searchParams)
    }
}
</code></pre>
<p>I'm not saying I like having many parameters to begin with, but if I have to, I try wrapping them into an object. <mark>If my function has four or more parameters, I reach for an object instead</mark>. It has a nice side effect of readability when you have optional or boolean parameters.</p>
<h3 id="heading-avoid-long-functions">Avoid long functions</h3>
<p>If you try to keep your functions focused with limited responsibility, this will almost be automatic. <mark>My personal preference is having the function fit on the screen</mark>. This usually means around 20-30 lines.</p>
<h3 id="heading-be-explicit-with-error-handling">Be explicit with error handling</h3>
<pre><code class="lang-typescript"><span class="hljs-comment">// 😱</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateAge</span>(<span class="hljs-params">age: <span class="hljs-built_in">number</span></span>): </span>{ msg: <span class="hljs-built_in">string</span> } {
    <span class="hljs-keyword">if</span> (age &lt; <span class="hljs-number">0</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Completely unexpected!'</span>)
    <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">70</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Ok boomer...'</span>)
    <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">30</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Still too old!'</span>)
    <span class="hljs-keyword">return</span> { msg: <span class="hljs-string">"It's all good!"</span> }
}
<span class="hljs-comment">// 🙏</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateAge</span>(<span class="hljs-params">age: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">ConceivableError</span> | <span class="hljs-title">Success</span> </span>{
  <span class="hljs-keyword">if</span> (age &lt; <span class="hljs-number">0</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Completely unexpected!'</span>)
  <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">70</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">'boomer'</span>
  <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">30</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">'still-too-old'</span>
  <span class="hljs-keyword">return</span> { msg: <span class="hljs-string">"It's all good!"</span> }
}
</code></pre>
<p>Silly example, and one of the principles I haven't yet fully landed in. But take a look at the first function definition. It's hard to understand what can go wrong inside the function. In the second example, we've at least defined some of the more common error states. You can play around a lot with this type of error handling and go for something like the Either type, which you usually find in more functional languages.</p>
<p>Please share if you have any good principles of your own that you think can be helpful!</p>
]]></content:encoded></item></channel></rss>