<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Troels F. Rønnow</title>
    <description>The latest articles on DEV Community by Troels F. Rønnow (@troelsfr).</description>
    <link>https://dev.to/troelsfr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F435209%2F5a796823-775c-4f30-a1a9-eecbf1af3f27.jpeg</url>
      <title>DEV Community: Troels F. Rønnow</title>
      <link>https://dev.to/troelsfr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/troelsfr"/>
    <language>en</language>
    <item>
      <title>Context-aware chatbots using Wonop</title>
      <dc:creator>Troels F. Rønnow</dc:creator>
      <pubDate>Sun, 17 Jan 2021 08:22:16 +0000</pubDate>
      <link>https://dev.to/troelsfr/context-aware-chatbots-using-wonop-28n4</link>
      <guid>https://dev.to/troelsfr/context-aware-chatbots-using-wonop-28n4</guid>
      <description>&lt;p&gt;In this tutorial, we will build a small context-aware bot which will serve as a virtual assistant for booking cars, hotels and dinner tables. We will be using &lt;a href="https://wonop.com"&gt;https://wonop.com&lt;/a&gt; to do so. Through these tutorials, you will be introduced to the different concepts of Rocklang one by one. By the end of the tutorial, you will be able to build your own context-aware bots. Here is what the end result will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f8Us61X5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dxsduycpju9vclwh8hdv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f8Us61X5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dxsduycpju9vclwh8hdv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Traditional &lt;code&gt;Hello World&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To get familiar with &lt;code&gt;rocklang&lt;/code&gt; we create a traditional &lt;code&gt;Hello world&lt;/code&gt; example. Navigate to the &lt;code&gt;Agents&lt;/code&gt; in the GUI and, if you have not already, create a new agent. Once created, you will see the code editor. Enter the following snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main(phrase: String): Int32
{
  // Making the agent say a phrase
  say("You said: "+ phrase)

  // Printing output to the console
  printLn("Debugging: "+ phrase);

  return 0i32;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;main&lt;/code&gt; function is the one which is invoked when you run the program. This simple script demonstrates two ways of creating output using Rocklang. The first function &lt;code&gt;say&lt;/code&gt; is used to get the agent to respond to the phrase. The second function &lt;code&gt;printLn&lt;/code&gt; prints a statement to the console at the bottom of your screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Welcoming Context
&lt;/h2&gt;

&lt;p&gt;The previous script replies &lt;code&gt;You said: ...&lt;/code&gt; and does not differentiate between different intents. The first thing for us to do is to try to understand the users intent. To this end, we will make use of Rocklang context, pattern and route concepts.&lt;/p&gt;

&lt;p&gt;We will start off by a simple bot that responds to the phrase "hello world" and for any other phrase says "I do not understand what you are saying.".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context Lobby {
  // Defining the pattern we want to match against
  pattern Hello: "hello" "world";

  // Creating a route for the pattern, meaning
  // that a match on "Hello" will invoke the function
  // "hello".
  route Hello: hello;
}

fn hello(ctx: MatchContext): Bool
{
  // Answers to the matched route
  say("Well, hello there!");

  // Informs the routing system that the route
  // indeed was successful by returning true.
  return true;
}

fn main(phrase: String): Int32
{
  // Getting the current user context. If no context
  // is found, then we default to "Lobby".
  let ctx: UserContext = getUserContext("Lobby");

  // Attempting to route the input phrase within the user
  // context
  if(!routePhrase(ctx, phrase))
  {
    say("I do not understand what you are saying.");
  }

  return 0i32;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lot of things are going on in the above example. If we start with the main function: Here we first get the user context. If no user context exists yet, we default to "Lobby". This means that "Lobby" will be the first context within which we will try to match the user's request. Next, we ask the system to route the phrase within the context. In our case, the context only contains one pattern, namely &lt;code&gt;"hello" "world"&lt;/code&gt; which means that matches will only be found for "hello world" and anything else will fail at being routed. If routing fails, the agent informs that the query is not understood.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extracting Contextual Information
&lt;/h2&gt;

&lt;p&gt;If you are familiar with Regex, you will note that context patterns have taken inspiration from this concept. We illustrate this by making a small adjustment to our previous agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context Lobby {
  // Defining the pattern we want to match against
  pattern Hello: Exclamation ("world"|"earth"|"planet");

  // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This relatively small change to the program has a huge impact: The agent will now respond to phrases like "Hello world", "hey planet" and "cheers earth". Note how little we had to do to cover this wide range of possibilities.&lt;/p&gt;

&lt;p&gt;As we are creating a &lt;code&gt;Lobby&lt;/code&gt; we would typically expect a greeting either followed by a name or nothing. We would like to extract the name from the phrase to check if the user got the name right or not. To do this, we update the pattern to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context Lobby {
  // Defining the pattern we want to match against
  pattern Hello: Exclamation name=AnyWord?;

  // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we create the logic to deal with the hello request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn hello(ctx: MatchContext): Bool
{
  let howCanIHelp : String = "How can I help you?";

  // Checking whether the user used a name
  if(ctx.has("name"))
  {
    // Extracting the name from the context
    let name: String = toString(ctx.get("name"));

    if(name == "lucy")
    {
      // The bot acts happy that you recognised its name
      say("Hi! Good to see you!");
    }
    else
    {
      // Informing the user that he/she got the name wrong
      say("My name is not " + name + ". My name is Lucy");
      howCanIHelp = "Anyway, how can I help you?";
    }
  }
  else
  {
    // In case that the user did not use a name, we give neutral response
    say("Hello there!");
  }

  // Finally, we ask how we can help
  say(howCanIHelp);

  return true;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic is relatively straight forward: Either the user used a name or not. If a name was used we check that it is the correct name. If not, we inform the user that the name was wrong and otherwise we greet back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Patterns
&lt;/h2&gt;

&lt;p&gt;As you try to match more advanced scenarios, the patterns you will use become longer and more involved. To keep things simple and testable, you can break patterns down into subpatterns. As we are building a virtual assistant for bookings, we need to be able to match the many different ways a user may formulate this request. We do this by breaking the sentence to parts. We first define the introductory part of the sentence, then the part with the active verb and finally, any modifications to the sentence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context Lobby {
  // ...

  // Introductory part of the sentence
  pattern IWouldLike: "i" "would" Adverb* ("like" "you"?|"want" "you") "to";
  pattern CouldYou: "could" "you";
  pattern INeed: "i" ("need"|"want") "you"? "to";

  // The active verb
  pattern Booking: (IWouldLike|CouldYou|INeed) ("book"|"reserve"|"get"|"find")?;

  // Phrase modification
  pattern ForWhoOrWhat: "for" forWhoOrWhat=(Determiner (Pronoun|Noun));

  // The full phrase and the route
  pattern ObjectBooking: Booking determiner=Determiner what=(Noun+) ForWhoOrWhat?;
  route ObjectBooking: objectBooking;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how we are nesting patterns to break the problem down into small conquerable parts. This pattern will match a wide variety of phrases ranging from requiring ("I want you to book a hotel") through wishful asking ("I would want you to book a hotel") to politely requesting ("I would like to book a car").&lt;/p&gt;

&lt;h2&gt;
  
  
  Navigating Contexts
&lt;/h2&gt;

&lt;p&gt;Next, we craft the logic to handle requests made with this pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn objectBooking(ctx: MatchContext): Bool
{
  // Defining the variables we will need
  let what: String = toString(ctx.get("what"));
  let determiner: String = toString(ctx.get("determiner"));
  let newContext: String  = what.capitalize() + "Booking";
  let who: String;

  // Checking if the context exists
  if(hasContext(newContext))
  {
    // If the request had a modification, we give a response
    // to reflect that we understood the request
    if(ctx.has("forWhoOrWhat"))
    {
      who = toString(ctx.get("forWhoOrWhat"));
      say("So you want to book " + determiner + " " + what + " for " + who);
    }
    else
    {
      // Otherwise, it's a straight forward request
      say("So you want to book " + determiner + " " + what);
    }

    // Regardless, we inform the user that we can do this
    say("Sure, I can do that!");

    // And then we change context
    pushContext(newContext);
  }
  else
  {
    // We do not have a context to handle this case and we inform the user about this
    say("Unfortunately, I don't know how to get you " + determiner + " " + what);
  }

  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of the above logic is similar to the logic we did for the greeting section. However, we do use two new functions &lt;code&gt;hasContext&lt;/code&gt; and &lt;code&gt;pushContext&lt;/code&gt;. The function &lt;code&gt;hasContext&lt;/code&gt; checks whether the developer has created a context with a specific name and returns a boolean to reflect that. The function &lt;code&gt;pushContext&lt;/code&gt; pushes the user into a new context with new patterns. If this happens are patterns in the &lt;code&gt;Lobby&lt;/code&gt; are put aside to the benefit of the patterns in the new context.&lt;/p&gt;

&lt;p&gt;The final step in this tutorial is to create dummy contexts for cars and hotels. To do this, we add a simple context with one route: The main pattern matches any phrase and invokes the route function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context CarBooking
{
  pattern WhatCar: AnyWord*;
  route WhatCar: whatCar;
}

fn whatCar(ctx: MatchContext): Bool
{
  // User feedback
  say("Car booked!");

  // Popping the context to return back to the Lobby
  popContext();

  // Informing the routing system that we were successful
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the route function, we call &lt;code&gt;popContext&lt;/code&gt; to return back to the &lt;code&gt;Lobby&lt;/code&gt; context. Finally, we can now extend this by adding similar contexts for the hotel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context HotelBooking
{
  pattern WhatHotel: AnyWord*;
  route WhatHotel: whatHotel;
}

fn whatHotel(ctx: MatchContext): Bool
{
  say("Hotel booked!");
  popContext();
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In just about 140 lines of code (including comments), we have made a context-aware agent that has the capability of understanding what you want to do and navigate to that context. Of course, there is more work to be done in order for this to become fully functional and we will cover this in the upcoming tutorials.&lt;/p&gt;

&lt;p&gt;I would love to hear some feedback on this language I've developed! Finally, you can join our community:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wonop.com/"&gt;https://wonop.com/&lt;/a&gt;&lt;br&gt;
Dev.to: @wonop &lt;br&gt;
Discord: &lt;a href="https://discord.gg/YtkWN9fb"&gt;https://discord.gg/YtkWN9fb&lt;/a&gt;&lt;br&gt;
Twitter: &lt;a href="https://twitter.com/wonop_io"&gt;https://twitter.com/wonop_io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The delights of C++17</title>
      <dc:creator>Troels F. Rønnow</dc:creator>
      <pubDate>Fri, 23 Oct 2020 09:20:07 +0000</pubDate>
      <link>https://dev.to/troelsfr/the-delights-of-c-17-165e</link>
      <guid>https://dev.to/troelsfr/the-delights-of-c-17-165e</guid>
      <description>&lt;p&gt;Over the years, I've made a ton of C++ experiments to understand new language features. Yesterday, I was looking for a specific example I wrote a few years back.&lt;/p&gt;

&lt;p&gt;I didn't find it, but I did find this gem that adds additional syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include "new-syntax.hpp"

int main() {

  let [a, b, c] be {42, 3.14, "Hi!"} exec {
    print "a = ", a;
    print "b = ", b;
    print "c = ", c;
  }

  return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To my surprise, it compiled and ran. The key functionality it makes use of is the C++17 template deductions expressed through a couple of macros in &lt;code&gt;new-syntax.hpp&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#pragma once
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;tuple&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;tuple&amp;gt;

struct Print {
  Print(std::ostream &amp;amp;s): s(s) {}
  template&amp;lt;class T&amp;gt; Print &amp;amp;operator,(T &amp;amp;&amp;amp;t) { return s &amp;lt;&amp;lt; t, *this; }
  ~Print() { s &amp;lt;&amp;lt; '\n'; }
private:
  std::ostream &amp;amp;s;
};

#define print Print(std::cout),

#define let for(auto &amp;amp;&amp;amp;
#define be : {std::tuple
#define exec })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not sure that it is particularly useful, but C++ never fails at amazing me with how flexible it has become over the years while remaining statically typed.&lt;/p&gt;

</description>
      <category>cpp</category>
    </item>
    <item>
      <title>Django SaaS dev course</title>
      <dc:creator>Troels F. Rønnow</dc:creator>
      <pubDate>Tue, 08 Sep 2020 13:04:12 +0000</pubDate>
      <link>https://dev.to/troelsfr/django-saas-dev-course-1aoh</link>
      <guid>https://dev.to/troelsfr/django-saas-dev-course-1aoh</guid>
      <description>&lt;p&gt;I am making a Django and ReactJS SaaS dev course. I'd be happy to get some feedback: &lt;a href="https://indiemy.com"&gt;https://indiemy.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>react</category>
      <category>kubernetes</category>
      <category>saas</category>
    </item>
  </channel>
</rss>
