In my last post I mentioned a new F# repo on Github for a Simple Password Checker. In that example I was comparing and storing passwords in clear text. Since this is a terrible idea and something that you should NEVER EVER do in production I decided to come back and create a function to hash my passwords. During the course of development I ended up rewriting the function several times to be more function. So I thought I would share my process and walk through going from a C#/OO mindset to a more F#/ FP coding style. Before you get started you will need to add 2 open declarations to get the required modules. Required Modules
With that out of the way, let's start by looking how I would solve this problem with a C#/OO mindset. Get Password Hash Original
This function works, it does the job but there are several intermediate variables that are only used once and 1 mutable variable. So let's see how we can clean this up. Immutable by default and no state are some of the corner stones of functional programming, so let's get rid of that loop first. But how do we do that? We need something that will go over the array, accept an initial state, do some action and return the new state before repeating the process again. It turns out that the creators of F# thought about this and gave us the Seq.Fold function. Get Password Hash after removing loop
That's much better. All variables are immutable, we removed a loop and we are letting the compiler take care of building the hash string output. Next on our list is tackling those intermediate, single use variables. In C# we could chain all those calls into a single method call, but that would be difficult to read and we would have to start at the inner most method and work our way out. It would be nice to be able to read from left to right and clearly understand what is happening. That would be a dream, some would say even a pipe dream (sorry for the terrible pun :-)). Get Password Hash written functionally
And there we have it. We have gone from a 7 line function with 5 intermediate, single use variables, 1 loop and 1 mutable variable to a 2 line function with a single intermediate variable, 0 loops, and no mutable variables. I left the sha512 variable by itself because I wanted to use the 'use' keyword. Use in F# is the same as using in C#. That's it for today. Stay tuned as I add user registration via a front end API and publish all this to Azure.
Hope you learned something and enjoying this post. As always, Happy Coding. I've been reading Isaac Abraham's book Get Programming with F#. It's been a very good introduction to the F# language, syntax, and operators. During one of the chapters that discussed folding, mapping, and filtering lists, arrays and sequences we created a simple validator program. I decided to extend it a bit and add the ability to look up previous passwords in a database. I created a repo on github and started on my simple password checker. After searching for recommended data access solutions I settled on trying Fsharp.Data.SqlClient as my ORM. Being totally new to Fsharp and this library I ran into a few issues and thought I'd share my learnings in this, the second, entry to the Quick Tips series. 1). The first thing I learned was that the client is activity checking your database schema as you are typing your query. So if you misspell a column name or don't add [] around an object that is a reserved SQL Server keyword you will get compile time errors. This was totally new to me and took me awhile to figure why I was getting a compiler error. Now that I know that's what happening I really like the feature. The downside that I can see is that it forces you to design and create your database before you start coding. 2). I was having trouble mapping the output results to my domain record. So I started experimenting with the different ResultType options. Here you can see how I specified the result type when creating the command provider. If you do not supply a type then the default of Records will be used. The command also provides a normal Execute function, which I could have used since I just called Async.RunSynchronously right away. 3). After continued experimenting, I found that I did not actually need a domain object for this example. Normally, in C# I would have created a simple POCO and used that as a DTO. Since the F# compiler has a stronger type system, even for dynamic objects, I did not need to create a DTO. Instead what I was able to do was access the columns by name in the rules engine without any translations. And then I was able to simplify my query. Notice that I dropped the AsyncExecute and the Seq.Map. The ResultType.Records is the default so you do not need to supply it like I did. That's it for this quick tip. Let me know what you like and as always. Happy Coding.
|
AuthorWelcome to The Blind Squirrel (because even a blind squirrel occasionally finds a nut). I'm a full-stack web and mobile developer that writes about tips and tricks that I've learned in Swift, C#, Azure, F# and more. Archives
April 2018
Categories
All
|