<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.tristan-rhodes.co.uk/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.tristan-rhodes.co.uk/" rel="alternate" type="text/html" /><updated>2026-10-09T13:48:21+00:00</updated><id>https://www.tristan-rhodes.co.uk/feed.xml</id><title type="html">Tristan’s Blog</title><subtitle>Thoughts on software engineering</subtitle><entry><title type="html">Blogging in an AI world</title><link href="https://www.tristan-rhodes.co.uk/2026/10/06/blogging-in-an-ai-world.html" rel="alternate" type="text/html" title="Blogging in an AI world" /><published>2026-10-06T00:00:00+00:00</published><updated>2026-10-06T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2026/10/06/blogging-in-an-ai-world</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2026/10/06/blogging-in-an-ai-world.html"><![CDATA[<h2 id="ai-and-i">AI and I</h2>

<p>I come from a strange background with AI. My first program was a chess computer, and I’ve been in/around the space longer than I have been in industry. In that time, I’ve seen technologies that were once cutting edge AI become commoditised, turn into brands or products, and cease to be considered AI (Google Maps navigation, Google Translate, Grammarly).</p>

<p>My early experience in industry was skewed by the tail end of the last <a href="https://en.wikipedia.org/wiki/AI_winter">AI Winter</a>, and was an era where people had to hide their usage of AI in order to secure funding for projects.</p>

<p>I’m familiar with the cycle of excitement and overinvestment, followed by the pullback of funding and I see the current time as just another phase in the AI history cycle. In the words of AC/DC, <code class="language-plaintext highlighter-rouge">Money talks, everything else walks</code> - and once investors say they don’t want AI, then that will be the driver. For now - Money says AI, and that’s what we’re going to do.</p>

<p>At some point “We use LLMs in our pipeline” will be the same as declaring that you use containers, Postgres or have CI/CD. The thing that matters will be what you do with it, and whether it is stable and secure.</p>

<p>Until that time comes - we as engineers are all figuring out our place in the world, and what our relationship with our tools is going to look like.</p>

<p>I have shaped an AI policy that reflects my values and should be workable in the real world, published <a href="/ai-policy">here</a>.</p>

<h2 id="how-i-use-ai">How I use AI</h2>

<ul>
  <li>A simple Agents.md for common rules works well for most code bases - avoid bloat.</li>
  <li>Keep the skills files to a minimum - Only add core operations.</li>
  <li>Keep the context small and focused on task - My top two commands are <code class="language-plaintext highlighter-rouge">/new</code> and <code class="language-plaintext highlighter-rouge">esc</code>.</li>
  <li>Steering is key - watch it run, provide guidance into the dialogue stream.</li>
  <li>A code base should be navigable by humans. As a side effect, this will also be navigable by bots. We still need to pass audit - investors will want to see what is being done.</li>
  <li>Code tags are great for the bot to grep/discover. These are signposts in your code base. E.g. //BOT: Extend here for additional jobs.</li>
  <li>Sometimes I still write code by hand!! Refactor a bit, make a commit, run “Apply last commit to all classes implementing IDocumentFactory.” <em>poof</em> magic.</li>
</ul>

<h2 id="test-and-verify">Test and Verify</h2>

<p>I have always driven a strong testing culture. Most of my engineering effort has been focused on defining what correct looks like, and then proving that it does actually work that way.</p>

<p>From my experience, when we tackle our large engineering problems, code and code generation have never been the challenge. 90% of the engineering effort has always gone into proving that you have delivered what you have said you have delivered. No amount of automation makes that part go away, so how fast we can move with automation is limited by how fast we can verify it is correct.</p>

<p>In an age of AI, rapid development and equally rapid change - having robust test harnesses, test suites and observability is even more critical in enabling us to move safely at speed.</p>

<h2 id="why-keep-blogging">Why keep blogging?</h2>

<p>Sure - I could make a content factory loop, schedule a job running a bot, it’s not a complicated process:</p>

<ul>
  <li>Schedule a job</li>
  <li>Generate 5 subject ideas based off current tech trends for a persona (Eccentric bald lead engineer who likes hats)</li>
  <li>Pick the best idea and generate an extended script of the subject following the persona.</li>
  <li>Generate an audio track of the script from a sample voice pack.</li>
  <li>Generate a video from the script/audio using an image asset pack.</li>
  <li>Publish to YouTube once a week.</li>
</ul>

<p>Content is easy, it’s become noise. Now noise is easy, signal is hard. So mostly I write for me - as a journal of things I have built, a record of things I explored and learned, and ways of approaching problems that I find useful or interesting.</p>

<p>I will speak with my own voice and aim to be a home of something genuine, and maybe a signal in the sea of noise.</p>

<p>I’m keeping my old blog, and the old format, although I’ll work on modernising the stack, as it provides history and content from the “before times” and a bridge into the modern AI era.</p>

<h3 id="credits">Credits</h3>
<p>I have always credited the photographer / artist behind images I used on my blog - but in the 4 years since my last post, finding anything made by a human has become… challenging.
Header photo by <a href="https://www.pexels.com/photo/man-writing-with-pen-on-paper-6249385/">Ryutaro Tsukata</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[What does it even mean?]]></summary></entry><entry><title type="html">Blue Green Deployments</title><link href="https://www.tristan-rhodes.co.uk/2022/07/10/blue-green-deployment.html" rel="alternate" type="text/html" title="Blue Green Deployments" /><published>2022-07-10T00:00:00+00:00</published><updated>2022-07-10T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2022/07/10/blue-green-deployment</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2022/07/10/blue-green-deployment.html"><![CDATA[<p>This post was originally published on behalf of Checkout.com <a href="https://medium.com/checkout-com-techblog/blue-green-deployments-649c40954d6a">here</a>.</p>

<h2 id="uptime">Uptime</h2>

<p>Here at Checkout.com, we process payments — and as the Wolf of Wall Street taught us, money never sleeps. It’s always flowing, 24 hours a day, 365.25 days a year.</p>

<p>As the engineering department for a company that processes payments, we cannot remain locked in stasis while the system runs. We have to be able to replace components and subsystems without interrupting the flow of traffic passing through the system.</p>

<p>Blue/Green deployments allow us to hot-swap systems already in use. Here, I cover the evolution of a simple server setup to a modern managed cluster and how Blue/Green deployments fit into the various systems configurations.</p>

<h2 id="in-the-beginning">In the beginning</h2>

<p>Let’s start with this basic setup. It’s a classic. The greybeards call it: Client/Server.</p>

<p><img src="/assets/blue-green-deployment/diagram-1.jpeg" alt="Client / Server" /></p>

<p>This… isn’t good enough to run a critical business. We can’t build a resilient, scalable system using this pattern. We’re limited to a single node that could fail, and a good rule of thumb is we should always run a minimum of two physical systems. With all the modern cloud systems we deploy to, it’s also pretty much impossible to avoid deploying to a cluster/load balancer setup anyway. Let’s represent that:</p>

<p><img src="/assets/blue-green-deployment/diagram-2.jpeg" alt="Client / Cluster" /></p>

<p>Great! Our app got deployed to a cluster, and now it’s being used. We’re running a successful business, money is rolling in, and everything is good. Now the business needs a new feature. We’ve developed it, tested it (it works on my machine!), and it’s all ready to go… let’s roll it out!</p>

<p>(I’ve used Octopus in our examples as it’s what we use; other deployment tools are available).</p>

<p><img src="/assets/blue-green-deployment/diagram-3.jpeg" alt="Client / Server Fail Deploy" /></p>

<p>We’ve gone to our deployment system and pressed “deploy”. It’s pushed our package/container to the cluster, replacing our old app with new instances. And now we’ve got a couple of problems — at least in our completely contrived scenario:</p>

<ul>
  <li>As we’re replacing our apps, some inbound connections will find the server they are trying to reach is in the process of an update, and we return some kind of failure, such as a 503 response.</li>
  <li>In the old app, some apps were not gracefully shut down. We have open transactions and locks on resources that were not released, so the new app may be locked out until these expire.</li>
  <li>In our new deployment, after we start it up, it doesn’t have the exchange rates (FX) in memory to process requests, and the API that provides them is not available. We can’t begin servicing requests.</li>
  <li>While we’re replacing the multiple app nodes, we also have no control or guarantee whether we are processing a given request with V1 or V2 of the system.</li>
  <li>At this point, our alerting system is screaming at us, and there’s nothing we can do about it. If we put the old system back, it will have the same problem with the FX API on start, so we’re still burning a hole in our service level agreement.</li>
</ul>

<p>How do we avoid affecting our primary system while we deploy?</p>

<p>First, we need to have something to switch to — a secondary version of the app running in isolation. What does this system look like?</p>

<p><img src="/assets/blue-green-deployment/diagram-4.jpeg" alt="Client / Server Isolated Deploy" /></p>

<p>When we talk about Blue/Green deployment, we’re really talking about a pair of systems that can hand over to each other. How do we build a setup so we can handle hot-swapping our two systems? First, we need to bring both the original Green and the new Blue system under a single entry point, which will manage traffic between the two app clusters.</p>

<p><img src="/assets/blue-green-deployment/diagram-5.jpeg" alt="Client / Server Managed Traffic" /></p>

<p>Now we have two separate systems behind a single entry point, which is invisible to the client. So how does our deployment system handle pushing to this new configuration, and how do we get our hot swap?</p>

<p><img src="/assets/blue-green-deployment/diagram-6.jpeg" alt="Deploy / Server Swap Traffic" /></p>

<p>Magic!</p>

<p>Can we do anything to improve this? Currently, our swap is immediate, and we may still find a bug in our new app when we deploy to an environment and start running it at maximum load. Can we add any more confidence to our deployment?</p>

<p>Indeed we can. In the current setup, we instruct the traffic manager that acts as routing between our two systems to send all new connections to our secondary app at once — we can make this smoother.</p>

<p>To do so, we can gradually transfer traffic to the new service, keeping an eye on our logging system (such as DataDog) and confirming at each level of load that we’re not getting any errors until all traffic has been migrated.</p>

<p><img src="/assets/blue-green-deployment/diagram-7.jpeg" alt="Deploy / Server Monitored Swap Traffic" /></p>

<p>This process trades off deployment speed for a slower, more risk-averse approach. In critical areas of the business, this tradeoff makes sense as we can deploy the new version of our app with greater confidence.</p>

<h2 id="simplifying-the-system">Simplifying the System</h2>

<p>As it stands, our system is composed of two clusters with their own load balancers, plus an additional traffic manager to handle routing between the two. Network hops are one of the more expensive considerations in a distributed system: how can we reduce these?</p>

<p>As all three components are responsible for handling network traffic, we could fold all the responsibilities for these together and make it run in a single hybrid cluster. If we do, we have a single controller for the cluster that handles both DNS routing and traffic management. If you’ve worked with Azure, the below setup used to support slot-based deployments will look familiar:</p>

<p><img src="/assets/blue-green-deployment/diagram-8.jpeg" alt="Deploy / Server Monitored Cluster Traffic Swap" /></p>

<p>More magic!</p>

<h2 id="modern-cluster">Modern Cluster</h2>
<p>This brings us to where we are today with modern cluster management techniques used for ECS, function apps, lambdas, and automatic scale sets. They can support hybrid app hosting and slot-based deployments. Now, we live in a magical wonderland of containers and shared infrastructure that just scales up and down on-demand. We only pay for what we use a̶n̶d̶ ̶w̶e̶ ̶n̶e̶v̶e̶r̶ ̶h̶a̶v̶e̶ ̶t̶o̶ ̶w̶o̶r̶r̶y̶ ̶a̶b̶o̶u̶t̶ ̶c̶o̶-̶h̶o̶s̶t̶e̶d̶ ̶s̶e̶r̶v̶i̶c̶e̶s̶ ̶e̶a̶t̶i̶n̶g̶ ̶a̶l̶l̶ ̶o̶f̶ ̶o̶u̶r̶ ̶s̶h̶a̶r̶e̶d̶ ̶r̶e̶s̶o̶u̶r̶c̶e̶s̶ ̶a̶n̶d̶ ̶D̶O̶S̶i̶n̶g̶ ̶u̶s̶…</p>

<p><img src="/assets/blue-green-deployment/diagram-9.jpeg" alt="Modern Cluster" /></p>

<h2 id="alternative-implementations">Alternative Implementations</h2>
<p>We can take Blue/Green deployment principles and apply them in a couple of other ways.</p>

<h3 id="canary-deployment">Canary deployment</h3>
<p>Rather than deploying a complete cluster/node set and swapping, we can deploy to a single active node, observe how it runs under incremental load and replace the remaining nodes one at a time.</p>

<p><img src="/assets/blue-green-deployment/diagram-10.jpeg" alt="Canary Deployment" /></p>

<h3 id="canary-consumers">Canary Consumers</h3>
<p>The same principle can be applied to queue consumers. A single throttled queue consumer (thread limits and delays) can be deployed and then monitored, with a policy in place to ramp up the consumer and then deploy the remainder.</p>

<h3 id="indexdatabase-swaps">Index/Database swaps</h3>
<p>We can also use this approach to publish a new version of a data store/index. Create a new read-only database/index under an alias and change the default alias used by the read cluster — for example, changing the “main” database role to point to a new DB/Elasticsearch index.</p>

<p>The queries continue without interruption, but the new store is now returning results.</p>

<h3 id="limitations--considerations">Limitations / Considerations</h3>
<p>One of the key principles in this approach is backward compatibility. It is critical we do not deploy breaking changes to contracts or storage schemas/models, as this will cause errors when used by different versions. This is why when adding a new column or field, it’s important to ensure it is optional and, when removing one, to ensure that it’s not validated or a required field for serialization.</p>

