Wednesday, June 29, 2016

A Look Back at June 2016

This is normally where I would list my speaking engagements for the upcoming month (July 2016), but there aren't any. I guess I'll be taking a month off of speaking. Considering how busy I've been so far this year (21 events / 30 talks), it's probably good to rest a bit.

Of course, if any of my Workshops or Presentations look interesting, be sure to contact me, and we can talk about setting something up.

A Look Back
June was a busy month. So let's take a look back at the awesome events that I spoke at (and got to attend).

NDC Oslo
It's still hard to believe that I went all the way to Norway to speak at a conference. NDC Oslo is an *amazing* event. It takes place at the main event center in the city (where concerts and sporting events are held).

I really like the layout. The main floor is used as the expo area, and there is food service *ALL DAY LONG*. I wish that more events would pick up on this. When I'm traveling and speaking, I don't always have time to eat at the right times -- and when I'm several time zones off, I don't always feel like eating at the right times either. Here's a picture of the expo area:

The session rooms surrounded the expo hall, and many of them were up in the arena seating areas and included a stage that was hanging from the ceiling. Interesting layout that works surprisingly well.

Another great thing is the overflow room. Some people call this the "ADD Room" because you can flip back and forth and try to watch all 9 talks at once. Here's a view from the back side of the room:

There are live feeds from all 9 session rooms, and a headset pipes in the audio. Just switch channels to watch a different talk. I most appreciated this when I was really tired and didn't want to risk falling asleep in front of the speaker. (There are times when it doesn't matter how interesting the speaker is, how interesting the topic is, or how much you want to hear the talk. Sometimes you just can't stay awake.)

My presentations were a lot of fun. I had a talk during the first session slot on "Becoming a Social Developer":

Thanks to Pavneet Singh Saund (@pavsaund) for the picture.

You can read more about how it went here: "Becoming a Social Developer" at NDC Oslo. And if you'd like to watch the talk, it's available here: Video from NDC Oslo.

One really exciting thing happened. My topic was featured in the NDC Oslo opening day re-cap video:

Later in the week, I talked about how design patterns are for everyone -- not just architects:

If you look at the left side of this picture, you can see the girders that held up the stage (along with the 3 pulleys holding everything up). It was a bit disconcerting to look over the edge and see a 30 foot drop. But I tried not to think about it (even though the stage swayed a bit when I walked around).

This picture gives a good idea of what the seating was like in these "rooms":

Thanks to Jonathan Mill (@jonathanfmills) for both of these pictures.

You can watch a video of the talk here: "Learn the Lingo: Design Patterns" at NDC Oslo.

