A functional take on console program loop in F#

April 14th, 2009
Comments Off

Often when learning a new technology I start with a simple console application in which the program is run in a loop it continues to prompt you for more input until you give some command like quit or exit or whatever you choose:

Enter input: someInput
someOutput
Enter input: otherInput
someoutPut
Enter input: quit
Thanks! Come again!

The code for this is in an imperative language is usually something like:

   1: while(true)
   2: {
   3:     Console.Write("\nEnter input:");
   4:     var line = Console.ReadLine();
   5:     if(line == "quit") break;
   6:     
   7:     doSomething(line);
   8: }
   9:  
  10: Console.WriteLine("Thanks! Come Again");

 

While reading some F# samples, I saw some code doing essentially the same thing which looked something like:

   1: Console.Write "\nEnter input:"
   2: let mutable input = Console.ReadLine()
   3: while input <> "quit"
   4:     do
   5:     
   6:     if input <> "quit" 
   7:     then
   8:         doSomething input
   9:         Console.Write "\nEnter input:" 
  10:         input <- Console.ReadLine()

 

Now this just feels dirty! In a functional language explicit loop constructs like a while loop feel wrong.  I different way of doing this which is more functional is to create an infinite list of actions.  Where each action represents one iteration of any of the above loops. Then you just execute each action until some condition is met (like seeing the input “quit”).

   1: let action = fun _ ->
   2:     Console.Write "\nEnter input: "
   3:     Console.ReadLine()
   4:  
   5: let readlines = Seq.init_infinite (fun _ -> action())
   6:     
   7: let run item = if item = "quit" 
   8:                 then Some(item) 
   9:                 else
  10:                     parse item 
  11:                     None
  12:  
  13: Seq.first run readlines |> ignore
  14: Console.WriteLine "Thanks! Come Again"

This code makes use of the Seq.init_infinite which create a infinite sequence and Seq.first which enumerates the sequence until the passed in function returns Some.

Author: MattManela Categories: F#, Programming Tags:

Synchronizing Scrollbars using JQuery

March 19th, 2009
Comments Off

I just wrote this simple plugin for JQuery which lets you synchronize the scroll bars of any collection of elements.  This lets you move the scrollbar of one div it have the scrollbars’ of the rest of the divs move the same exact amount.

Here is the code:

   1: jQuery.fn.synchronizeScroll = function() {
   2:  
   3:            var elements = this;
   4:            if (elements.length <= 1) return;
   5:  
   6:            elements.scroll(
   7:            function() {
   8:                var left = $(this).scrollLeft();
   9:                var top = $(this).scrollTop();
  10:                elements.each(
  11:                function() {
  12:                    if ($(this).scrollLeft() != left) $(this).scrollLeft(left);
  13:                    if ($(this).scrollTop() != top) $(this).scrollTop(top);
  14:                }
  15:                );
  16:            });
  17:        }

 

Using this is SUPER simple.  Lets say you have several divs defined as:

<div class=”scrollDiv” style=”overflow:auto;”> .. some large content</div>

To synchronize the scrollbars’ on all divs with the class scrollDiv all you need to write is:

$(“.scrollDiv”).synchronizeScroll();

Author: MattManela Categories: JQuery, JavaScript, Programming Tags:

Prime Factorization using Unfold in Haskell

March 17th, 2009
Comments Off

I randomly yesterday started thinking about the unfoldr function in Haskell while working out at the gym (how nerdy is that, I am lifting iron but thinking of functional programming). Unfoldr take a single and an unfolding function and turns it into a list (the opposite of fold).  At the gym I was thinking about an application where I can use this and I decided that when I got home I would use it to write a prime factorization function.  This is a method that when given a number returns the list of its prime factors.

It was easy to write the only part I am not pleased about is the code I used to deal with tuples.  It seems clumsy and I am still looking for a way to clean that up.

One note: The code below references a list of prime numbers called primes , which is not shown.

Here is the code:

   1: primeFactors x = unfoldr findFactor x
   2:                  where
   3:                    first (a,b,c) = a
   4:                    findFactor 1 = Nothing
   5:                    findFactor b = (\(_,d,p)-> Just (p, d))
   6:                                   $ head $ filter ((==0).first) 
   7:                                   $  map (\p -> (b `mod` p, b `div` p, p))  primes

This function will take any number which is greater than 1 and return a list of its prime factors.  But don’t take my word for it, I wrote a quickcheck property to ensure the prime factors multiply back to the original number:

   1: prop_factors num =  num > 1 ==> num == (foldr1 (*) $ primeFactors num)

When running quickcheck on this property you see the following: 

quickCheck prop_factors
OK, passed 100 tests.

 

Author: MattManela Categories: Haskell, Programming Tags:

My xUnit.net Visual Studio Code Snippets

March 2nd, 2009
Comments Off

The xUnit .Net codeplex page lists one useful Visual Studio code snippet for creating a Fact.  As you can tell I am fairly fond of code snippets so I created a few more which I use when writing xUnit.net facts. These are one line snippets that I find very convenient when writing my assertions.

Below is a table which shows the shortcut you use to access the snippet and the code the snippet generates