<p>This is doubly important for data that has a temporal element and may live for a longer period of time outside a service — for example, scheduled messages — as it’s entirely possible we could have progressed multiple versions of an API or system ahead of where the message originated.</p>

<p>One strategy for managing this is to use versioned contracts and feature toggles where appropriate.</p>

<h2 id="wrap-up">Wrap up</h2>
<p>These techniques are part of the toolkit for building resilient systems and remain responsive through the development/deployment cycle. It’d be great to see more of these in production, particularly the local council waste collection site, which is usually down when I need to check the bin days…</p>

<h3 id="credits">Credits</h3>
<p>Header photo by <a href="https://www.pexels.com/@tima-miroshnichenko?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels">Tima Miroshnichenko</a> from <a href="https://www.pexels.com/photo/photo-of-a-person-in-a-vest-doing-card-tricks-6254935/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels">Pexels</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Hot swap magic]]></summary></entry><entry><title type="html">Embedded Diagrams</title><link href="https://www.tristan-rhodes.co.uk/2022/04/22/embedded-diagrams.html" rel="alternate" type="text/html" title="Embedded Diagrams" /><published>2022-04-22T00:00:00+00:00</published><updated>2022-04-22T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2022/04/22/embedded-diagrams</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2022/04/22/embedded-diagrams.html"><![CDATA[<h2 id="diagramsnet">Diagrams.net</h2>

<p>Diagrams.net is a <em>great</em> tool for diagramming. I find it vastly superior to Miro, exclusively down to its soothing pastel color palette and selection of line end arrows. Aesthetics aside, taking screen shots, clipping them, sorting them, and updating your post, and once it’s live spotting a spelling mistake…. only to have to do it all over again… it just leaves my crying into my tea.</p>

<p>There must be an easier way!</p>

<h2 id="can-we-embed-diagrams-directly-in-blog-posts">Can we embed diagrams directly in blog posts?</h2>

<p align="center"><iframe src="https://giphy.com/embed/Oc4KnIJ3E7ziqN3l6T" width="480" height="269" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe><p><a href="https://giphy.com/gifs/betnetworks-2022-naacp-bet-image-awards-Oc4KnIJ3E7ziqN3l6T">via GIPHY</a></p></p>

<h2 id="hmmmm">Hmmmm…</h2>

<div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;resize&quot;:true,&quot;toolbar&quot;:&quot;zoom lightbox&quot;,&quot;xml&quot;:&quot;&lt;mxfile host=\&quot;app.diagrams.net\&quot; modified=\&quot;2022-04-25T22:19:20.071Z\&quot; agent=\&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\&quot; etag=\&quot;i7nf4BjC3M5B2RAeI8wX\&quot; version=\&quot;17.4.6\&quot; type=\&quot;github\&quot;&gt;&lt;diagram id=\&quot;QXLJM_nJW9eunkgCMoW-\&quot; name=\&quot;Page-1\&quot;&gt;7VnLUtswFP2WLrIs40f8yBICpDOlQ2foDNCdYim2imJ5ZDkPvr6SLccPOYEUJ6GlgYXukWRb59x7dS0P7PF8NWEgib5RiMjAMuBqYF8OLMscWtZA/htwXSCe4RRAyDBUgyrgDj8jBRoKzTBEaWMgp5RwnDTBgMYxCngDA4zRZXPYjJLmXRMQIg24CwDR0XsMeVSgvuVV+BeEw6i8s+mOip45KAerlaQRgHRZg+yrgT1mlPKiNV+NEZHklbwU86639G4ejKGYv2bC89fJ4zTNlhi6aQpG95OfxPvsFldZAJKpBauH5euSAUazGCJ5EXNgXywjzNFdAgLZuxSaCyzic6K6Z5iQMSWU5XPtmSP/JE5jXsOLn8BTzugTqvW4+U/06MtTK14gxtGqBqnlThCdI87WYojqHRqK+nVpF+ayEtIssagmolXOA8p5ws2lK35FQ1G8B92mrdGLoPA3ZVLGIxrSGJCrCr1oClCNuaE0UeAvxPlaBQ/IOG2KglaYP9Taj6JtnDnKupRsGaWxVsZW+lOasQDtWKPyIA5YiPiOcSqC5Pp3iskQARwvmvHYuzKWFghjguXa+wwH6CAfDrvc3remdl9ub7lNtzdN78zRPN/vcPyhcyB2bY3d8yTpl1qA/FnQmVECH01nPWUUp0mtq2cUr4vXg+UTQyNxn3xi/A35xHtlPvHfVT4xzTcp86eZPhbP/lDyL42aNtKsxMmtF9V5kXW7b9bV1O8Uy+S7CTyrldPaIVW4kZpVaXfOGFjXhiVyQLrjPnb3fa5fOd43Wp5TPEDlRxtK3uBaeo32TouI3t2xt2QxOojbHtvbykL1oO7maXt3rxs3MkVV5HVt3CPXs0FPNZHtt5i29Z27+1XgQPuD38GqS7jkIQGxaIeynVdJBSzuUu/5B4on0zpx9TT6r4Hpn7qCHe6TXox3+srlNVntOGjoSi6HI9U5MKlH8dUWqaNTk7rXWdn+pB5nI/S21NEnY3Wv8mJ/Vk97Atlm++Q+rJcdY5KlHDGNdLFC3mS2yVRMY9SiW0GA4DAWJkEzeQXJFg4AOVfwHEOYv5J0CdmUugcFzPaL40g/CnM7JLAPJoFeddxQAAUiiANx8IGkGOpSjI4pRfk8NSnuEFt8HAU6YuG4ApiaAFtO3f9RAU4eAZYeAVkiA8D4gYIolkyJ9iUGIQPzT5osaQQSlHPNt3FYk2wKgqcw5/Q24wRLeXIcAvZ0K2Zhnh8AnRlyv06LgyjT6tjTZzMr6Cw/oTt1nb4+o7S06nhb3Zwi1MXy9xdLmNV34OLcpvqabl/9Bg==&lt;/diagram&gt;&lt;/mxfile&gt;&quot;}"></div>
<script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>

<h2 id="yes-we-can">Yes we can!</h2>

<p>With diagrams.net’s handy viewer tool, we can host our diagram and export an IFrame wrapper around the viewer tool to get a nifty embedded diagram.</p>

<p>Dump the diagrams somewhere publicly accessible, I’m using a <a href="https://github.com/TristanRhodes/Diagrams">Diagrams repo</a></p>

<p>Open your diagram and go to File &gt; Embed &gt; HTML (or an IFrame, but I found you have more control with the HTML side).</p>

<p><img src="/assets/embedded-diagrams/export-html.png" alt="Export Html" width="60%" /></p>

<p>And dump the link / html into your HTML / markdown.</p>

<p align="center"><iframe src="https://giphy.com/embed/Ri7d8I18cto2jufOKc" width="480" height="270" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe><p><a href="https://giphy.com/gifs/morphin-marvel-deadpool-superhero-Ri7d8I18cto2jufOKc">via GIPHY</a></p></p>

<h2 id="caveat">Caveat</h2>

<p>I still haven’t figured out how to style them properly :)</p>

<h3 id="credit">Credit</h3>

<p>Image by <a href="https://pixabay.com/users/clker-free-vector-images-3736/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=311347">Clker-Free-Vector-Images</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=311347">Pixabay</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Can we embed diagrams directly in blog posts?]]></summary></entry><entry><title type="html">Commands, Events, And?</title><link href="https://www.tristan-rhodes.co.uk/2022/02/17/commands-events-and.html" rel="alternate" type="text/html" title="Commands, Events, And?" /><published>2022-02-17T00:00:00+00:00</published><updated>2022-02-17T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2022/02/17/commands-events-and</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2022/02/17/commands-events-and.html"><![CDATA[<h2 id="command-and-event-based-systems">Command and Event based systems</h2>

<p>By now, Command and Event based systems in software are ubiquitous and well understood. We can see them in WPF / React with UI commands and state change events, and we see it in distributed systems with Command and Event queues and the publish / subscribe model.</p>

<p>These systems have two types of messages, and are composed of three main concepts.</p>

<h3 id="state">State</h3>
<p>The system state as it currently stands can be stateful and in memory, such as a React state / WPF model, or stateless and out of process such as a database or document store tied to a set of function apps / lambdas.</p>

<h3 id="commands">Commands</h3>
<p>Commands are an instruction to modify state: they have not yet happened, but are an expression of intent to make something happen in the future. Commands have one recipient and they can fail, but when they succeed they have side effects.</p>

<h3 id="events">Events</h3>
<p>Events are indications that the state has changed. The state has been updated and the event provides a description and timestamp for the thing that occurred in the past. They can be broadcast to multiple recipients / subscribers.</p>

<h3 id="putting-it-together">Putting it together</h3>
<p>In this diagram, flowing from left to right, you have commands on the left, that are modifying the current state in the middle, which are raising events on the right.</p>

<p><img src="/assets/commands-events-and/command-state-event.png" alt="Command, State, Event" /></p>

<h3 id="making-it-real">Making it real</h3>
<p>While this is good, it’s all still a bit abstract. Let’s make it real - who likes food? We’re all on the same page? Great! So let’s go with a restaurant kitchen. We’re going to map the above concepts to our kitchen:</p>

<ul>
  <li>State: the kitchen’s current ingredients, available chefs (threads) and in-progress dishes.</li>
  <li>Commands: the orders coming in from the waiters. You’ll see these queuing up on the shelf.</li>
  <li>Events: the dishes output by the kitchen. The Ack part is slapping the order ticket on the completed orders spike when the dish is picked up.</li>
</ul>

<p><img src="/assets/commands-events-and/kitchen-commands-events.png" alt="Order, Kitchen, Dish" /></p>

<p>Bonus: Our kitchen analogy comes with built in queues; I don’t even need to explain them.</p>

<h3 id="what-else-is-there">What else is there?</h3>

<p>We’ve got two messages here: Commands / Orders that express intent / hunger, and Events / Dishes that express a side effect / satisfied customer. What else is there in our Kitchen system?</p>

<h3 id="ingredients">Ingredients</h3>

<p>These aren’t commands and they don’t do anything on their own - a tomato is not a command, and neither is a steak. We’ll receive them and use them when we execute an order/command and may issue low stock alerts when they run low, but the ingredients themselves are inert.</p>

<p>When we receive ingredients, we have a couple of options:</p>

<ul>
  <li>We could prepare them and freeze them</li>
  <li>We could put them in the fridge raw</li>
  <li>We could prepare them in a sauce as an ingredient for another dish</li>
  <li>We could prepare a dish to be served immediately.</li>
</ul>

<p>Whatever choice we make we’ll do based on our own context, not because of any specific instructions attached to our raw ingredient.</p>

<h3 id="recipies">Recipies</h3>

<p>Recipes look kind of like commands at first glance, but the key difference is that we’re not running them now - they’re a pre-defined set of steps we want to store as a template, and execute when we run a command.</p>

<p>We may unpack those steps into individual commands to be run inside the context of the kitchen, and we may skip some steps depending on the context of the order (I’m not fond of mushrooms, so we’ll leave them out), but as far as front of house is concerned these are invisible.</p>

<h3 id="behind-the-scenes">Behind the scenes</h3>

<p>This is what’s going on behind the scenes of our KitchenAPI:</p>

<p><img src="/assets/commands-events-and/kitchen-commands-events-messages.drawio.png" alt="Order, Kitchen, Dish, Back of house" /></p>

<h3 id="wait-whats-that">Wait, what’s that?</h3>

<p>Our orders and dishes are all we want expose to our front of house - or in other words, our commands and events are all we want to surface from our KitchenAPI.</p>

<p>But there are clearly other things happening behind the scenes, because guacamole doesn’t appear out of thin air. These aren’t commands/orders, as we are not representing intent. Nor are they events/dishes, as we are not indicating something has happened. What we receive as the payload <em>is</em> the thing that is happening, and that thing can have side effects in its own right.</p>

<p><img src="/assets/commands-events-and/ingredient-delivery.drawio.png" alt="Ingredient Delivery" /></p>

<p>What are they in a software context, these concepts that aren’t commands or events?</p>

<h3 id="just-a-message">Just a message</h3>

<p>They’re just a plain message, a document, an inert packet of information or data that carries no context of its own. What the recipient does with the payload is up to them. A couple of real world examples:</p>

<ul>
  <li>Data points: instead of sensor information as a sequence of events, they can be viewed as a series of sampled absolute values.</li>
  <li>Frames: a video frame is not an event, but it is part of a feed that provides you with hours of entertainment.</li>
  <li>Documents: the complete works of Shakespeare are not an event. Unless someone performs it, it’s just a payload of data.</li>
  <li>Document fragment: if a document is large and needs to be broken down, the parts of that document that are transmitted are not events.</li>
  <li>Workflow: a self-contained workflow can be a payload in its own right, and when processed may generate commands and events as part of its transformation while not be either itself.</li>
</ul>

<h3 id="shoulders-of-giants">Shoulders of giants</h3>

<p>And of course, <a href="https://www.enterpriseintegrationpatterns.com/patterns/messaging/DocumentMessage.html">nothing new here</a>.</p>

<h3 id="bottom-line">Bottom line</h3>

<p>We’re all building first-class command and event-based systems. When thinking about our command sources and event stores, and while running our user action and event storming workshops, it’s always worth bearing in mind that it’s still valid to pass messages between systems that are neither commands nor events - and it’s worth having room to express these concepts in your system designs.</p>

<h3 id="finally">Finally</h3>

<p>I’m hungry, so I’m going to run</p>

<blockquote>
  <p>kitchen exec prepare cheeseburger-taco</p>
</blockquote>

<p>Aaaand….</p>

<p><img src="/assets/commands-events-and/taco_taco_taco.jpg" alt="Cheeseburger Taco" /></p>

<p>(No, there is no clean way to eat these)</p>

<h3 id="credits">Credits</h3>

<p>Art work - All stick man artwork is masterfully created by me in Draw.io… probably the wrong tool for the job.</p>

<p>Main photo by <a href="https://www.pexels.com/@frostroomhead?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels">Rodion Kutsaiev</a> from <a href="https://www.pexels.com/photo/yellow-and-white-3-d-cube-9436715/?utm_content=attributionCopyText&amp;utm_medium=referral&amp;utm_source=pexels">Pexels</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Is there anything else?]]></summary></entry><entry><title type="html">Scannerless Parsing</title><link href="https://www.tristan-rhodes.co.uk/2022/01/25/scannerless-parsers.html" rel="alternate" type="text/html" title="Scannerless Parsing" /><published>2022-01-25T00:00:00+00:00</published><updated>2022-01-25T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2022/01/25/scannerless-parsers</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2022/01/25/scannerless-parsers.html"><![CDATA[<h3 id="previously">Previously</h3>

<p>Over my last few posts I’ve covered <a href="/2021/12/11/regex-redemption.html">pattern matching with regex</a>, how to <a href="/2021/12/19/tokenisation.html">break down a sentence into recognized parts</a> using a lexer/tokeniser, creating the basic <a href="http://localhost:4000/2022/01/07/expression-parsing.html">building blocks of a combinatorial parser</a> from an OO perspective and migrated it all to a <a href="http://localhost:4000/2022/01/16/expression-parsing-monads.html">purely functional approach</a>.</p>

<p>We used a two phase process, firstly a Lexer/Tokeniser, where we turned a string into higher order tokens such as Day, ClockTime and Reserved Words, and a combinatorial expression Parser to process the structure of phrase:</p>

<p><img src="/assets/scannerless-parsing/string-parsing.png" alt="String Parsing" /></p>

<p>And we applied this process to the following phrases to generate an object:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Separate two part element context =&gt; DayTime range</span>
<span class="s">"Pickup Mon 08:00 dropoff wed 17:00"</span>

<span class="c1">// Range elements with different separators =&gt; Open Days range and Hours Range</span>
<span class="s">"Open Mon to Fri 08:00 - 18:00"</span>

<span class="c1">// Repeating tokens =&gt; List of tour times</span>
<span class="s">"Tours 10:00 12:00 14:00 17:00 20:00"</span>

<span class="c1">// Repeating complex elements =&gt; List of event day times</span>
<span class="s">"Events Tuesday 18:00 Wednesday 15:00 Friday 12:00"</span>
</code></pre></div></div>

<h3 id="why-two-phase">Why two phase</h3>

<p>In some of the projects I worked on the goal with the separate tokenisation phase was to keep the language constructs separate from the syntax rules. This would enable us to hot-swap the language pack without touching the syntax rules, and on the flip side, convert any compiled syntax rules into a local language.</p>

<p>I put together a similar example implementation <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing.Tests/Functional/LanguageAwareTokeniserTests.cs">here</a> based off a modified <a href="https://github.com/TristanRhodes/TextProcessing/blob/e53c55cec41530fdad4d1257d325a576853d4773/TextProcessing/Functional/Tokenisers/LanguageAwareTokeniser.cs">language aware tokeniser</a>.</p>

<p><img src="/assets/scannerless-parsing/multi-language-tokens.PNG" alt="String Parsing" /></p>

<p>Additionally, it’s entirely possible that you may be Tokenising from a different source, maybe a number of images are being processed as words, or you are processing an audio stream and tokenising that before you analyze it for expression.</p>

<p><img src="/assets/scannerless-parsing/other-parsing.png" alt="Other Parsing" /></p>

<h3 id="what-else-can-a-token-be">What else can a token be?</h3>

<p>The first phase of our two phase process is to turn our strings into an array of objects / symbols that represent complete concepts, but what constitutes a complete concept is flexible.</p>

<p>At the end of the day, we need an array of things to work with, and currently they are Token objects. A string is also an array of Char[], and if we consider Character, Digit, Symbol, and Whitespace as our tokens then we can use a string directly as the Token source and build all of our actual word logic via combinatorial parsers.</p>

<h3 id="scannerless-parsing">Scannerless Parsing</h3>

<p>The single phase parsing process is known as Scannerless Parsing and there is already an excellent .Net implementation <a href="https://github.com/sprache/Sprache">Sprache</a> (The word is “Language” in German) which has been going for a good decade now.</p>

<h3 id="sprache">Sprache</h3>

<p>Sprache is a great library that has a full blown suite of combinatorial parsers and the ability to embed regex matches at any phase, consider some of the following we never even got near:</p>

<ul>
  <li>DelimitedBy</li>
  <li>Repeat</li>
  <li>XOr</li>
  <li>Optional</li>
  <li>Once</li>
  <li>Not</li>
</ul>

<p>There are a couple of other neat tricks they have, rather than returning a single object, it returns an array of 0 or 1 (and possibly in some scenarios more, I have not looked into concatenation), which means that it can be used directly with Linq <em>and</em> it can be written using the Linq Query syntax:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Parser</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">identifier</span> <span class="p">=</span>
    <span class="k">from</span> <span class="n">leading</span> <span class="k">in</span> <span class="n">Parse</span><span class="p">.</span><span class="n">WhiteSpace</span><span class="p">.</span><span class="nf">Many</span><span class="p">()</span>
    <span class="k">from</span> <span class="n">first</span> <span class="k">in</span> <span class="n">Parse</span><span class="p">.</span><span class="n">Letter</span><span class="p">.</span><span class="nf">Once</span><span class="p">().</span><span class="nf">Text</span><span class="p">()</span>
    <span class="k">from</span> <span class="n">rest</span> <span class="k">in</span> <span class="n">Parse</span><span class="p">.</span><span class="n">LetterOrDigit</span><span class="p">.</span><span class="nf">Many</span><span class="p">().</span><span class="nf">Text</span><span class="p">()</span>
    <span class="k">from</span> <span class="n">trailing</span> <span class="k">in</span> <span class="n">Parse</span><span class="p">.</span><span class="n">WhiteSpace</span><span class="p">.</span><span class="nf">Many</span><span class="p">()</span>
    <span class="k">select</span> <span class="n">first</span> <span class="p">+</span> <span class="n">rest</span><span class="p">;</span>
</code></pre></div></div>

<p>I’ve done a third implementation of the original expression parser suite in Sprache, with the parsers split between the <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing/SpracheParsers/TokenParsers.cs">Token Parsers</a> and <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing/SpracheParsers/ExpressionParsers.cs">Expression Parsers</a></p>

<p>We can look at the different ways to implement DayTime expression parser side by side:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Linq Delegates Syntax</span>
<span class="k">public</span> <span class="k">static</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">DayTimeDelegate</span> <span class="p">=</span>
    <span class="n">TokenParsers</span><span class="p">.</span><span class="n">DayOfWeek</span><span class="p">.</span><span class="nf">Then</span><span class="p">(</span><span class="n">day</span> <span class="p">=&gt;</span>
        <span class="n">Parse</span><span class="p">.</span><span class="n">WhiteSpace</span><span class="p">.</span><span class="nf">Then</span><span class="p">(</span><span class="n">_</span> <span class="p">=&gt;</span>
            <span class="n">TokenParsers</span><span class="p">.</span><span class="n">LocalTime</span><span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">time</span> <span class="p">=&gt;</span>
                <span class="k">new</span> <span class="nf">DayTime</span><span class="p">(</span><span class="n">day</span><span class="p">,</span> <span class="n">time</span><span class="p">))));</span>