I had a great time. I saw a lot of people that I knew from the US. And I met many new people. I now have friends in Germany, Sweden, Norway, England, Denmark, Poland, and other places in Europe. In addition, Oslo is a beautiful city (at least in June -- I'm not sure how I would like it in January). Next time I go, I'll need to make sure to have a few extra days to do some exploring. My trip was way too short.

Irvine Programming Meetup
There's a brand new user group in Irvine -- the Irvine Programming Meetup. I got to speak at the 2nd meeting:

I had a great time talking about Dependency Injection. You can watch a recording of the presentation here: Video from Irvine Programming Meetup.

Kansas City .NET User Group
Last week, I was in Kansas City for KCDC. But before the conference, I was invited to speak at the Kansas City .NET User Group. I got to share another topic that is dear to me: Unit Testing Makes Me Faster. It was a great turnout, especially considering that they moved their date to accommodate my travel schedule (Thanks again for that).

The most encouraging part was to get a tweet from Duane Newman (@duanenewman) this week:

I'm glad that I could encourage people to approach unit testing with an open mind. It's not a hindrance. It actually makes things go faster.

Thanks also to Duane for taking the picture above.

I had heard really good things about KCDC, and I was very excited when I was selected to speak this year. It was an *AMAZING* event. I got to see many of my friends in the Midwest (most of whom I first met at Nebraska.Code() last year). And I got to meet a ton of new people.

The sessions were first-rate, the speakers were excellent, and I had a really great time.

I was very happy with my presentations. On Thursday, I got to speak about interfaces: "IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces":

Thanks to Cori Drew (@coridrew) for the great picture. And thanks to Cori for hanging out with me during the week. It was great to get to know her better.

I always like to talk about interfaces -- mainly because this topic was very hard for me to learn. I knew interfaces were important, but I didn't know why. Once I got a handle on this, they became very important to me as a developer. I love to help people take the short cut to understanding.

The next day, someone came up to tell me how helpful the presentation was. Many of the things that they were seeing in code at work now made sense. That's what makes this all worthwhile to me. The benefit I get from speaking is finding out that I made someone else's job easier.

The next day (last day of the event), I got to speak on asynchronous methods: "I'll Get Back to You: Task, Await, and Asynchronous Methods":

Thanks to Dave Fancher (@davefancher) for the picture.

I think that I was almost as caffeinated as my shirt:

Thanks again to Cori for this picture.

I know it was an awesome event because I was exhausted when it was over (I even slept for a bit on the plane). I met a ton of new people, and I got to spend time with friends in the area. I'm always amazed at how easy it is to pick up conversations with someone even if you haven't seen him/her for several months (or even a year).

I had the great chance to start out my week with lunch at Q39:

Thanks to Cory House (@housecor - left), Heather Downing (@quorralyne - center), and Matthew Renze (@MatthewRenze - right) for taking the time to meet up with me. It was a great start to a great week.

A Look Ahead
Even though I won't be speaking in July, I've got quite a few events lined up for the rest of the year. In August, I'm headed to Music City Code in Nashville TN. In September, I'm going to AIM hdc in Nebraska. Also in September, I'll be at SouthBay .NET in Mountain View CA.

At the tail end of September, I'm offering a full-day workshop as a part of Code Stars Summit in San Jose CA. This is your chance to spend an entire day with me learning about interfaces and dependency injection. Sign up now to get the early-bird pricing. If you wait too long, you'll miss your chance.

October is going to be a bit crazy. Right now, I'm confirmed for Silicon Valley Code Camp in San Jose CA, the Desert Code Camp in Chandler AZ, and DevUp in St. Louis MO. Plus I have a few tentative items that I'll announce once they get confirmed.

For a full list of upcoming events, just check my website: JeremyBytes - Upcoming Events.

I'm doing a lot of speaking and traveling. And I really love to do it. If I can help make other developers' lives better, then I'm accomplishing my goal. I love to watch people learn, and I love to be useful (don't we all).

I'm looking forward to meeting lots of new people, catching up with friends, and going places I haven't been before. (It's still hard to believe I was actually in Norway a few weeks ago.)

It took me a long time, but I really feel like I found a spot that I fit in the world (at least for now). I hope that you find the same.

Happy Coding!

Functional Practice: Euler Problem #1 in F#

Time for a little more coding practice as I'm learning F#. And for that, I'm headed back to Project Euler. Many of these problems lend themselves to functional-style solutions.

I took a look at Euler Problem #1 way back in October 2013 (wow, has it been that long already?) with a solution in Haskell. Since I've already thought about this problem, putting together a solution in F# was pretty simple.

[Update: Collected articles for the first 10 Euler Problems in F# are available here: Jeremy Explores Functional Programming.]

Euler Problem #1
Here is problem 1:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
For the solution in Haskell, we built things up step-by-step. We'll do the same thing here for F#.

Building a Solution
We'll start with the example with the numbers below 10. Once we have a matching output, we'll expand it to work with numbers below 1000.

The first step is to get a list of the natural numbers below 10:

The "[1..9]" creates a list that gives us the natural numbers below 10 -- which translates into integers from 1 to 9 inclusive.

For these examples, I'll just show the input (from an F# script file) and the output (from the F# Interactive window). I prefer using a script file for syntax highlighting and such. But this would work just the same if we typed things into F# Interactive directly.

Piping Forward
The next step is to get the numbers that are multiples of 3 or 5. For this, we'll use the "filter" function:

The "List.filter" function takes 2 parameters. The first parameter is a function used to filter the data. We just have to return a true/false value to determine whether the list item is included in the resulting list. In this case, we use a function that checks to see if "x" is evenly divisible by 3 or 5 (using the modulus operator).

This is very similar to the LINQ "Where" function in C# that takes a "Func<TSource, bool>" (a delegate) as a parameter. The anonymous function we show here is equivalent to a lambda expression in C#.

The last parameter of the "filter" function is the list. In F# (and other functional languages), it is common to have the data parameter as the last parameter. This is a bit different than C# programmers are used to; in C#, we usually put the data parameter as the first parameter (since it's most important).

One reason that we like to have the data parameter last is so that we can easily use pipelining -- where we pass the output of one function as a parameter to another function. In F#, we use the "|>" operator for this. Here's the same function re-arranged to use pipelining:

In this case, we create the list on the first line, then we pipe the output of that list creation to the "List.filter" function. This uses the list as the last parameter of the "filter" function. And this is why we like to have the data parameter as the last parameter of a function -- we can easily pipe the output of a function into the input of another function.

Side note: Another reason to have the "important" parameter last is so that we can do partial application of functions -- but that's not something that we'll be talking about today.

These two ways of calling "List.filter" are equivalent. But when we use pipelining, we give ourselves a very easy way of chaining functions together.

Summing the List
The pipelining doesn't seem too useful when we just have 1 function (well, technically, we have at least 3 functions here, but it looks like 1). But it gets much more interesting when we add more functions. The last step in our problem is to sum the results. We'll just pipe the results to the "List.sum" function:

"List.sum" take a single parameter: a list of values to be added together. When we pipe our filtered list into the "sum" function, we get our expected result of 23.
I really like how easy it is to chain functions together with pipelining. It feels very natural (especially since I'm such a big fan on LINQ in C#).
Completing the Challenge
Now that we've replicated the sample, it's time to see if this works for the full list:

This gives us all the natural numbers below 1000, filters it to values evenly divisible by either 3 or 5, and then sums the result. We've previously verified the result for Euler Problem #1, so we know that this value is correct.

A Reusable Function
As a final step, let's create a function that is reusable. For this, we'll just add a declaration and a parameter:

We called this "euler1" and it takes a parameter "belowThis". This will create a list that ends just below the value passed in. This way, we can call the function with the same values that are in the problem.

Note: We don't have to declare a type for "belowThis" because F# uses type inference pretty much everywhere. Since we're using "belowThis" as an integer (by subtracting one and using it as a value for our list creation), F# determines this is an integer, so we don't have to put that in. Cool stuff (although I sometimes have issues reading code -- I'm hoping I'll get used to it, but I also worry a bit about people who are new to the environment getting frustrated).

For example, this will use all natural numbers below 10:

And here is a call for all numbers below 1000:

We can see that our output values are still correct.

And in case you're wondering, yes, it does fit in a tweet:

Wrap Up
So that takes us through Euler Problem #1 using F#. Nothing too groundbreaking here. And lots of people have solved this problem before. For me, this was a good bit of coding practice, and it helps me get more familiar with F# (which is really my goal here).

The next Euler problem uses the Fibonacci sequence. And creating a "functional" Fibonacci sequence while keeping decent performance has been a problem for me in the past. I might put that on hold a bit while I go through some of my F# books to learn more about the language and constructs. I'm sure there will be a bit of trial and error there.

This type of exploration is how we can learn new things. And even if we're not learning anything new, it helps us get more comfortable with the tools, language, and environment.

Happy Coding!

Monday, June 27, 2016

Unit Test Factory Methods: Return an Interface or a Mock?

Had a great question today regarding what to return when using factory methods with unit tests:
Should a unit test factory method return the interface or a mock of the interface?
The best way to look at this is to look at an example. Let's say that we have a class ("DataParser") that take an "ILogger" as a constructor parameter. This class would look like this:

Now in our tests, we want to test the "ParseData" method behavior. But we need an "ILogger" to satisfy the constructor parameter. In some situations we just need the "ILogger" for construction (technically, behaving as a stub), and for other situations, we need to assert against the "ILogger" (behaving as a mock).

So if we have a factory method, should it return "ILogger" or "Mock<ILogger>"? Here's what the options would look like:

Note: this code is using Moq for mocking. This mocking framework has met most of my needs over the years.

Before going any further, I want to say that my "recommendation" is just my opinion -- this is the way that I prefer to do this. Roy Osherove (who wrote the excellent The Art of Unit Testing) says that we need to make a clear distinction in our code between a stub and a mock. (Also, he's not a fan of Moq as a mocking framework because it does not make that distinction.)

What I've found is that in the tests that I've written, that distinction is unneeded. So, I've chosen a direction that (hopefully) minimizes confusion and enhances readability of the code.

Picking One
One option would be to keep both of these methods and use "GetLogger" when we need a stub and "GetMockLogger" when we need a mock. I would rather minimize the number of factory methods that I have unless they are really needed, so I'm going to pick one.

Note: it's perfectly valid to keep both of these; however, I might recommend having the "GetLogger" method call the "GetMockLogger" method so that we are only creating mocks in one place.

So, let's look at both options, and then I'll give you my preference.

Option 1: Returning the Mock<ILogger>
Let's start by looking at a factory method that returns the mock object:

A test that needs a stub would look like this:

Notice that when we create the "DataParser" object on the second line, we need to use the "Object" property of our mock. This gets the actual "ILogger" object out of our mock so that we can use it as a parameter for our constructor.

I don't really like this. It requires too much knowledge of the mocking framework inside the test. If the test does not care about the mock object, I don't want it to be "polluted" with that knowledge.

Option 2: Returning ILogger
So, what if we have our factory return "ILogger"?

We still create the mock object (because we may still need the in-memory behavior of a mock), but we return the "ILogger" itself from the factory.

Then our test would look like this:

I like this much better. This test does not care about whether we have a mock or a fake (meaning, a real class that implements the interfaces and is used for testing purposes). And I think it lends to the readability: we don't have extra stuff that stops us from reading the code.

But What if We Need a Mock?
There are times that we really need a mock object. For example, in this case, we want to verify that the "ILogger.Log()" method is getting called the right number of times by our "ParseData" method. So what does that code look like?

Returning Mock<ILogger>
If we use the method that returns the mock, then our test could look like this:

In this case, we actually need the mock, because we are calling the "Verify" method on it. In Moq, the "Verify" method lets us check to see if a method was called with certain parameters or called a certain number of times (among other things). In this case, we are checking that the "Log" method is called only one time (that's the "Times.Once()" parameter).

We don't care about the parameters, which is why we have the "It.IsAny<string>()" methods in there. I won't get into the details of those right now. We'll save those for a longer article about mocking.

This code is pretty clean. So, let's look at the other option.

Returning ILogger
We can still use the method that returns "ILogger" here. That's because of one of the features of Moq. Here's what that same test looks like:

Notice that we get the "ILogger" from the factory and then pass it to the "DataParser" constructor. But since we want to use the "Verify" method, and that requires a "Mock<ILogger>" to work, we need to do a little extra work.

The last line of the "Arrange" section uses the "Mock.Get()" method. This is a static method in Moq that allows us to take an interface that has been mocked and get the original mock object back. We can see in this case, we end up with a "Mock<ILogger>", which is just what we need.

The rest of the test, including the call to "Verify" is the same as above.

The Danger
This code seems a little bit dangerous. What if "ILogger" is a fake object (instead of a mock)? Well, this code will throw an exception. "Mock.Get()" will only work with objects that were created with Moq.

This means that if we change the "GetLogger" method to return a fake instead of a mock, all of the tests that need a mock will blow up.

Am I worried about this? Not really. If I need a mock object that I'm running assertions against, then I'm probably extra aware of what's going on in the factory methods.

My Preference
So, my preference is to have a single factory method that returns an "ILogger":

Then my tests look like this:

This gives me the most readable code for the first test (where I just need a stub and don't care about asserting against the "ILogger"). This also makes writing these tests really easy. I don't have to worry about the internals of my mocking framework.

The second test is a bit more dangerous, but because I'm asserting against a mock object, I'm going to be paying closer attention to this anyway. And if I'm writing new tests that assert against the mock object, I'm going to have to know something about the mocking framework. So it makes sense to need that additional knowledge here instead of in the "simple" test.

As I noted above, this is just my preference based on my experience. I've written several different kinds of unit tests (and lots of them), and this "feels" the best to me.

Wrap Up
Your mileage may vary. It is perfectly valid to have *both* factory methods, but I prefer to keep factory methods to a minimum. And as I noted before, the distinction between stubs and mocks is more of a technical one in my world -- having the clear separation between them has not been important.
When you're new to unit testing, you'll come across lots of opinion and even more "best practices". 
Try out the ones that look interesting. If they fit into your environment, then keep them. If they don't fit, then feel free to discard them. This is part of the process of learning what works best for you. And that may be different than what works best for me.

Happy Coding!

Digit Recognizer - Grouping Items and Visualizing Errors

So, I've been making some UI changes to my Digit Recognizer project to try to make it easier to visualize the data. Last time, we used the F# code so that we could play with the code a bit. You can read about it here: Exploring the Digit Recognizer with F#.

But we were displaying the source bitmap alongside the prediction from our machine learning algorithm:

This is pretty cool, but it's a bit hard to read, and it doesn't size well. So today, we'll group the bitmap and textbox together in a button. That way, we can click on the button to show which items are incorrect:

This is one step closer to easily analyzing the data visually (which is where I'm headed with this).

The actual display output will change visually depending on what resolution you're using (I'm going to be looking at this in the future). I'm running this application at 1280x800 and showing a little under 200 digits here.

The code for this is available in GitHub: jeremybytes/digit-display -- specifically, this code references the UIAwesome branch.

Grouping the Items
Previously, I created a bitmap (to represent the source data) and a textbox (to represent the prediction) and added them to the wrap panel individually. This lead to some issues when resizing the screen (the items would not always be grouped together).

Here's the code for that (where I started):

So, I added a button that would contain both the bitmap and the textbox. Here are the button-related bits:

This creates a button and adds the items that we created earlier. Then we add the button to the wrap panel.

This keeps the items "paired" so that we don't have to worry about resizing the application and throwing off our display.

Flagging Errors
The other thing I wanted to do was add the ability to flag the incorrect items. This obviously takes human intervention. Previously, I was scanning through the screen and counting the incorrect ones. Now that I had a button, I could add in some functionality to help with that.

In the code snippet above, you'll notice that there is a "ToggleCorrectness" method hooked up to the button click event handler. Here's that code:

When we click on one of the buttons, it will toggle the background color (to light red) and also increment our error count which displays at the top of the screen. We can also toggle back to "correct" if we hit a button by accident.

There were a couple other minor changes that I had to make as well -- such as making the bitmap transparent. You can check the code if you're really curious about that.

The Result
The result of this is that we can visually see the bitmaps along with the predictions and then flag the items that are incorrect:

Here we can see that there are 6 errors in our data (there might be a couple more if you look closely -- if I couldn't tell what the digit should be, then I didn't fault the computer for getting it wrong).

This makes it easier to see the items that are incorrect. It's still a bit tedious, though. Since it needs a human (me) to flag the items, I need to scan through all of the numbers. And quite honestly, my brain gets bored easily, so I'm sure that there are some items that I'm missing.

In case you're curious, this code is using the Manhattan Distance algorithm, and it is using the full training set (over 40,000 items).

Reminder: The code for this is available in GitHub: jeremybytes/digit-display -- specifically, this code references the UIAwesome branch.

Next Steps
This is really an interim step. As I mentioned previously, I'm really interested in seeing how different algorithms behave differently, and I'm also curious about how altering the size of the training set affects both the accuracy and the speed.

One other thing I'd like to do is add an "offset" so that I can start looking at data at an arbitrary (but repeatable) location. This will make sure that I'm not just optimizing for the data that is in the "first" part of the validation set.

So my next steps are a few more UI improvements to let me pick these different variables -- right now, they are in the code, and I have to rebuild/rerun to try different scenarios. I'd really like to be able to see the different outputs without having to alter code and rebuild the application.

I've been enjoying this exploration, and I'll keep doing it even though it doesn't have specific application. Many times, when we dig into things that don't have an immediate value, we find things that are really helpful in the future.

Happy Coding!

Saturday, June 18, 2016

FizzBuzz in F# in 99 Characters

I haven't done a whole lot with functional programming for a while. But at NDC Oslo, I got to hang out with the FP folks, and it inspired me to start exploring (and playing) again. I picked up my Digit Recognizer project and got the F# code integrated. (And I've done more with that project since the last article; I'll be writing that up soon.)

So, I've been playing and exploring a bit. And I put together a very compact implementation of FizzBuzz. We'll see why I was headed for "compact" a bit later.

FizzBuzz is a pretty simple programming problem. There are only a few rules:
  1. Print the numbers from 1 to 100.
  2. If the number is divisible by 3, print the word "Fizz".
  3. If the number is divisible by 5, print the word "Buzz".
  4. If the number is divisible by both 3 and 5, print "FizzBuzz".
Since this is a pretty simple problem, I've found it as a good way to get started with TDD (in C#). You can check out a video of that here: New Video: TDD Basics with C#.

Here's one way of implementing a method that fulfills the rules:

Why FizzBuzz and F#?
When I've been working with F#, I've been really interested in doing things the "functional way". I figure the more that I can do that, the more I can wrap my brain around the functional concepts that are just beyond my grasp at the moment.

But when I tried to do FizzBuzz in F#, I ran into a roadblock. The implementations that came up with were all very imperative in nature. The C# code above is pretty straightforward: we start with an empty string, append "Fizz" and/or "Buzz" if appropriate, and if we don't append either one, then we print out the original number.

But this deals with a mutable object (the "output" string).

I even talked to some of the functional folks at an even back in November, and one of the suggested solutions used if/elif/else:

This works -- it generates a list with the proper data -- but it felt too much like the code I'd written in C#. I wanted something a bit "more functional" (yes, I know that's not strictly necessary, but I'm still learning and trying to get the concepts and language features).

Help from Elixir
The reason that I'm back on this today is that I just watched the recording of Bryan Hunter's (@bryan_hunter) talk at NDC Oslo: What every Node.js developer needs to know about Elixir. He showed an Elixir implementation of FizzBuzz:

And this gave me a great idea of how I could use pattern matching in F# to do the same thing.

So, I didn't write anything original, but I translated it from Elixir to F# (which is actually a pretty good accomplishment considering my current experience with the language).

Pattern Matching in F#
So, here's the code in F#:

Let's walk through this.

First, the "[1..100]" creates a list consisting of the integers from 1 to 100.

Then we use the pipe-forward operator "|>" to pass that to the "" function. The "map" function will apply a function to each of the elements in our list.

Then we have the function that uses pattern matching to get what we want. The "fun x ->" tells us that we have a function with a parameter called "x". In this case, "x" is the integer that represents the value of a list element.

Then we have the "match" expression. The first part "(x % 3, x % 5)" will create a tuple with 2 values. This uses the modulo operator "%" to get the remainder when we divide by 3 for the first value, and divide by 5 for the second value.

So if "x" is 9, our tuple would be "(0, 4)" since 9 divided by 3 has a remainder of 0, and 9 divided by 5 has a remainder of 4.

After the "with", we have the patterns that we're trying to match.

The first pattern "(0, 0)" tells us that the number is evenly divisible by both 3 and 5 (since the remainders of both after division is 0). So we want to output "FizzBuzz" here.

The next pattern "(0, _)" tells us that the number is evenly divisible by 3 (the first value). For the second value, we have an underscore. This means that we don't care what this number is. Since the number is divisible by 3, we output "Fizz". (Our example above, "(0,4)" would match this pattern.)

The next pattern "(_, 0)" tells us that the number is evenly divisible by 5 (the second value). We don't care what the first value is in this case. Since it's divisible by 5, we output "Buzz".

The last pattern "(_, _)" says that we don't care what the values are. This is a "catch all", and will simply convert the integer to a string.

Since this pattern matching is greedy (meaning the first pattern to match wins), we know that we'll get the output that we want. If we reordered things, then we would get unexpected results.

Here's the output when we run this in the REPL:


And I liked this implementation much better than using the if/elif/else. The pattern matching seemed like a "better" solution since pattern matching is such a key component of F#. This gave me a chance to use it and explore a bit.

Paring Down to 109 Characters
Since this implementation was fairly compact, I decided to see how small I could make it. So, I took out all of the white space that I could:

This isn't very readable, but it's only 109 characters. This got me within my goal.

What's the goal? Well Mathias Brandewinder (@brandewinder, who I've mentioned many times) wrote a Twitter bot that parses F# and sends back results. He showed me this at the Microsoft MVP Summit last November, and I thought it was pretty cool.

Basically, you just send a tweet to @fsibot, and it will tweet back with the result. (As an aside, Mathias showed me all of the parsing and input sanitation that he has to do to make sure that no one does anything malicious with it. It's quite a challenge.)

Since 109 characters will fit in a tweet, I sent it in:


The Purpose
Is this world changing? Absolutely not. But it is interesting. It is a bit of a challenge. And it's also a bit of fun. I had a good time exploring, and I learned a bit more about pattern matching.

BTW, I found that I actually have some extra characters. The parentheses around the patterns can be removed:

This removes several more characters (also notice that the last pattern simply has a single underscore -- this still acts as the "catch all").

This brings the total down to 99 characters:

Cool stuff.

I've found a bit of joy in the functional programming that I've been doing recently. I'm definitely going to continue. My travel schedule lightens up a bit in July. That will be a good time for deep dive.

Keep exploring, and find those things that pique your interest and make coding fun.

Happy Coding!