Hidden .NET Gems – ReactiveUI

0

Hi,

Today, I’m going to talk about an open source gem in .NET for developing WPF applications for people who are interested in reactive and functional programming. To understand the work behind ReactiveUI, one mst understand Rx, or rather Reactive Extensions for .NET. The goal of the syntax of ReactiveUI for read-write properties is to notify Observers that a property has changed. Otherwise we would not be able to know when it was changed as it’s mentionned on their website. This is super cool because it allows you to abstract mutable state away from your user interfaces and express the idea around a feature in one readable place whilst improving application testability.

To have a better understanding why you should take a look at reactive programming, take a look at the following Youtube videos:

Soon, I’ll be building a Xamarin application with ReactiveUI. I’ll also weight the pros and cons of implementing the business logic with Akka.NET and F#. Keep on reading and you’ll see it briefly.

 

Kevin

 

 

Bullet points formatter

0

Hey guys,

So this week I worked on a small code kata. The purpose of this project is to simply be able to format text into a bullet point like any text editor allows you to do it. To complete this challenge, I decide to use F# since it’s so great for prototyping and get fast results. The project had the following requirements:

  • Produce an outline of headings
  • Heading values are provided

Here’s an example of what should be printed in console :

  1. Software development is

A. An awesome thing to do

2.  Why do code katas ?

A. They are

i. Entertaining

ii. Challenging

So as we can, we have three different level of formatting to do on the string and heading values are provided for the formatting. Those requirements led to the following code :

code language="fsharp"]
 open System
 open System.Linq 

type Indexes = {
     Primaryint 
     Secondary int
     Third int 
 }
type BulletPointStyle =
     | NumberedStyle 
     | LetteredStyle 

type HeadingWeight = 
     | HW1 
     | HW2 
     | HW3 

type Heading = {
     Weight HeadingWeight
     Text string
 }

type Node = {
     Line Heading 
 }

type Outline = {
     Text string 
     HeadingIndexes Indexes
 }
 with 
     member x.addContent str = { x with Text = x.Text + Environment.NewLine  + str }

let updateIndexes (oOutline) (hHeading) = 
     match h.Weight with 
     | HW1 -> 
         let indexes = { o.HeadingIndexes with Primary = o.HeadingIndexes.Primary + 1Secondary = 1 ;Third = 1 }
         { o with HeadingIndexes = indexes }
     | HW2 -> 
         let indexes = { o.HeadingIndexes with Secondary = o.HeadingIndexes.Secondary + 1Third = 1 }
         { o with HeadingIndexes = indexes }
     | HW3 ->
         let indexes = { o.HeadingIndexes with Third = o.HeadingIndexes.Third + 1 }
         { o with HeadingIndexes = indexes }       

let determineBulletStyle (hwHeadingWeight) = 
     match hw with 
     | HW1 -> NumberedStyle
     | HW2 | HW3 -> LetteredStyle

let getLetter (indexint)=
     (("ABCDEFGHIJKLMNOPQRSTUVWXYZ".[index-1]).ToString())

let formatTextNode(nNode) (oOutline)
     let header = n.Line
     let mutable text = ""
     let style = determineBulletStyle header.Weight
     let indexer = o.HeadingIndexes
     match style with 
     | NumberedStyle -> 
         text <(indexer.Primary.ToString()) + "" + header.Text
     | LetteredStyle -> 
         let head = 
             match header.Weight with 
             | HW2 -> String.Join(""Enumerable.Repeat(" ",4)) + getLetter indexer.Secondary
             | HW3 -> String.Join(""Enumerable.Repeat(" "8)) + String.Join(""Enumerable.Repeat("i"indexer.Third))
             | _ -> ""
          text <head + "" + header.Text 
     text

// Folds an Outline and a list Nodes to an Outline
 let formatTextOutline(nodeListNode list) =
     ( { Text = ""HeadingIndexes = { Primary = 1Secondary = 1Third = 1 } }nodeList) 
     ||> Seq.fold (fun outline node -> 
         let text = formatTextNode node outline
         let outline = outline.addContent text
         updateIndexes outline node.Line
     )

[<EntryPoint>]
 let main argv = 
     let nList = 
         [
              { Line = { Weight = HW1Text = "Software development is" } } 
              { Line ={ Weight = HW2Text = "Super fun" } } 
              { Line ={ Weight = HW3Text = "But challenging" } } 
              { Line ={ Weight = HW3Text = "And rewarding" } }
         ]
     let outline = formatTextOutline nList
     printf "%s" outline.Text
     0 // return an integer exit code

[/code]

So basically, the process is made thanks to formatTextOutline and formatTextNode. Through those functions, I can create the Outline record that holds the formatted text and the indices for the level of formatting (Indexes). When I get in formatTextNode, I can first establish the heading style of the line thanks BulletPointStyle discriminated union(DU) type. Using the style enables me to know if I only have to take care of numbers or the letters. When I have to deal with characters, the HeadingWeight DU becomes handy to see whether or not I’ll be using a single tab (4 spaces) or a 2 tabs (8 spaces).

There you go ! 🙂

Kevin out