<span class="c1">// Linq Query Syntax                        </span>
<span class="k">public</span> <span class="k">static</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">DayTimeLinqQuery</span> <span class="p">=</span>
    <span class="k">from</span> <span class="n">day</span> <span class="k">in</span> <span class="n">TokenParsers</span><span class="p">.</span><span class="n">DayOfWeek</span>
    <span class="k">from</span> <span class="n">_</span> <span class="k">in</span> <span class="n">Parse</span><span class="p">.</span><span class="n">WhiteSpace</span>
    <span class="k">from</span> <span class="n">time</span> <span class="k">in</span> <span class="n">TokenParsers</span><span class="p">.</span><span class="n">LocalTime</span>
    <span class="k">select</span> <span class="k">new</span> <span class="nf">DayTime</span><span class="p">(</span><span class="n">day</span><span class="p">,</span> <span class="n">time</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="whitespace">Whitespace</h3>

<p>It’s worth noting that we have to pay more attention to white space in the patterns. Scannerless parsing does not pre-process and package tokens, so they have to be sifted out of the whitespace / punctuation.</p>

<p>The tokeniser we have been using so far has been very basic and not taken into account white space or phrases that contain white space. A feature complete implementation would be able to shave regex matches off a string and move a cursor forward the length of the match.</p>

<h3 id="up-next">Up Next</h3>

<p>I’m going to do something completely different…</p>

<h3 id="credit">Credit</h3>

<p>I’d like to credit <a href="https://github.com/sprache/Sprache">Sprache</a> for being a source of inspiration, and helping me bridge a couple of the concept gaps when trying to build both equivalent OO and Functional version of the same combinatorial parsers.</p>

<p>Header image by <a href="https://pixabay.com/users/geralt-9301/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=2926215">Gerd Altmann</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=2926215">Pixabay</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Single phase parsing]]></summary></entry><entry><title type="html">Expression Parsing - Functional Edition</title><link href="https://www.tristan-rhodes.co.uk/2022/01/16/expression-parsing-monads.html" rel="alternate" type="text/html" title="Expression Parsing - Functional Edition" /><published>2022-01-16T00:00:00+00:00</published><updated>2022-01-16T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2022/01/16/expression-parsing-monads</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2022/01/16/expression-parsing-monads.html"><![CDATA[<h3 id="previously">Previously</h3>

<p>In my <a href="/2022/01/07/expression-parsing.html">previous post</a>, we created a basic set of object orientated parser implementations to handle converting some simple expressions.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Separate two part element context =&gt; DayTime range</span>
<span class="s">"Pickup Mon 08:00 dropoff wed 17:00"</span>

<span class="c1">// Range elements with different separators =&gt; Open Days range and Hours Range</span>
<span class="s">"Open Mon to Fri 08:00 - 18:00"</span>

<span class="c1">// Repeating tokens =&gt; List of tour times</span>
<span class="s">"Tours 10:00 12:00 14:00 17:00 20:00"</span>

<span class="c1">// Repeating complex elements =&gt; List of event day times</span>
<span class="s">"Events Tuesday 18:00 Wednesday 15:00 Friday 12:00"</span>
</code></pre></div></div>

<h3 id="in-action">In Action</h3>

<p><img src="/assets/expression-parsing/pickup-dropoff-tests.PNG" alt="Pickup Dropoff Tests" /></p>

<h3 id="the-system">The System</h3>

<p>The system is two phase, with an initial Lexer/Tokeniser that splits a string into identified parts, and a combinatorial parser system that matches a complex pattern and converts this into a higher order object. We’ve been following an Object Orientated style so far with interfaces and implementation classes.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Converts words into typed concepts</span>
<span class="k">public</span> <span class="k">interface</span> <span class="nc">ITokenParser</span>
<span class="p">{</span>
    <span class="n">TokenisationResult</span> <span class="nf">Tokenise</span><span class="p">(</span><span class="kt">string</span> <span class="n">token</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// Converts the array of typed objects into higher order objects</span>
<span class="k">public</span> <span class="k">interface</span> <span class="nc">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">ParserExtensions</span>
<span class="p">{</span>
    <span class="c1">// Extension method to enable us to enter into the IParser interface with just a Token array.</span>
    <span class="k">public</span> <span class="k">static</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Parse</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="k">this</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">parser</span><span class="p">,</span> <span class="n">Token</span><span class="p">[]</span> <span class="n">tokens</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="nf">parser</span><span class="p">(</span><span class="n">Position</span><span class="p">.</span><span class="nf">For</span><span class="p">(</span><span class="n">tokens</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="implementations">Implementations</h4>
<ul>
  <li>Is</li>
  <li>Then</li>
  <li>Or</li>
  <li>Select</li>
  <li>ListOf</li>
  <li>End</li>
</ul>

<h3 id="going-functional">Going Functional</h3>

<p>Now we’re going to drop the interface implementations, make them all delegates and take an entirely functional approach.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">delegate</span> <span class="n">TokenisationResult</span> <span class="nf">TokenParser</span><span class="p">(</span><span class="kt">string</span> <span class="n">token</span><span class="p">);</span>
<span class="k">public</span> <span class="k">delegate</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">Position</span> <span class="n">position</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="disclaimer">Disclaimer</h3>

<p>While I use functional programming regularly, I don’t come from a functional background, so I may be butchering some terms. I’ve tried to be as accurate as possible, but the concepts feel kind of fuzzy and share many similar attributes with each other, so I may blur the boundaries a bit.</p>

<h3 id="main-players">Main Players</h3>

<p>There are a couple of concepts that we need words for in order to properly describe whats going on.</p>

<ul>
  <li><a href="https://en.wikipedia.org/wiki/Functor_(functional_programming)">Functors</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)">Monads</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Combinatory_logic">Combinators / Combinatory Logic</a></li>
</ul>

<p>Now, if you click on any of those links, you’ll be confronted with a lot of mathsy looking stuff that’s heavy on symbols and steeped in category theory. Monads also seem to have this logical fallacy around them that once you understand Monads, you cannot explain them to people who don’t. But I think I’m safe, because I still don’t understand them…</p>

<h3 id="functor">Functor</h3>
<p>Wikipedia:</p>
<blockquote>
  <p>In functional programming, a functor is a design pattern inspired by the definition from category theory, that allows for a generic type to apply a function inside without changing the structure of the generic type.</p>
</blockquote>

<p>Me:</p>
<blockquote>
  <p>A function that turns one thing into a another thing.</p>
</blockquote>

<h3 id="combinator">Combinator</h3>
<p>Wikipedia:</p>
<blockquote>
  <p>A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.</p>
</blockquote>

<p>Me:</p>
<blockquote>
  <p>One or more functions used to generate a result inside another function.</p>
</blockquote>

<h3 id="monads">Monads</h3>
<p>Wikipedia:</p>
<blockquote>
  <p>In functional programming, a monad is a type that wraps another type and gives some form of quality to the underlying type. In addition to wrapping a type, monads define two functions: one to wrap a value in a monad, and another to compose together functions that output monads (these are known as monadic functions).</p>
</blockquote>

<p>Me:</p>
<blockquote>
  <p>A function that you wrap in another function of the same type to decorate / extend its behavior.</p>
</blockquote>

<p>Final Note: All monads are functors, but not all functors are monads.</p>

<h3 id="functional-flow">Functional Flow</h3>

<p align="center"><iframe src="https://giphy.com/embed/0Av9l0VIc01y1isrDw" width="480" height="360" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe><p><a href="https://giphy.com/gifs/drinkdroplet-hero-captain-planet-savetheplanet-0Av9l0VIc01y1isrDw">via GIPHY</a></p></p>

<p>Let’s start with two functions, baseValue() which returns 0, and add(), which is a function that runs baseValue() and returns the result + 1.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Fact</span><span class="p">]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">BasicNestedFunctionTest</span><span class="p">()</span>
<span class="p">{</span>
    <span class="c1">// Function that returns a starting value of 0</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="m">0</span><span class="p">;</span>

    <span class="c1">// Function that returns a function that adds 1</span>
    <span class="c1">// to the result of the basevalue function.</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="k">add</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span>
        <span class="nf">baseValue</span><span class="p">()</span> <span class="p">+</span> <span class="m">1</span><span class="p">;</span>

    <span class="c1">// Run the add function, returning the result of basevalue() + 1</span>
    <span class="k">add</span><span class="p">()</span>
        <span class="p">.</span><span class="nf">Should</span><span class="p">().</span><span class="nf">Be</span><span class="p">(</span><span class="m">1</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>When we run add, we get 1 added to the result of another function. Not too useful, but both the baseValue() and add() are Func&lt;int&gt;, meaning they are functions that take no parameters and return an int.</p>

<p>This means that, as they have the same function footprint, we can apply a combinator pattern and put one Func&lt;int&gt; inside another Func&lt;int&gt;, and what we have is still a single Func&lt;int&gt; that acts as a bridge between the other two.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Fact</span><span class="p">]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">NestedFunctionTest</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="m">0</span><span class="p">;</span>

    <span class="c1">// A Function that takes a function and returns a function that adds 1 to </span>
    <span class="c1">// the result.</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;&gt;</span> <span class="k">add</span> <span class="p">=</span> <span class="p">(</span><span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="p">()</span> <span class="p">=&gt;</span> <span class="nf">baseValue</span><span class="p">()</span> <span class="p">+</span> <span class="m">1</span><span class="p">;</span>

    <span class="c1">// A function returning a baseValue() inside an Add(), inside an Add()</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">result</span> <span class="p">=</span> 
        <span class="k">add</span><span class="p">(</span>
            <span class="k">add</span><span class="p">(</span>
                <span class="n">baseValue</span><span class="p">));</span>

    <span class="c1">// Because we ran add() twice, we get a value of 2.</span>
    <span class="nf">result</span><span class="p">()</span>
        <span class="p">.</span><span class="nf">Should</span><span class="p">().</span><span class="nf">Be</span><span class="p">(</span><span class="m">2</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I believe this is now a fully qualified Monad. We have a bridge that can nest and chain our functions and total the result, but we need to be able to do more than just add 1, we need a value parameter.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Fact</span><span class="p">]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">MonadNestingTest</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="m">0</span><span class="p">;</span>

    <span class="c1">// A Function that takes value and a function and returns a function that </span>
    <span class="c1">// adds the value to the result of the function.</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;&gt;</span> <span class="k">add</span> <span class="p">=</span>
        <span class="p">(</span><span class="kt">int</span> <span class="k">value</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span><span class="p">)</span> <span class="p">=&gt;</span>
            <span class="p">()</span> <span class="p">=&gt;</span> <span class="nf">baseValue</span><span class="p">()</span> <span class="p">+</span> <span class="k">value</span><span class="p">;</span>

    <span class="c1">// A function returning a baseValue, inside an add(1), inside an add(2), </span>
    <span class="c1">// inside an add(3)</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">result</span> <span class="p">=</span>
        <span class="k">add</span><span class="p">(</span><span class="m">3</span><span class="p">,</span>
            <span class="k">add</span><span class="p">(</span><span class="m">2</span><span class="p">,</span>
                <span class="k">add</span><span class="p">(</span><span class="m">1</span><span class="p">,</span>
                    <span class="n">baseValue</span><span class="p">)));</span>

    <span class="nf">result</span><span class="p">()</span>
        <span class="p">.</span><span class="nf">Should</span><span class="p">().</span><span class="nf">Be</span><span class="p">(</span><span class="m">6</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now let’s say we want to take our number and turn it into a monetary string, so what we want is a Func&lt;string&gt; that is going to be wrapping/converting a Func&lt;int&gt;, this is where we’re going to apply our combinator pattern against a functor. (I believe that while a Monad always chains functions, a Functor is just a converter of types, and those types <em>can</em> be functions.)</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Fact</span><span class="p">]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">MonadNestingFunctorTest</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span> <span class="p">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="m">0</span><span class="p">;</span>

    <span class="c1">// A Function that takes a value and a function and returns a function that </span>
    <span class="c1">// adds the value to the result of the function.</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;&gt;</span> <span class="k">add</span> <span class="p">=</span>
        <span class="p">(</span><span class="kt">int</span> <span class="k">value</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span><span class="p">)</span> <span class="p">=&gt;</span>
            <span class="p">()</span> <span class="p">=&gt;</span> <span class="nf">baseValue</span><span class="p">()</span> <span class="p">+</span> <span class="k">value</span><span class="p">;</span>

    <span class="c1">// Function that takes a Func&lt;int&gt; and returns a Func&lt;string&gt; that runs the Func&lt;int&gt;,</span>
    <span class="c1">// turns the result into a string and prefixes it with the &amp;pound; symbol</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;&gt;</span> <span class="n">asGBPString</span> <span class="p">=</span>
        <span class="p">(</span><span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span><span class="p">)</span> <span class="p">=&gt;</span>
            <span class="p">()</span> <span class="p">=&gt;</span> <span class="s">$"&amp;pound;"</span> <span class="p">+</span> <span class="nf">baseValue</span><span class="p">();</span>

    <span class="c1">// A function returning a baseValue, inside an add(1), inside an add(2), </span>
    <span class="c1">// inside an add(3), inside an asString()</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">price</span> <span class="p">=</span>
        <span class="nf">asGBPString</span><span class="p">(</span>
            <span class="k">add</span><span class="p">(</span><span class="m">3</span><span class="p">,</span>
                <span class="k">add</span><span class="p">(</span><span class="m">2</span><span class="p">,</span>
                    <span class="k">add</span><span class="p">(</span><span class="m">1</span><span class="p">,</span>
                        <span class="n">baseValue</span><span class="p">))));</span>

    <span class="nf">price</span><span class="p">()</span>
        <span class="p">.</span><span class="nf">Should</span><span class="p">().</span><span class="nf">Be</span><span class="p">(</span><span class="s">"&amp;pound;6"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So now we’re composing nested additions with our values and converting the result into a formatted string, but the configuration is still fiddly and unintuitive. We can tidy this up with some fluent helpers.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">Beginning</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="nf">With</span><span class="p">(</span><span class="kt">int</span> <span class="k">value</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="p">()</span> <span class="p">=&gt;</span> <span class="k">value</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">MonadExtensions</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="nf">Add</span><span class="p">(</span><span class="k">this</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span><span class="p">,</span> <span class="kt">int</span> <span class="k">value</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="p">()</span> <span class="p">=&gt;</span> <span class="nf">baseValue</span><span class="p">()</span> <span class="p">+</span> <span class="k">value</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">static</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="nf">AsGBPString</span><span class="p">(</span><span class="k">this</span> <span class="n">Func</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">baseValue</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="p">()</span> <span class="p">=&gt;</span> <span class="s">$"&amp;pound;"</span> <span class="p">+</span> <span class="nf">baseValue</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And our updated code makes our nesting come out as a flat chain:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Fact</span><span class="p">]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">MonadChainFluentTest</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">price</span> <span class="p">=</span>
        <span class="n">Beginning</span>
            <span class="p">.</span><span class="nf">With</span><span class="p">(</span><span class="m">0</span><span class="p">)</span>
            <span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
            <span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="m">2</span><span class="p">)</span>
            <span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="m">3</span><span class="p">)</span>
            <span class="p">.</span><span class="nf">AsGBPString</span><span class="p">();</span>

    <span class="nf">price</span><span class="p">()</span>
        <span class="p">.</span><span class="nf">Should</span><span class="p">().</span><span class="nf">Be</span><span class="p">(</span><span class="s">"&amp;pound;6"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Much cleaner. So the equation here is</p>

<blockquote>
  <p>Functions + Fluent API = Magic</p>
</blockquote>

<h3 id="wait-a-second">Wait a second</h3>
<p>If this feels familiar to any C# developers, it should, because this pattern is the backbone of Linq and the Lambda based composable query system. Linq extends and chains IEnumerable, and in my last post we were chaining functions that returned IParsers and using extension methods on the interface. This time, we don’t have an interface, so we’re putting <em>extension methods onto a Delegate</em>.</p>

<p align="center"><iframe src="https://giphy.com/embed/xT0xeJpnrWC4XWblEk" width="480" height="320" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe><p><a href="https://giphy.com/gifs/whoa-hd-tim-and-eric-xT0xeJpnrWC4XWblEk">via GIPHY</a></p></p>

<h3 id="putting-it-together">Putting it together</h3>

<p>But what does this mean, and why is it useful to us?</p>

<p>Let’s go back to OO thinking and start with one of our original IParser<T> implementations, IsToken:</T></p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">IsToken</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">?</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="nf">Next</span><span class="p">(),</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">:</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>What if we want to add a condition? We’ve got our OO hat on, so let’s create a base class!</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">IsTokenConditionBase</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">&amp;&amp;</span> <span class="nf">check</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">?</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="nf">Next</span><span class="p">(),</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">:</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">abstract</span> <span class="kt">bool</span> <span class="nf">check</span><span class="p">(</span><span class="n">T</span> <span class="n">entity</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now we’ve got a base class we can use to implement conditions, let’s create a check for ints over a certain value.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">IsIntegerOver</span> <span class="p">:</span> <span class="n">IsTokenConditionBase</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">_value</span><span class="p">;</span>

    <span class="k">public</span> <span class="nf">IsIntegerOver</span><span class="p">(</span><span class="kt">int</span> <span class="k">value</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="n">_value</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">override</span> <span class="kt">bool</span> <span class="nf">check</span><span class="p">(</span><span class="kt">int</span> <span class="n">entity</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="n">entity</span> <span class="p">&gt;</span> <span class="n">_value</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>By now, your spider senses should be tingling. This route is the route to great pain, we’re going to be creating a <em>looooot</em> of base classes and classes that use configurations of them and it feels like a trap. What about if we make it flexible by supplying our check as a delegate?</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">FlexibleIsTokenCondition</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;</span> <span class="n">_check</span><span class="p">;</span>

    <span class="k">public</span> <span class="nf">FlexibleIsTokenCondition</span><span class="p">(</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;</span> <span class="n">check</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="n">_check</span> <span class="p">=</span> <span class="n">check</span><span class="p">;</span>

    <span class="k">public</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">&amp;&amp;</span> <span class="nf">_check</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">?</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="nf">Next</span><span class="p">(),</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">:</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We don’t need to make a new implementation each time, we’ve got something configurable. We can run that in a test, and it all works.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Theory</span><span class="p">]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"1"</span><span class="p">,</span> <span class="k">false</span><span class="p">)]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"10"</span><span class="p">,</span> <span class="k">false</span><span class="p">)]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"101"</span><span class="p">,</span> <span class="k">true</span><span class="p">)]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"1000"</span><span class="p">,</span> <span class="k">true</span><span class="p">)]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">FlexibleParser</span><span class="p">(</span><span class="kt">string</span> <span class="n">text</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">succeed</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">tokens</span> <span class="p">=</span> <span class="nf">Tokenise</span><span class="p">(</span><span class="n">text</span><span class="p">);</span>
    <span class="k">new</span> <span class="n">FlexibleIsTokenCondition</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;(</span><span class="n">i</span> <span class="p">=&gt;</span> <span class="n">i</span> <span class="p">&gt;</span> <span class="m">100</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">tokens</span><span class="p">)</span>
        <span class="p">.</span><span class="n">Success</span>
        <span class="p">.</span><span class="nf">Should</span><span class="p">().</span><span class="nf">Be</span><span class="p">(</span><span class="n">succeed</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>What we’ve just done here to make it more flexible is to put a function inside an object. Going back to earlier in this post, we talk about the Interface being replaceable with a Function, if we make that change now, we will instead be putting a function inside a function, and that brings functional composition of functors and monads into reach.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">delegate</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">Position</span> <span class="n">position</span><span class="p">);</span>

<span class="k">public</span> <span class="k">static</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span> <span class="p">=&gt;</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">?</span> 
        <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="nf">Next</span><span class="p">(),</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">:</span>
        <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
<span class="p">};</span>

<span class="k">public</span> <span class="k">static</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;</span> <span class="n">check</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span> <span class="p">=&gt;</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">&amp;&amp;</span> <span class="nf">_check</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">?</span>
        <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="nf">Next</span><span class="p">(),</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">:</span>
        <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
<span class="p">};</span>
</code></pre></div></div>

<p>And now we can implement each complete parser in a declarative static property, no interfaces, no classes, no inheritance, no new().</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">Theory</span><span class="p">]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"1"</span><span class="p">,</span> <span class="k">false</span><span class="p">)]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"10"</span><span class="p">,</span> <span class="k">false</span><span class="p">)]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"101"</span><span class="p">,</span> <span class="k">true</span><span class="p">)]</span>
<span class="p">[</span><span class="nf">InlineData</span><span class="p">(</span><span class="s">"1000"</span><span class="p">,</span> <span class="k">true</span><span class="p">)]</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">DelegateParser</span><span class="p">(</span><span class="kt">string</span> <span class="n">text</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">succeed</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">tokens</span> <span class="p">=</span> <span class="nf">Tokenise</span><span class="p">(</span><span class="n">text</span><span class="p">);</span>
    <span class="n">Parsers</span>
        <span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;(</span><span class="n">i</span> <span class="p">=&gt;</span> <span class="n">i</span> <span class="p">&gt;</span> <span class="m">100</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">tokens</span><span class="p">)</span>
        <span class="p">.</span><span class="n">Success</span>
        <span class="p">.</span><span class="nf">Should</span><span class="p">().</span><span class="nf">Be</span><span class="p">(</span><span class="n">succeed</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="functional-parsers">Functional Parsers</h3>

<p>I’ve migrated all the original OO implementations of the <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing/Functional/Parsers/Parsers.cs">Parsers</a> and <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing/Functional/Tokenisers/TokenParsers.cs">Token Parsers</a>.</p>

<p>There are a couple of interesting additions worth noting. This FromRegex() method can be used to fluently build a Parser by combining a regex pattern and a function that processes the successful Regex Match.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">TokenParser</span> <span class="nf">FromRegex</span><span class="p">(</span><span class="kt">string</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="n">Match</span><span class="p">,</span> <span class="n">TokenisationResult</span><span class="p">&gt;</span> <span class="n">resolver</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">regex</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Regex</span><span class="p">(</span><span class="n">pattern</span><span class="p">);</span>
    <span class="k">return</span> <span class="p">(</span><span class="kt">string</span> <span class="n">token</span><span class="p">)</span> <span class="p">=&gt;</span>
    <span class="p">{</span>
        <span class="kt">var</span> <span class="n">match</span> <span class="p">=</span> <span class="n">regex</span><span class="p">.</span><span class="nf">Match</span><span class="p">(</span><span class="n">token</span><span class="p">);</span>

        <span class="k">if</span> <span class="p">(!</span><span class="n">match</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">TokenisationResult</span><span class="p">.</span><span class="nf">Fail</span><span class="p">();</span>

        <span class="k">return</span> <span class="nf">resolver</span><span class="p">(</span><span class="n">match</span><span class="p">);</span>
    <span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This enables us to separate the Regex match step from the actual processing of the successful match, and use them together via a combinator.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">TokenParser</span> <span class="n">JoiningWord</span> <span class="p">=</span> <span class="n">Tokeniser</span>
    <span class="p">.</span><span class="nf">FromRegex</span><span class="p">(</span><span class="s">@"^[Tt]o$"</span><span class="p">,</span> <span class="n">match</span> <span class="p">=&gt;</span>
        <span class="n">TokenisationResult</span><span class="p">.</span><span class="nf">Success</span><span class="p">(</span><span class="k">new</span> <span class="nf">JoiningWord</span><span class="p">()));</span>
</code></pre></div></div>

<h3 id="monad-parsers-vs-functor-parsers">Monad Parsers vs Functor Parsers</h3>

<p>If we have a closer look at the original Parser implementations, we’ll see that they aren’t all specifically Monads or Functors. I’m not confident enough to accurately categorize them, but have a think about where they sit relative to the functional concepts described above:</p>

<ul>
  <li>Is - Parser&lt;T&gt; IsToken&lt;T&gt;()</li>
  <li>Then - Parser&lt;U&gt; Then&lt;T, U&gt;(Parser&lt;T&gt; first, Func&lt;T, Parser&lt;U&gt;&gt; second)</li>
  <li>Or - Parser&lt;T&gt; Or&lt;T&gt;(params Parser&lt;T&gt;[] children)</li>
  <li>Select - Parser&lt;U&gt; Select&lt;T, U&gt;(Parser&lt;T&gt; child, Func&lt;T, U&gt; converter)</li>
  <li>ListOf - Parser&lt;List&lt;T&gt;&gt; ListOf&lt;T&gt;(Parser&lt;T&gt; child)</li>
  <li>End - Parser&lt;T&gt; End&lt;T&gt;(Parser&lt;T&gt; child)</li>
</ul>

<h3 id="functionally-parsing-daytime">Functionally Parsing DayTime</h3>

<p>Now we can go back to the starting scenario from the previous post which was initially solved with the OO approach:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">DayTimeParser</span> <span class="p">=</span>
    <span class="k">new</span> <span class="n">Then</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">,</span> <span class="n">DayTime</span><span class="p">&gt;(</span>
        <span class="k">new</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">&gt;(),</span>
        <span class="n">dow</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">Select</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">,</span> <span class="n">DayTime</span><span class="p">&gt;(</span>
            <span class="k">new</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;(),</span>
            <span class="n">lt</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">DayTime</span> <span class="p">{</span> <span class="n">Day</span> <span class="p">=</span> <span class="n">dow</span><span class="p">,</span> <span class="n">LocalTime</span> <span class="p">=</span> <span class="n">lt</span> <span class="p">}));</span>
</code></pre></div></div>

<p>This can now be assembled with functions:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">WeekDayTimeParser</span> <span class="p">=</span>
    <span class="n">Parsers</span><span class="p">.</span><span class="nf">Then</span><span class="p">(</span>
        <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">&gt;(),</span>
        <span class="n">dow</span> <span class="p">=&gt;</span> <span class="n">Parsers</span><span class="p">.</span><span class="nf">Select</span><span class="p">(</span>
            <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;(),</span>
            <span class="n">lt</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">DayTime</span> <span class="p">{</span> <span class="n">Day</span> <span class="p">=</span> <span class="n">dow</span><span class="p">,</span> <span class="n">LocalTime</span> <span class="p">=</span> <span class="n">lt</span> <span class="p">}));</span>
</code></pre></div></div>

<p>And we can apply our fluent API on top of this:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">DayTimeFluentParser</span> <span class="p">=</span>
    <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">&gt;().</span><span class="nf">Then</span><span class="p">(</span><span class="n">dow</span> <span class="p">=&gt;</span>
        <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;().</span><span class="nf">Select</span><span class="p">(</span><span class="n">lt</span> <span class="p">=&gt;</span>
            <span class="k">new</span> <span class="n">DayTime</span> <span class="p">{</span> <span class="n">Day</span> <span class="p">=</span> <span class="n">dow</span><span class="p">,</span> <span class="n">LocalTime</span> <span class="p">=</span> <span class="n">lt</span> <span class="p">}));</span>
</code></pre></div></div>

<p>And now we can do the same for all of the other <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing/Functional/Parsers/ExpressionParsers.cs">combinations of parsers</a> that we have, pure functions and functional combinators.</p>

<h3 id="code">Code</h3>

<p>The code is all available <a href="https://github.com/TristanRhodes/TextProcessing">here</a> where I put together a bunch of different ways to do parsing. We’ve just covered the functional part, so check out the <a href="https://github.com/TristanRhodes/TextProcessing/tree/master/TextProcessing/Functional">Functional folder</a>.</p>

<h3 id="note">Note</h3>

<p>It’s interesting to note that when you apply the fluent API, both the OO and Functional code is now identical on the surface. The OO pattern is still packaging object =&gt; delegate =&gt; object =&gt; delegate, but at least it’s tidy. In the new functional implementation it’s just delegates all the way.</p>

<p>The reason they are so similar is that I cheated in my last post and the “Object Orientated Approach” is actually a hybrid, but I find it helps bridge the gap between the OO and functional concepts.</p>

<h3 id="credits">Credits</h3>
<p>Header Image by <a href="https://pixabay.com/users/jackmac34-483877/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=970943">jacqueline macou</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=970943">Pixabay</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Magic with Monads (and Functors)]]></summary></entry><entry><title type="html">Expression Parsing</title><link href="https://www.tristan-rhodes.co.uk/2022/01/07/expression-parsing.html" rel="alternate" type="text/html" title="Expression Parsing" /><published>2022-01-07T00:00:00+00:00</published><updated>2022-01-07T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2022/01/07/expression-parsing</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2022/01/07/expression-parsing.html"><![CDATA[<p>In my <a href="/2021/12/19/tokenisation.html">last post</a>, I talked about splitting up sentences of text and using Regex to turn a longer string into an array of objects representing fragments of a sentence. We also created a basic expression parser to convert a sentence containing two parts, a Day and a Time, into a single DayTime object. On top of this, we considered the following scenarios:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Separate two part element context</span>
<span class="s">"Pickup Mon 08:00 dropoff wed 17:00"</span>

<span class="c1">// Range elements with different separators</span>
<span class="s">"Open Mon to Fri 08:00 - 18:00"</span>

<span class="c1">// Repeating tokens</span>
<span class="s">"Tours 10:00 12:00 14:00 17:00 20:00"</span>

<span class="c1">// Repeating complex elements</span>
<span class="s">"Events Tuesday 18:00 Wednesday 15:00 Friday 12:00"</span>
</code></pre></div></div>

<h2 id="expression-trees">Expression Trees</h2>

<p>Selecting exactly two values into a single object is simple, but when things become combinations of conditional, repetitive or optional rules, the patterns cannot be easily configured in a single phase pattern match. We need a better understanding of the pattern structure in order to begin to solve it with code. For this, we are going to need to define our sentences as expression trees, with the root being the complete concept we are parsing.</p>

<p>You read an expression tree from left leaf to right leaf, with each branch node being a syntax rule and each leaf element being a token extracted from the original sentence. We can start by describing our original parsing subject, DayTime:</p>

<p><img src="/assets/expression-parsing/expression-tree-daytime.png" alt="Parsed DayTime" /></p>

<p>This is simple enough, but our sentences are more complex concepts than this, a higher order object can be composed of other higher order concepts, and what is a root for some scenarios may be a child for others. Consider the expression trees for the scenarios above:</p>

<table width="100%">
<tr>
    <th width="25%">Pickup / Dropoff</th>
    <th width="25%">Range seperators</th>
    <th width="25%">Repeating Tokens</th>
    <th width="25%">Repeating Complex Children</th>
</tr>
  <tr>
  <td><a class="example-image-link" href="/assets/expression-parsing/expression-tree-pickup-drop-off.png" data-lightbox="example-1"><img class="example-image" src="/assets/expression-parsing/expression-tree-pickup-drop-off.png" height="100" width="100" alt="" /></a></td>
    <td><a class="example-image-link" href="/assets/expression-parsing/expression-tree-ranges.png" data-lightbox="example-1"><img class="example-image" src="/assets/expression-parsing/expression-tree-ranges.png" height="100" width="100" alt="" /></a></td>
    <td><a class="example-image-link" href="/assets/expression-parsing/expression-tree-repeating-token.png" data-lightbox="example-1"><img class="example-image" src="/assets/expression-parsing/expression-tree-repeating-token.png" height="100" width="100" alt="" /></a></td>
    <td><a class="example-image-link" href="/assets/expression-parsing/expression-tree-repeating-complex.png" data-lightbox="example-1"><img class="example-image" src="/assets/expression-parsing/expression-tree-repeating-complex.png" height="100" width="100" alt="" /></a></td>
  </tr>
</table>

<h3 id="basic-parser-rules">Basic Parser Rules</h3>

<p>In order to begin to process the above scenarios, we’re going to need something to handle our expression rules, let’s stick with those needed just for handling DayTime for now:</p>

<ul>
  <li>IsToken - A parser that matches a single token. (These would be the blue Token nodes in the tree)</li>
  <li>Then - A parser that matches two consecutive parsers together in a chain.</li>
  <li>Select - A parser that converts the result of one Parser into a different result type. (These would be the purple higher order nodes in the tree)</li>
</ul>

<h3 id="parser-chaining">Parser Chaining</h3>

<p>How do you start to combine these together? We are in a situation where we have a list of tokens we want to provide to a parser, but we also need to put a parser inside another parser and do some magic… We’re missing some key concepts. Let’s go back to our naive parser implementation:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Token</span><span class="p">[]</span> <span class="n">tokens</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">bool</span> <span class="n">Success</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="n">T</span> <span class="n">Value</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We can’t really chain this. Our input is always a Token[] array, and our output is always a result of processing the complete input. But what if an instance of a parser only consumed the tokens that were relevant to itself and its children, and returned the remaining tail? How would we do that?</p>

<p>We can create a Position object that encapsulates our Tokens and Ordinal:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Position</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nf">Position</span><span class="p">(</span><span class="n">Token</span><span class="p">[]</span> <span class="n">source</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ordinal</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">Source</span> <span class="p">=</span> <span class="n">source</span><span class="p">;</span>
        <span class="n">Ordinal</span> <span class="p">=</span> <span class="n">ordinal</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="n">Token</span><span class="p">[]</span> <span class="n">Source</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="kt">int</span> <span class="n">Ordinal</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="n">Token</span> <span class="n">Current</span> <span class="p">=&gt;</span> <span class="p">!</span><span class="n">End</span> <span class="p">?</span> <span class="n">Source</span><span class="p">[</span><span class="n">Ordinal</span><span class="p">]</span> <span class="p">:</span> <span class="k">throw</span> <span class="k">new</span> <span class="nf">ApplicationException</span><span class="p">(</span><span class="s">"At End"</span><span class="p">);</span>

    <span class="k">public</span> <span class="kt">bool</span> <span class="n">End</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="n">Ordinal</span> <span class="p">==</span> <span class="n">Source</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>From here, if we change the input to Position and we add a Position to the response, then when we take the a successful Parse attempt that has moved the Ordinal forward, we can feed that relative Position into the next parser in the expression tree, and we’ve opened up the possibility of chaining and composition.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">bool</span> <span class="n">Success</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="n">T</span> <span class="n">Value</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="n">Position</span> <span class="n">Position</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now let’s look at some implementations to get an idea of what they do individually.</p>

<h3 id="basic-implementations">Basic implementations</h3>

<h4 id="istoken">IsToken</h4>

<p>We can start with the most basic check, see if the current position is a match for the Token, and if it is, return the next position and the result, otherwise return a failure at the current position. We’ll use this to check for Day and LocalTime.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">IsToken</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nf">IsToken</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>

    <span class="k">public</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">?</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">.</span><span class="nf">Next</span><span class="p">(),</span> <span class="n">position</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">As</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;())</span> <span class="p">:</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="then">Then</h4>

<p>The Then implementation contains a first parser, representing the syntax on the left, and a function to generate the second parser, which we run and use to evaluate the syntax on the right but only if the first parser is successful. In our scenario, we will be looking for an Is&lt;DayOfWeek&gt; on the left, followed by Is&lt;LocalTime&gt; on the right.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Then</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">_first</span><span class="p">;</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;&gt;</span> <span class="n">_second</span><span class="p">;</span>

    <span class="k">public</span> <span class="nf">Then</span><span class="p">(</span><span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">first</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;&gt;</span> <span class="n">second</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">_first</span> <span class="p">=</span> <span class="n">first</span><span class="p">;</span>
        <span class="n">_second</span> <span class="p">=</span> <span class="n">second</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="n">_first</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
        <span class="n">position</span> <span class="p">=</span> <span class="n">result</span><span class="p">.</span><span class="n">Position</span><span class="p">;</span>

        <span class="k">if</span> <span class="p">(!</span><span class="n">result</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>

        <span class="kt">var</span> <span class="n">thenResult</span> <span class="p">=</span> <span class="nf">_second</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">Value</span><span class="p">)</span>
            <span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
        <span class="n">position</span> <span class="p">=</span> <span class="n">thenResult</span><span class="p">.</span><span class="n">Position</span><span class="p">;</span>

        <span class="k">return</span> <span class="n">thenResult</span><span class="p">.</span><span class="n">Success</span> <span class="p">?</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">,</span> <span class="n">thenResult</span><span class="p">.</span><span class="n">Value</span><span class="p">)</span> <span class="p">:</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="select">Select</h4>

<p>Select takes a core Parser as an argument and a converter function. When the core parser is successful, the result is fed into the converter function and the converted result is returned. Here, our converter method will pass in the previous two values and generate our DayTime.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Select</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">_core</span><span class="p">;</span>
    <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;</span> <span class="n">_converter</span><span class="p">;</span>

    <span class="k">public</span> <span class="nf">Select</span><span class="p">(</span><span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">core</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;</span> <span class="n">converter</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">_core</span> <span class="p">=</span> <span class="n">core</span><span class="p">;</span>
        <span class="n">_converter</span> <span class="p">=</span> <span class="n">converter</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="n">_core</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
        <span class="n">position</span> <span class="p">=</span> <span class="n">result</span><span class="p">.</span><span class="n">Position</span><span class="p">;</span>

        <span class="k">return</span> <span class="n">result</span><span class="p">.</span><span class="n">Success</span> <span class="p">?</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">position</span><span class="p">,</span> <span class="nf">_converter</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">Value</span><span class="p">))</span> <span class="p">:</span>
            <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">(</span><span class="n">position</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Using this pattern, we can build a tree of parsers to represent our expression and run this over our Token array.</p>

<h3 id="putting-it-together">Putting it together</h3>
<p>Let’s take our original naive parser for DayTime, and replace it with our new parser setup.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">DayTimeParser</span> <span class="p">=</span>
    <span class="k">new</span> <span class="n">Then</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">,</span> <span class="n">DayTime</span><span class="p">&gt;(</span>
        <span class="k">new</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">&gt;(),</span>
        <span class="n">dow</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">Select</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">,</span> <span class="n">DayTime</span><span class="p">&gt;(</span>
            <span class="k">new</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;(),</span>
            <span class="n">lt</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">DayTime</span> <span class="p">{</span> <span class="n">Day</span> <span class="p">=</span> <span class="n">dow</span><span class="p">,</span> <span class="n">LocalTime</span> <span class="p">=</span> <span class="n">lt</span> <span class="p">}));</span>
</code></pre></div></div>

<p><img src="/assets/expression-parsing/day-time-parser-tests.PNG" alt="DayTime Parser Tests" /></p>

<p>Ok - it works, it’s got the Is&lt;DayOfWeek&gt;(), Then(), Is&lt;LocalTime&gt;(), Select&lt;DayTime&gt;() pattern, but this isn’t particularly fun to work with. There are lots of new keywords and the code reads like <a href="https://en.wikipedia.org/wiki/Polish_notation">Polish notation</a>.</p>

<h3 id="making-it-fluent">Making it fluent</h3>

<p>To make things easier, we can create a bunch of static helper methods to configure our root parsers, and a set of extension methods to combine our parsers together:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">Parsers</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="p">=&gt;</span>
        <span class="k">new</span> <span class="n">IsToken</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;();</span>

    <span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">List</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;&gt;</span> <span class="n">ListOf</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">parser</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="k">new</span> <span class="n">ListOf</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">parser</span><span class="p">);</span>

    <span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Or</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="k">params</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;[]</span> <span class="n">options</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="k">new</span> <span class="n">Or</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">options</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">ParserExtensions</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;</span> <span class="n">Then</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;(</span><span class="k">this</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">core</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;&gt;</span> <span class="n">then</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="k">new</span> <span class="n">Then</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;(</span><span class="n">core</span><span class="p">,</span> <span class="n">then</span><span class="p">);</span>

    <span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;</span> <span class="n">Select</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;(</span><span class="k">this</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">core</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;</span> <span class="k">select</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="k">new</span> <span class="n">Select</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">U</span><span class="p">&gt;(</span><span class="n">core</span><span class="p">,</span> <span class="k">select</span><span class="p">);</span>

    <span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">End</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="k">this</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">core</span><span class="p">)</span> <span class="p">=&gt;</span>
        <span class="k">new</span> <span class="n">End</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">core</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Then we can re-write our original implementation using a fluent approach to compose our parser tree, with the result being much cleaner:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">DayTimeFluentParser</span> <span class="p">=</span>
    <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">&gt;().</span><span class="nf">Then</span><span class="p">(</span><span class="n">dow</span> <span class="p">=&gt;</span>
        <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;().</span><span class="nf">Select</span><span class="p">(</span><span class="n">lt</span> <span class="p">=&gt;</span>
            <span class="k">new</span> <span class="n">DayTime</span> <span class="p">{</span> <span class="n">Day</span> <span class="p">=</span> <span class="n">dow</span><span class="p">,</span> <span class="n">LocalTime</span> <span class="p">=</span> <span class="n">lt</span> <span class="p">}));</span>
</code></pre></div></div>

<p>But this is only a parser for our basic scenario, right? We’ve added a whole bunch of code, complexity and fluff, with no new functionality, and we’re still left with only this?</p>

<h3 id="composition">Composition</h3>

<p>Well… not quite. Now we can create parsers from other parsers; that’s what we did when we created our DayTimeParser from Is&lt;DayOfWeek&gt; and Is&lt;LocalTime&gt; checks, so let’s take our pickup / dropoff scenario above, where our DayTimeParser can point to either of our fluent/non-fluent implementations:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// This parser returns a DayTime where it is preceded by a PickupFlag</span>
<span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">PickupDayTime</span> <span class="p">=&gt;</span> <span class="n">Parsers</span>
    <span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">PickupFlag</span><span class="p">&gt;()</span>
        <span class="p">.</span><span class="nf">Then</span><span class="p">(</span><span class="n">_</span> <span class="p">=&gt;</span> <span class="n">DayTimeParser</span><span class="p">);</span>

<span class="c1">// This parser returns a DayTime where it is preceded by a Dropoff flag</span>
<span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">DropOffDayTime</span> <span class="p">=&gt;</span> <span class="n">Parsers</span>
    <span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">DropoffFlag</span><span class="p">&gt;()</span>
        <span class="p">.</span><span class="nf">Then</span><span class="p">(</span><span class="n">_</span> <span class="p">=&gt;</span> <span class="n">DayTimeParser</span><span class="p">);</span>

<span class="c1">// This parser returns a PickupDropOff object that is derived from a </span>
<span class="c1">// sequential Pickup/Dropoff match. Note that each of the Pickup/Dropoff</span>
<span class="c1">// parsers return a DayTime.</span>
<span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">PickupDropoff</span><span class="p">&gt;</span> <span class="n">PickupDropOff</span> <span class="p">=&gt;</span> 
    <span class="n">PickupDayTime</span><span class="p">.</span><span class="nf">Then</span><span class="p">(</span><span class="n">pu</span> <span class="p">=&gt;</span> 
        <span class="n">DropOffDayTime</span><span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">dr</span> <span class="p">=&gt;</span> 
            <span class="k">new</span> <span class="n">PickupDropoff</span> <span class="p">{</span> <span class="n">Pickup</span> <span class="p">=</span> <span class="n">pu</span><span class="p">,</span> <span class="n">DropOff</span> <span class="p">=</span> <span class="n">dr</span> <span class="p">}))</span>
    <span class="p">.</span><span class="nf">End</span><span class="p">();</span>
</code></pre></div></div>

<p>And that’s it, we’ve got our text with our pickup DayTime and our dropoff DayTime mashed together into a single object, using composition and some tidy fluent snippets.</p>

<p><img src="/assets/expression-parsing/pickup-dropoff-tests.PNG" alt="Pickup Dropoff Tests" /></p>

<h3 id="completing-the-set">Completing the set</h3>

<p>We’re still pretty limited in terms of what we can do with our original Is/Then/Select parsers, we can’t cater to some of the more complex scenarios. We’re not done yet.</p>

<h4 id="or">Or</h4>
<p>A parser that matches one of multiple child parsers of the same result type. Let’s say we want to treat two different Tokens the same way; we need something conditional in our expression to indicate that one expression must be a match. Let’s take an expression where we want to use “to” or “-“ to indicate that we are matching a term describing a range between two values.</p>

<p><img src="/assets/expression-parsing/expression-tree-range.png" alt="Range Expression" /></p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">RangeMarker</span><span class="p">&gt;</span> <span class="n">RangeMarker</span> <span class="p">=</span>
    <span class="n">Parsers</span><span class="p">.</span><span class="nf">Or</span><span class="p">(</span>
        <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">HypenSymbol</span><span class="p">&gt;().</span><span class="nf">Select</span><span class="p">(</span><span class="n">r</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="nf">RangeMarker</span><span class="p">()),</span>
        <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">JoiningWord</span><span class="p">&gt;().</span><span class="nf">Select</span><span class="p">(</span><span class="n">r</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="nf">RangeMarker</span><span class="p">())</span>
    <span class="p">);</span>
</code></pre></div></div>

<p>We can then use this as part of a combination to satisfy either condition:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">Range</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;&gt;</span> <span class="n">TimeRangeParser</span> <span class="p">=</span>
    <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;().</span><span class="nf">Then</span><span class="p">(</span><span class="k">from</span> <span class="p">=&gt;</span>
        <span class="n">RangeMarker</span><span class="p">.</span><span class="nf">Then</span><span class="p">(</span><span class="n">_</span> <span class="p">=&gt;</span>
            <span class="n">Parsers</span><span class="p">.</span><span class="n">IsToken</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;()</span>
                <span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">to</span> <span class="p">=&gt;</span> <span class="k">new</span> <span class="n">Range</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;</span> <span class="p">{</span> <span class="n">From</span> <span class="p">=</span> <span class="k">from</span><span class="p">,</span> <span class="n">To</span> <span class="p">=</span> <span class="n">to</span> <span class="p">})));</span>
</code></pre></div></div>

<p>And we can match 12 or 24 hour clocks, separated by a range marker of “to” or “-“.</p>

<p><img src="/assets/expression-parsing/range-parser-tests.png" alt="Pickup Dropoff Tests" /></p>

<h4 id="listof">ListOf</h4>

<p>A parser that matches a number of items against a single child parser and returns a list of the child parser values:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">List</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;&gt;</span> <span class="n">result</span> <span class="p">=</span> <span class="n">Parsers</span>
    <span class="p">.</span><span class="nf">ListOf</span><span class="p">(</span><span class="n">DayTimeParser</span><span class="p">)</span>
    <span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">tokens</span><span class="p">);</span>
</code></pre></div></div>

<p><img src="/assets/expression-parsing/list-of-day-time-parser-tests.PNG" alt="Pickup Dropoff Tests" /></p>

<h4 id="end">End</h4>

<p>A parser that determines if the result is the end of the Token array. This prevents a match from being successful when there are unconsumed tokens from the complete parsing expression.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="n">ExplicitDayTimeParser</span> <span class="p">=</span>
    <span class="n">DayTimeParser</span><span class="p">.</span><span class="nf">End</span><span class="p">();</span>
</code></pre></div></div>

<p>All of these lovely Parser implementations are available <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing/OO/Parsers/Parsers.cs">here</a>, with the configurations for the original sentence structures <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing/OO/Parsers/ExpressionParsers.cs">here</a>. There might even be some tests in there somewhere.</p>

<h3 id="turtles">Turtles</h3>

<p>And after that… it all gets a bit, Turtles… all the way down…</p>

<p><img src="/assets/expression-parsing/turtles.jpg" alt="Turtles" /></p>

<p>So if you want to take this thought experiment a bit further, try thinking about (or implementing) lists of lists of complex objects…. or lists of lists of lists… or just n+1. Once you solve the problem at one level, you can solve it at any level.</p>

<h3 id="code">Code</h3>

<p>More code turtles are available <a href="https://github.com/TristanRhodes/TextProcessing">here</a> where I put together a bunch of different ways to do parsing. We’re currently still in the slavishly Object Orientated part, so check out the <a href="https://github.com/TristanRhodes/TextProcessing/tree/master/TextProcessing/OO">OO folder</a>.</p>

<h3 id="next-up">Next Up</h3>

<p>So far, we’ve been good little object orientated boys and girls, we’ve got our Interface, we have our little implementation classes, we’ve got good SOLID principles, but it’s still pretty heavy… this interface is only a single method.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Position</span> <span class="n">position</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Does it need to be an interface? What else could it be?</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">delegate</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Parser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">Position</span> <span class="n">position</span><span class="p">);</span>
</code></pre></div></div>

<p align="center"><iframe src="https://giphy.com/embed/26gR0YFZxWbnUPtMA" width="480" height="270" frameborder="20" class="giphy-embed" allowfullscreen=""></iframe><p><a href="https://giphy.com/gifs/tipsyelves-math-26gR0YFZxWbnUPtMA">via GIPHY</a></p></p>

<h3 id="credits">Credits</h3>
<p>Header Image by <a href="https://unsplash.com/@glencarrie?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Glen Carrie</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Turning bigger strings, into complex things.]]></summary></entry><entry><title type="html">Tokenisation</title><link href="https://www.tristan-rhodes.co.uk/2021/12/19/tokenisation.html" rel="alternate" type="text/html" title="Tokenisation" /><published>2021-12-19T00:00:00+00:00</published><updated>2021-12-19T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2021/12/19/tokenisation</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2021/12/19/tokenisation.html"><![CDATA[<h2 id="tokens">Tokens</h2>

<p>In my <a href="/2021/12/11/regex-redemption.html">last post</a>, I talked about using Regex to match the pattern of a WeekDay or ClockTime string and unpacking this into a meaningful object. This is known as Parsing, and we can see plenty of examples in the .Net framework, int.Parse(), Guid.Parse(), plus others. But how do we deal with parsing more complicated bodies of text that are made up of multiple words / parts?</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">"Monday 08:30am"</span>
<span class="s">"tue 18:30"</span>
<span class="s">"thurs 12:30pm"</span>
</code></pre></div></div>

<p>We’re going to tackle this in two phases firstly we’re going to split our text into parts and parse them into tokens (Tokenisation/Scanning phase), then we’re going to check the tokens match a correct syntax pattern and turn that into an object (Parsing phase).</p>

<p><img src="/assets/tokenisation/ParsingProcess.png" alt="Parsing" /></p>

<h3 id="tokeniser">Tokeniser</h3>
<p>To start with, we’re going to need a Tokeniser for converting a complete string into tokens. This is going to need a split pattern and a number of ITokenParsers to identify and convert the individual string fragments into sentence primitives.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Tokeniser</span>
<span class="p">{</span>
    <span class="n">Regex</span> <span class="n">_splitPattern</span><span class="p">;</span>
    <span class="n">IList</span><span class="p">&lt;</span><span class="n">ITokenParser</span><span class="p">&gt;</span> <span class="n">_tokenisers</span><span class="p">;</span>

    <span class="k">public</span> <span class="nf">Tokeniser</span><span class="p">(</span><span class="kt">string</span> <span class="n">splitPattern</span><span class="p">,</span> <span class="k">params</span> <span class="n">ITokenParser</span><span class="p">[]</span> <span class="n">tokenisers</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">_splitPattern</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Regex</span><span class="p">(</span><span class="n">splitPattern</span><span class="p">);</span>
        <span class="n">_tokenisers</span> <span class="p">=</span> <span class="n">tokenisers</span><span class="p">.</span><span class="nf">ToList</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">Token</span><span class="p">&gt;</span> <span class="nf">Tokenise</span><span class="p">(</span><span class="kt">string</span> <span class="n">inputString</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="kt">var</span> <span class="n">parts</span> <span class="p">=</span> <span class="n">_splitPattern</span><span class="p">.</span><span class="nf">Split</span><span class="p">(</span><span class="n">inputString</span><span class="p">);</span>
        <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">part</span> <span class="k">in</span> <span class="n">parts</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="kt">var</span> <span class="n">match</span> <span class="p">=</span> <span class="n">_tokenisers</span>
                <span class="p">.</span><span class="nf">Select</span><span class="p">(</span><span class="n">t</span> <span class="p">=&gt;</span> <span class="n">t</span><span class="p">.</span><span class="nf">Tokenise</span><span class="p">(</span><span class="n">part</span><span class="p">))</span>
                <span class="p">.</span><span class="nf">Where</span><span class="p">(</span><span class="n">t</span> <span class="p">=&gt;</span> <span class="n">t</span><span class="p">.</span><span class="n">Successful</span><span class="p">)</span>
                <span class="p">.</span><span class="nf">FirstOrDefault</span><span class="p">();</span>

            <span class="k">yield</span> <span class="k">return</span> <span class="n">match</span> <span class="p">==</span> <span class="k">null</span> <span class="p">?</span>
                <span class="n">Token</span><span class="p">.</span><span class="nf">Create</span><span class="p">(</span><span class="n">part</span><span class="p">)</span> <span class="p">:</span>
                <span class="n">match</span><span class="p">.</span><span class="n">Token</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">interface</span> <span class="nc">ITokenParser</span>
<span class="p">{</span>
    <span class="n">TokenisationResult</span> <span class="nf">Tokenise</span><span class="p">(</span><span class="kt">string</span> <span class="n">token</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">TokenisationResult</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="n">Token</span> <span class="n">Token</span>  <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="kt">bool</span> <span class="n">Successful</span>  <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We will now need to port the logic from the original post for matching and parsing DayOfWeek and LocalTime and implement our ITokenParser interface, then drop them all into the Tokeniser…</p>

<p><img src="/assets/tokenisation/ConvertedTokensTest.PNG" alt="Token Tests" /></p>

<p>Now we have an array of Tokens generated from a string, with tokens that match a specific Tokeniser rule being captured and converted, note that I’ve also included an integer converter, and any unmatched tokens are returned as String tokens. But we still need something that checks if these tokens are a recognizable configuration, and then converts this into a meaningful object.</p>

<h3 id="parsing-a-complete-daytime">“Parsing” a complete DayTime</h3>

<p>While we’re only writing one parser for one pattern right now, it’s a common concept, so we can start with an interface. We’ll also follow the Regex response pattern, which returns a Match object with a Success flag and result information, but we will be returning a typed object.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">IParser</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Token</span><span class="p">[]</span> <span class="n">tokens</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">ParseResult</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">bool</span> <span class="n">Success</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="n">T</span> <span class="n">Value</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="n">init</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Our DayTime object is composed of two parts, the Day and the Time. All we need now is to create a simple expression parser that takes an array of Token[] and populates the fields in a DayTime object.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">DayTime</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nf">DayTime</span><span class="p">(</span><span class="n">DayOfWeek</span> <span class="n">day</span><span class="p">,</span> <span class="n">LocalTime</span> <span class="n">time</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">Day</span> <span class="p">=</span> <span class="n">day</span><span class="p">;</span>
        <span class="n">LocalTime</span> <span class="p">=</span> <span class="n">time</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="n">DayOfWeek</span> <span class="n">Day</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">public</span> <span class="n">LocalTime</span> <span class="n">LocalTime</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">SimpleDayTimeParser</span> <span class="p">:</span> <span class="n">IParser</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span> <span class="nf">Parse</span><span class="p">(</span><span class="n">Token</span><span class="p">[]</span> <span class="n">tokens</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">tokens</span><span class="p">.</span><span class="n">Length</span> <span class="p">!=</span> <span class="m">2</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">();</span>
        <span class="k">if</span> <span class="p">(!</span><span class="n">tokens</span><span class="p">[</span><span class="m">0</span><span class="p">].</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">&gt;())</span>
            <span class="k">return</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">();</span>
        <span class="k">if</span> <span class="p">(!</span><span class="n">tokens</span><span class="p">[</span><span class="m">1</span><span class="p">].</span><span class="n">Is</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;())</span>
            <span class="k">return</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;.</span><span class="nf">Failure</span><span class="p">();</span>

        <span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">DayTime</span><span class="p">(</span>
            <span class="n">tokens</span><span class="p">[</span><span class="m">0</span><span class="p">].</span><span class="n">As</span><span class="p">&lt;</span><span class="n">DayOfWeek</span><span class="p">&gt;(),</span>
            <span class="n">tokens</span><span class="p">[</span><span class="m">1</span><span class="p">].</span><span class="n">As</span><span class="p">&lt;</span><span class="n">LocalTime</span><span class="p">&gt;());</span>

        <span class="k">return</span> <span class="n">ParseResult</span><span class="p">&lt;</span><span class="n">DayTime</span><span class="p">&gt;</span>
            <span class="p">.</span><span class="nf">Successful</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And that’s it, we can convert our two part string into a higher order object.</p>

<p><img src="/assets/tokenisation/ParsedDayTime.PNG" alt="Parsed DayTime" /></p>

<h3 id="expression-trees-and-parsers">Expression Trees and Parsers</h3>
<p>Our “parser” implementation is a bit of an overstatement here, this is the most naive logic we can get. It doesn’t have any flexibility for supporting more complex structures and is only going to support a very explicit match. If we wanted to extend this to support more complex patterns, we’re going to be quite limited. Consider trying to solve the following patterns:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Separate two part element context</span>
<span class="s">"Pickup Mon 08:00 dropoff wed 17:00"</span>

<span class="c1">// Range elements with different separators</span>
<span class="s">"Open Mon to Fri 08:00 - 18:00"</span>

<span class="c1">// Repeating tokens</span>
<span class="s">"Tours 10:00 12:00 14:00 17:00 20:00"</span>

<span class="c1">// Repeating complex elements</span>
<span class="s">"Events Tuesday 18:00 Wednesday 15:00 Friday 12:00"</span>
</code></pre></div></div>

<p>To solve these problems, we’re going to need a parser with the ability to process an expression tree, and we’ll get to that next.</p>

<p>All the code is available in a small sandbox project I’m building to go along with a couple of posts <a href="https://github.com/TristanRhodes/TextProcessing">here</a>.</p>

<h3 id="note">Note</h3>
<p>Post updated 7th January to line up with work done on demo project.</p>

<h3 id="credits">Credits</h3>

<p>Header Image by <a href="https://pixabay.com/users/fantasycoins-1910023/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1146135">Tim west</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1146135">Pixabay</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Turning bits of strings, into little things.]]></summary></entry><entry><title type="html">Regex Redemption</title><link href="https://www.tristan-rhodes.co.uk/2021/12/11/regex-redemption.html" rel="alternate" type="text/html" title="Regex Redemption" /><published>2021-12-11T00:00:00+00:00</published><updated>2021-12-11T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2021/12/11/regex-redemption</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2021/12/11/regex-redemption.html"><![CDATA[<h2 id="regex">Regex</h2>

<p>Because I went through a phase of being <a href="https://tristan-rhodes.co.uk/2021/11/25/check-your-assumptions.html">monumentally dumb</a> recently, I felt it was appropriate to perform some kind of penance, and prove that I’m not actually an idiot when it comes to using Regex.</p>

<p>So this is an introductory post on using regex to perform basic tokenisation on a couple of common concepts, weekdays and clock times.</p>

<h3 id="regex-for-a-weekday">Regex for a Weekday</h3>

<p>Let’s say we want to figure out if a string of characters represents the day Monday. Well, we need to figure out all the ways we can define Monday, then define that in a pattern. Mon, mon, Monday, monday are the 4 we’ll use to start. So, how do we create a pattern to find that?</p>

<p>Firstly, we’ll note that we want the beginning and the end of the string to line up with the beginning and the end of the word. To do this, we’ll need to use Anchors. These ensure that the text being matched begins at the beginning, and ends at the end of a string.</p>

<ul>
  <li><em>^</em> =&gt; This symbol anchors the beginning of a string</li>
  <li><em>$</em> =&gt; This symbol anchors the end of a string</li>
</ul>

<p>Then we need the word itself. Let’s start with a single literal text - Monday.</p>

<blockquote>
  <p>^Monday$</p>
</blockquote>

<p>This will match the start and end of a string matching the phrase ‘Monday’. ‘ Monday’ and ‘Monday ‘ would not match.</p>

<p><img src="/assets/regex-redemption/MondayMatch.PNG" alt="MondayMatch" /></p>

<p>But what about our other permutations?</p>

<p>Well, we can handle the casing at the beginning of the word by using a range of characters.</p>

<ul>
  <li>[Mm] =&gt; this represents a match against either an upper case M or a lower case m, so we can add this to the beginning.</li>
</ul>

<blockquote>
  <p>^[Mm]onday$</p>
</blockquote>

<p>This gets us Monday and monday, but we have no abbreviation. So we need to add something to indicate that the last section is optional.</p>

<ul>
  <li>()? =&gt; wrapping braces and placing a question mark after an expression (or a single character) makes it optional, so we can add this to indicate that the suffix (day)? may or may not exist.</li>
</ul>

<blockquote>
  <p>^[Mm]on(day)?$</p>
</blockquote>

<p>Broken down it looks like this:</p>

<p><img src="/assets/regex-redemption/MondayRegexBreakdown.PNG" alt="Monday Regex Breakdown" /></p>

<p>And that’s it, we’ve got a nice little regex expression to check for Monday in various forms.</p>

<p><img src="/assets/regex-redemption/MondayCompleteMatch.PNG" alt="Monday Match" /></p>

<p>You can see the whole test suite <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing.Tests/DayMatchTest.cs">here</a>.</p>

<h3 id="groups">Groups</h3>

<p>Many versions of regex have the ability to retrieve named groups from captures, in the .Net Regex library, this is achieved by wrapping the target in (?&lt;name&gt;pattern), and when you retrieve the result of a Regex.Match(), you will be able to look in the Match.Groups[“name”] property to retrieve the value.</p>

<ul>
  <li>(?&lt;name&gt;pattern) =&gt; Capture a named group where the pattern is met.</li>
</ul>

<p>This is useful when we have a number of related patterns that we want to group together, we can use the group names, combined with the | operator, which functions as an OR condition.</p>

<ul>
  <li>this|that =&gt; match “this” or “that”</li>
</ul>

<h3 id="full-week-regex">Full Week Regex</h3>
<p>Now if we take all the regex for the individual days of the week, we can use the regex Group syntax (?&lt;dayName&gt;dayPattern), combined with the or pipe |. This enables us to set up a named match that covers each day, and when that match is met, we return the named group for the match.</p>

<blockquote>
  <p>”^(?&lt;Monday&gt;[Mm]on(day)?)|(?&lt;Tuesday&gt;[Tt]ue(sday)?)|(?&lt;Wednesday&gt;[Ww]ed(nesday)?)|(?&lt;Thursday&gt;[Tt]hu(rs(day)?)?)|(?&lt;Friday&gt;[Ff]ri(day)?)|(?&lt;Saturday&gt;[Ss]at(urday)?)|(?&lt;Sunday&gt;[Ss]un(day)?)$”</p>
</blockquote>

<p>With this regex, we can now validate a string token and convert it from a range of input values to the correct matching Enum using some basic mapping logic.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">DayOfWeek</span><span class="p">?</span> <span class="nf">Convert</span><span class="p">(</span><span class="kt">string</span> <span class="n">token</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">match</span> <span class="p">=</span> <span class="n">Regex</span><span class="p">.</span><span class="nf">Match</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">FullWeekRegex</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(!</span><span class="n">match</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nf">NotSupportedException</span><span class="p">(</span><span class="s">$"Bad Format: </span><span class="p">{</span><span class="n">token</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"Monday"</span><span class="p">].</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">DayOfWeek</span><span class="p">.</span><span class="n">Monday</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"Tuesday"</span><span class="p">].</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">DayOfWeek</span><span class="p">.</span><span class="n">Tuesday</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"Wednesday"</span><span class="p">].</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">DayOfWeek</span><span class="p">.</span><span class="n">Wednesday</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"Thursday"</span><span class="p">].</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">DayOfWeek</span><span class="p">.</span><span class="n">Thursday</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"Friday"</span><span class="p">].</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">DayOfWeek</span><span class="p">.</span><span class="n">Friday</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"Saturday"</span><span class="p">].</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">DayOfWeek</span><span class="p">.</span><span class="n">Saturday</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"Sunday"</span><span class="p">].</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">DayOfWeek</span><span class="p">.</span><span class="n">Sunday</span><span class="p">;</span>

    <span class="k">throw</span> <span class="k">new</span> <span class="nf">NotSupportedException</span><span class="p">(</span><span class="s">$"Bad Format: </span><span class="p">{</span><span class="n">token</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now we can run our word through this text converter and get back an Enum for DayOfWeek. This process is known as Tokenisation and is the first step in building a text processing system.</p>

<p><img src="/assets/regex-redemption/FullWeekMatch.PNG" alt="Full Week Match" /></p>

<p>The whole setup is available <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing.Tests/DayConvertTests.cs">here</a>.</p>

<h3 id="clock-time">Clock Time</h3>

<p>Let’s have a look at doing the same with a clock time. What’s the anatomy?</p>

<ul>
  <li>Starts with 1-2 digits to indicate the hour part.</li>
  <li>Colon character ‘:’ to separate the hour from the minute.</li>
  <li>2 digits to indicate the minute part.</li>
  <li>An optional am/pm indicator which, if omitted indicates a 24 hour clock.</li>
</ul>

<p>Based on this, we’re going to need to match the following patterns:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 12 Hr</span>
<span class="s">"8:30am"</span>
<span class="s">"08:30am"</span>
<span class="s">"8:30pm"</span>
<span class="s">"08:30pm"</span>

<span class="c1">// 24 Hr</span>
<span class="s">"20:30"</span>
<span class="s">"10:30"</span>
<span class="s">"1:30"</span>
</code></pre></div></div>

<p>So what does the pattern look like?</p>

<p><img src="/assets/regex-redemption/ClockTimeBreakdown.PNG" alt="Full Week Match" /></p>

<p>This gives us a pattern match, so we can detect a time pattern (at least approximately), but we still need to convert it into something useful, so we have to pick it apart. To do this, we’re going to go back to groups.</p>

<blockquote>
  <p>^(?&lt;hr&gt;\d{1,2}):(?&lt;min&gt;\d{2})((?&lt;am&gt;am)|(?&lt;pm&gt;pm))?$</p>
</blockquote>

<p>Here we pull apart our clock time string and take the hour digits, the minute digits and the am/pm indicator group. Then we convert that into local time with a sprinkling of number range validation, and we’re done.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="n">LocalTime</span><span class="p">?</span> <span class="nf">MatchTime</span><span class="p">(</span><span class="kt">string</span> <span class="n">token</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">match</span> <span class="p">=</span> <span class="n">Regex</span><span class="p">.</span><span class="nf">Match</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="s">@"^(?&lt;hr&gt;\d{1,2}):(?&lt;min&gt;\d{2})((?&lt;am&gt;am)|(?&lt;pm&gt;pm))?$"</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(!</span><span class="n">match</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nf">NotSupportedException</span><span class="p">(</span><span class="s">$"Bad Format: </span><span class="p">{</span><span class="n">token</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>

    <span class="kt">var</span> <span class="n">hour</span> <span class="p">=</span> <span class="kt">int</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"hr"</span><span class="p">].</span><span class="n">Value</span><span class="p">);</span>
    <span class="kt">var</span> <span class="n">min</span> <span class="p">=</span> <span class="kt">int</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"min"</span><span class="p">].</span><span class="n">Value</span><span class="p">);</span>
    <span class="kt">var</span> <span class="n">am</span> <span class="p">=</span> <span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"am"</span><span class="p">].</span><span class="n">Success</span><span class="p">;</span>
    <span class="kt">var</span> <span class="n">pm</span> <span class="p">=</span> <span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="s">"pm"</span><span class="p">].</span><span class="n">Success</span><span class="p">;</span>
    <span class="kt">var</span> <span class="n">twentyFourHr</span> <span class="p">=</span> <span class="p">!</span><span class="n">am</span> <span class="p">&amp;&amp;</span> <span class="p">!</span><span class="n">pm</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">min</span> <span class="p">&gt;</span> <span class="m">60</span><span class="p">)</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nf">NotSupportedException</span><span class="p">(</span><span class="s">$"Bad Format: </span><span class="p">{</span><span class="n">token</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">twentyFourHr</span> <span class="p">&amp;&amp;</span> <span class="n">hour</span> <span class="p">&lt;</span> <span class="m">24</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nf">LocalTime</span><span class="p">(</span><span class="n">hour</span><span class="p">,</span> <span class="n">min</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">am</span> <span class="p">&amp;&amp;</span> <span class="n">hour</span> <span class="p">&lt;</span> <span class="m">12</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nf">LocalTime</span><span class="p">(</span><span class="n">hour</span><span class="p">,</span> <span class="n">min</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">pm</span> <span class="p">&amp;&amp;</span> <span class="n">hour</span> <span class="p">&lt;</span> <span class="m">12</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nf">LocalTime</span><span class="p">(</span><span class="n">hour</span> <span class="p">+</span> <span class="m">12</span><span class="p">,</span> <span class="n">min</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">throw</span> <span class="k">new</span> <span class="nf">NotSupportedException</span><span class="p">(</span><span class="s">$"Bad Format: </span><span class="p">{</span><span class="n">token</span><span class="p">}</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And we can see that running against our range of formats <a href="https://github.com/TristanRhodes/TextProcessing/blob/master/TextProcessing.Tests/TimeConvertTests.cs">here</a>:</p>

<p><img src="/assets/regex-redemption/ClockTimeConversion.PNG" alt="Full Week Match" /></p>

<p>Now we have the logic to determine if a string matches a Weekday or ClockTime pattern, and return the appropriate typed object we’ve got the first steps of a system to tokenise strings. I’ve spun up a small repo to play with these concepts, it’s available <a href="https://github.com/TristanRhodes/TextProcessing">here</a>, and I’m going to use it as a sandbox to dive further into the really cool powerful things you can do with regex and tokens.</p>

<p>If you want to pull the repo and have a play, there are a couple of exercises you can do:</p>
<ul>
  <li>Can you make the day converter process say, German/French as well as English interpretations of days?</li>
  <li>What other international clock formats are there? Can you add support them?</li>
  <li>Create a basic tokeniser for an enum representing Hotel Room types, or Retail Stores.</li>
</ul>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[I felt the need to write a post to prove that I do actually know how to use regex....]]></summary></entry><entry><title type="html">Check Your Assumptions</title><link href="https://www.tristan-rhodes.co.uk/2021/11/25/check-your-assumptions.html" rel="alternate" type="text/html" title="Check Your Assumptions" /><published>2021-11-25T00:00:00+00:00</published><updated>2021-11-25T00:00:00+00:00</updated><id>https://www.tristan-rhodes.co.uk/2021/11/25/check-your-assumptions</id><content type="html" xml:base="https://www.tristan-rhodes.co.uk/2021/11/25/check-your-assumptions.html"><![CDATA[<h2 id="regex">Regex</h2>

<p>I use a lot of regex. I’ve written parses and tokenisers for a wide range of DSL’s and data formats. So one day, I reached for my Regex-fu to validate a credit card number, and it was gone. Like superman finding he suddenly couldn’t fly, I found myself glued to the earth, taking the stairs…</p>

<h2 id="whats-going-on">What’s going on?</h2>
<p>Does this look right to you? Because it sure didn’t look right to me…. and I spent a <em>long</em> time staring at it.</p>

<p><img src="/assets/check-your-assumptions/NotARegexBug.png" alt="Not a regex bug" /></p>

<h2 id="whats-really-going-on">What’s <em>really</em> going on?</h2>

<p>So… what is this dastardly bug that has cropped up? Why are my tests failing, and how did I get there? Well… I started with the simplest scenarios. This seems like a solid start right? We’re all good?</p>

<p><img src="/assets/check-your-assumptions/AllGood.png" alt="All Good" /></p>

<p>That all works right? Regex magic all good. But when I added the new scenario above, it failed. And this confused me, because I knew it worked on the simpler scenario, that assumption was now in my white list. My test pass, they prove the regex is correct, but a new scenario failes then it has to be a bug, right?</p>

<p>Well… not quite. See… here’s the thing…</p>

<iframe src="https://giphy.com/embed/NmerZ36iBkmKk" width="480" height="323" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe>
<p><a href="https://giphy.com/gifs/NmerZ36iBkmKk">via GIPHY</a></p>

<p>Regex… has <em>TWO STRING PARAMETERS</em>. Do you know what happens if you put them in the wrong order? <em>It don’t work right</em>. So what was my assumption? That the Regex pattern was on the left.</p>

<p>But… why didn’t we catch that? Surely the tests would have picked up that the Regex and the check are in the wrong order? We validate both the positive and the negative… But…</p>

<p><img src="/assets/check-your-assumptions/Oops.png" alt="Oops" /></p>

<p>This check string matches the valid pattern, and the pattern matches the valid check string, so it works either way round.</p>

<p>So yeah, assumptions creep in, and you forget to go back to basics and re-validate.</p>

<h2 id="sick-note">Sick Note</h2>
<p>I totally want to play my sick note card here. I had food poisoning and spent hours peering through heavy brain fog.</p>

<iframe src="https://giphy.com/embed/3o6ZsWFclZCXU3SuSQ" width="480" height="270" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe>
<p><a href="https://giphy.com/gifs/southparkgifs-3o6ZsWFclZCXU3SuSQ">via GIPHY</a></p>

<p>But I don’t really have any excuse… this is just one of those experiences that keeps you humble.</p>

<p>So in a note to other devs… sick or not, check your bloody assumptions before you do something <em>really stupid</em> like filing a report for a <a href="https://github.com/dotnet/runtime/issues/62017">non existant bug</a>.</p>

<h3 id="credit">Credit</h3>
<p>Header Image by <a href="https://pixabay.com/users/openclipart-vectors-30363/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=152211">OpenClipart-Vectors</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=152211">Pixabay</a></p>]]></content><author><name>tristan-rhodes</name></author><summary type="html"><![CDATA[Sometimes we know something so well, we assume we can't make an obvious mistake.]]></summary></entry></feed>