Shortcut Snippet
ae Assert.Equal($expected$,$actual$)
ane Assert.NotEqual($expected$,$actual$)
an Assert.Null($actual$)
ann Assert.NotNull($actual$)
at Assert.True($actual$)
af Assert.False($actual$)

I have included a zip containing these snippets.   Enjoy!

Author: MattManela Categories: C#, Snippets, Visual Studio Tags:

Code Assumptions

February 2nd, 2009
Comments Off

My co-workers and I recently came across a piece of code which exposed some assumptions we had about the “correct” behavior of two functions; these assumptions turned out to be false.  The code dealt with determining if the IP of a  request coming into to a website matches a certain range of IP address. The range of IP address was defined in a config file and could look something like this:

156.27.1.2, 156.*.*.*, 127.0.0.*

Where the * acts as a wild card and each comma-separated IP format is matched against the incoming IP address. The code’s intended behavior is that specifying no IP address formats in the config would mean that no IP addresses would match the format.  We noticed that this wasn’t holding true.  We went to examine the code that was performing the matching (which none of us had written and sadly has NO test cases around it).  The code boiled down to something like this:

 

   1: bool DoesIPMatchIPFormat(string incomingIpAddress, string ipFormatsFromConfig)
   2: {
   3:     foreach(var ipFormat in ipFormatsFromConfig.Split(','))
   4:     {
   5:         Regex re = ConvertFormatIntoRegex(ipFormat);
   6:         if(rs.Match(incomingIpAddress).Success) return true;
   7:     }
   8: }

 

Where ipFormatsFromConfig is the ip range of formats shown above separated by “,” or an empty string if no formats are given. On first glance we all were confused by why this didn’t work and then as we looked into it we realized we had made some incorrect assumptions.

First, we assumed that “”.Split(‘,’) would return a zero element array.  This assumption is false. It returns a 1 element array containing the empty string. 

After we learned this we encountered our second assumption.  We assumed that a regular expression whose pattern was an empty string would not match anything. (ConvertFormatIntoRegex returned just that).  This assumption is also false.  After learning the true behavior, it makes sense why it behaves this way.  (A DFA with only one state must accept every input. )

Our assumptions about the “correct” behavior of functions reflect similar mistakes made by all programmers; assuming that you don’t make these kinds of assumptions is a very dangerous way to program and reinforces the importance of unit testing.

Author: MattManela Categories: Programming, testing Tags:

Snippet Designer 1.1 Released

January 5th, 2009
Comments Off

I just released Snippet Designer 1.1.  This is not a major release but just some bug fixes and often requested changes to make the snippet designer more useful.

 

Some of the most notable changes are:

  1. Languages Service are turned OFF by default now.  Since I was unable to figure out a way to host the C# and VB language services in the snippet editor without causing fake errors in projects I decided to give the users an option to turn them on or off.  If you are ok with the fake error you can turn this back on but since it really annoyed me I have it off.  I plan in a future release to provide some basic color coding outside of the language service so you can at least have color coded code.
  2. Many more aspects of the plug in are now configurable through the options menu under Snippet Designer.  you can now set the location of the snippet index, set preferences for which snippet languages you would like to appear in the snippet explorer.
  3. Several bug fixes to how the highlighting of replacements works and performance improvements with it also.

 

Hopefully these changes will make it much more useful so please download it and try it out here

 

 

The future…

My plans for the future are still up in the air but some of the things I would like to add are:

  1. More bug fixes and more feature enhancements suggested by many helpful users on the Snippet Designer Codeplex page.
  2. Ability to color code snippets without using the language service.  I have a few options here I have been looking at.
  3. Create a website to host snippets and allow you to consume and publish from Visual Studio to this website.

I don’t know how much time I will have to commit to any of these but hopefully I will be able to get more work done on this.

 

Thanks!

Inline Regular Expression Options

January 1st, 2009
Comments Off

I was using attributes from the System.ComponentModel.DataAnnotations   namespace for model validation.  This namespace includes a few very useful validation attributes such as

    1. Required Attribute – Validates the field has a value
    2. Range Attribute – Validates the field is within a given range
    3. RegularExpression Attribute – Validates the field matches a given regular expression.

 

The regular expression attribute is very useful since you can describe exactly what format you want a string property to be in.  While using this though I ran into a problem.  The attribute doesn’t let you specify RegexOptions.  This was an issue for me since I wanted to use the regex to validate that the users input was between 5 and 200 characters long , so I had attribute that property as such:

   1: [RegularExpression(@".{5,200}")]
   2: public string Text{get;set;}

 

However this doesn’t work since by default the wildcard . does not match new lines (which I am allowing in the input).  The way to fix this is to specify the RegexOptions.SingleLine option to either the Regex constructor or Match function.  The problem is I have no way of doing that here, and there is no argument on the attribute constructor to specify those options.  I was considering overriding the attribute to create one that allows specifying the attribute but then I stumbled upon this:

Regular Expression Options

You are able to specify the regex option inside of the regular expression text! (which I thought was a huge discovery until my co-worker said he knew this all along but never let me know!). 

So I just changed the expression to look like this:

   1: [RegularExpression(@"(?s).{5,200}")]
   2: public string Text{get; set;}

The (?s) is the inline regex option definition so say I want this in SingleLine mode! And now the validation works the way I wanted!

Author: MattManela Categories: C#, Regular Expression Tags: