tag:blogger.com,1999:blog-45809125335838719322024-03-14T00:26:28.766-04:00Nate HoelleinNate Hoelleinhttp://www.blogger.com/profile/13305321864740593607noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-4580912533583871932.post-47750115856086582792010-03-20T21:39:00.002-04:002010-03-20T22:18:01.547-04:00Book Review: Brownfield Application Development by Kyle Baley and Donald BelchamBrownfield Application development in .Net is a book I wish I had on my bookshelf when I started programming 8 years ago.<br />
<br />
Through a conversational tone, similar to pair programming, the authors expose both the simple and challenging aspects on not only how to work with a legacy code base, but how to start a new project ‘right’ from the beginning.<br />
<br />
The book is cleanly divided into two sections, the first covers the organic processes of software development filled with proven practices and real world scenarios to drive points home. Also discussed are ways to communicate these ideas with your team, sponsors and customers, which is a commonly neglected topic in software development literature.<br />
<br />
The second section shows practical code examples that clearly describe the necessary steps, techniques and designs to meet the ‘abilities’ of clean, maintainable code. Maintainability, Testability, Adaptability, Readability, Extensibility and Reversability. Another highlight is the constant referral of ‘back to the basics’ as described in the first section when some of the more challenging ideas are explained.<br />
<br />
As with most software development books where you read once and maybe crack open again as you navigate backwards from the index, this book is one that will stay on top of your book pile.<br />
<br />
Whether you have been programming for 30 years or a journey man, this book will be an invaluable resource.Nate Hoelleinhttp://www.blogger.com/profile/13305321864740593607noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-21284915747089132582009-06-13T15:56:00.006-04:002010-03-20T22:19:25.112-04:00Oh, those pesky semi-colons!I have a great fascination on the origin of things, whether it is the current set of books I am reading about early American history<sub>1</sub>, or the various nostalgic videos on the beginnings of Microsoft, or even the posts by <a href="http://www.folklore.org/index.py">Andy Hertzfield</a> on the early beginnings of the Mac. C is a language that has that same nostalgic appeal to me as well. It's the pre-pre cursor to C#, the language I actually get paid to write in. In life's continual twists, I am now on a team that has some applications that interface with C and C api's. Most people I mention this to reply, "ugh.. you have to learn C?!?!?" But to me, it's something to learn and since C is the predecessor to C#, it scratches my itch for learning about the origin of things.<br />
On a recent trip to my local public library there is a shelf for free books, and to my amazement, there was a copy of <a href="http://www.amazon.com/Problem-Solving-Program-Design-3rd/dp/0201754908">Problem Solving & Program Design in C</a>. Sarcasm aside, I couldn't understand why it was still there for my taking. In the chapter on arrays, there is a simple program on writing a stack, I added a print function to this program to list all the elements. <br />
<blockquote>
<script src="http://gist.github.com/179718.js">
</script></blockquote>
This code compiles, but when I ran it, I only saw the last element in the array. Hmmm...strange. I fooled around a little adding some extra printlines, check some other code snippets and I can't find what is going on!
<br />
Eventually, after a day or so, what was wrong was I had a semi-colon at the end of my for loop declaration. The C compiler accepted this code as valid code and when my program ran, the for loop looped over itself, never proceeding into my brackets until i <= *size was actually true, then only printed the 3rd element in my array!<br />
To me, there are several thoughts I took away from this little problem. <br />
<ul>
<li>What a great lesson to enforce really <em>reading</em> your code before you execute.</li>
<li>An increased appreciation for the C# compiler to not let me even make that mistake in C#. (The compiler gives you a warning.)</li>
</ul>
I would love to see what comments, if any, others have on the merits of learning C, really learning C, when your primary programming language is C#. Personally, I see merits in knowing/learning this language if not for the only habit to slow down and really read my code.
<br />
<hr />
<sub>1</sub>If your looking to get a nice start on early American History, I suggest the following:
<br />
<ul>
<li>John Adams by David McCullough</li>
<li>1776 by David McCullough</li>
<li>Benjamn Franklin by Walter Isaacson</li>
<li>Founding Brothers by Joseph Ellis</li>
</ul>
These authors have written several additional books, but these are great primers on the subject.Nate Hoelleinhttp://www.blogger.com/profile/13305321864740593607noreply@blogger.com3tag:blogger.com,1999:blog-4580912533583871932.post-62150657637105357922009-04-30T22:02:00.002-04:002010-03-20T22:18:37.375-04:00Haskell - Lists<strong><span style="color: navy;">Haskell - Lists</span></strong>
<br />
Lists in Haskell are defined by square brackets, []. In ghci, declaring a list is as simple as:<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> [1,2,3]<br />[1,2,3]</span></blockquote>
Lists can be of any length, indeed you can type in the following (although I wouldn't recommend it!)<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> [1,2, .. ]<br />[1,2,3,4,5,6,7,8,9,10,11,12....]</span></blockquote>
To create an empty list, type the following:<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> []<br />[]</span></blockquote>
Lists must be all the same type, if we try to declare a list with the following, we will get an error<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> [1,3,5,7,"nine"]<br /><br /><interactive>:1:7:<br /> No instance for (Num [Char])<br /> arising from the literal `7' at <interactive>:1:7<br /> Possible fix: add an instance declaration for (Num [Char])<br /> In the expression: 7<br /> In the expression: [1, 3, 5, 7, ....]<br /> In the definition of `it': it = [1, 3, 5, ....]<br /></span></blockquote>
What the interactive session is telling us here is there is a type incompatibility between <span style="color: green; font-family: Arial; font-size: 10pt;">Num</span> and <span style="color: green; font-family: Arial; font-size: 10pt;">[Char]</span> and suggests some possible fixes.<br />
<strong><span style="color: navy;">Operating on Lists</span></strong><br />
To concatonate two lists you use ++
<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> [1,2,3] ++ [4,5,6]<br />[1,2,3,4,5,6]</span></blockquote>
To add an element to a list use the cons operator :
<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> "Nate" : ["Bill","Ted","Stephen"]<br />["Nate","Bill","Ted","Stephen"]</span></blockquote>
<strong><span style="color: navy;">List Comprehensions</span></strong>
<br />
List comprehensions are really a thing of beauty, although, the Haskell Wiki labels them as <a href="http://haskell.org/haskellwiki/Syntactic_sugar">syntatic sugar</a>. I think they add an element of beauty and simplicity. Comprehensions follow the basic syntax<sub><a href="http://haskell.org/onlinereport/exps.html#sect3.11">1</a></sub>:<br />
<blockquote>
[ e | q<sub>1</sub> .., q<sub>n</sub>], n >=1<br />
where the q<sub>1</sub> qualifiers are:</blockquote>
<blockquote>
<ol>
<li>generators: p <- e, where p is a pattern of type t and e is an expression of type t</li>
<li>guards: an expression that evaluates to a bool</li>
<li>local bindings: provide new definitions for use or subsquent generators or guards</li>
</ol>
</blockquote>
Here's an example of how to generate a list of all even numbers between 1 and 50 using comprehensions:<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> [ x | x <- [1 .. 50],even x]<br />[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50]</span></blockquote>
Granted, you can accomplish the same thing using arithimetic sequences:<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">[2,4 .. 50]</span></blockquote>
<br />
But take a look at how to solve <a href="http://projecteuler.net/index.php?section=problems&id=1">Project Euler question #1</a> with list comprehensions:
<br />
<blockquote>
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> foldr (+) 0 [x | x <- [1 .. 999],x `mod` 3 == 0 || x `mod` 5 == 0]</span></blockquote>
Breaking down this line into parts,
<br />
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> foldr (+) 0 [x | <span style="color: red;">x <- [1 .. 999]</span>,x `mod` 3 == 0 || x `mod` 5 == 0]</span><br />
x <- [1 .. 999] is a generator, it's using an arithimetic sequence to get all the numbers between 1 and 999.<br />
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> foldr (+) 0 [x | <span style="color: green;">x <- [1 .. 999]</span>,<span style="color: red;">x `mod` 3 == 0 || x `mod` 5 == 0</span>]</span><br />
x `mod` 3 == 0 || x `mod` 5 == 0 is a guard or predicate. Only when this expressions is true is it "passed" to the new list.<br />
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> <span style="color: red;">foldr (+) 0 [x</span> | <span style="color: green;">x <- [1 .. 999]</span>,<span style="color: green;">x `mod` 3 == 0 || x `mod` 5 == 0</span>]</span><br />
x is the new list of all the numbers between 1 and 999 that satisfy the predicate. Then, x becomes part of the last expression, the foldr function.<br />
foldr, or reduce, applys the the operator + in this case to the seed value 0 and each element in the list.<br />
<hr />Nate Hoelleinhttp://www.blogger.com/profile/13305321864740593607noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-88971039433027292912009-04-19T21:08:00.002-04:002010-03-20T22:18:54.877-04:00Learning Haskell<span style="color: navy;"><strong>Why am I learning Haskell?</strong></span><br />
There are several different answers, but there are a few that stick out more than others. While I was learning F# and making my way through ProjectEuler problems, I was getting frustrated with running into type issues. Here I was looking at some beautiful, clean and consice code, and then watching it get all cluttered up with F#'s casting syntax.<sub>1</sub><br />
Another reason is when I finally solved a Euler problem and quite proudly submitted my solution, I would browse the other F# solutions and became dissapointed with what some others where submitting. I was looking at F# syntax, but it was all procedural style.<br />
F# is a great language and I really enjoy writing with it, and will continue. However, I wanted to learn functional programming on a language that doesn't allow me to break the rules.<br />
<span style="color: navy;"><strong>Getting Started with Haskell</strong></span><br />
I am using the GHC implementation, which can be downloaded <a href="http://www.haskell.org/">here</a>. With the download you get three components:<br />
<ul>
<li>ghci - an interactive interpreter</li>
<li>ghc - compiler</li>
<li>runghc - runs Haskell programs as scripts</li>
</ul>
My examples will be in ghci, but I'll note when I switch. My development environment is a Mac, so the command window is the bash shell.<br />
After installing Haskell, launch Terminal and type in ghci:<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">$ghci<br />GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help<br />Loading package ghc-prim ... linking ... done.<br />Loading package integer ... linking ... done.<br />Loading package base ... linking ... done.<br />Prelude></span></code><br />
Once the ghci is loaded, we see several libraries being loaded, ghc-prim, integer and base. Details on these packages can be found <a href="http://haskell.org/ghc/">here</a>.
<br />
The <span style="color: green; font-family: Arial; font-size: 10pt;">Prelude></span> prompt means the prelude library is loaded, sort of shorthand for the <a href="http://haskell.org/onlinereport/standard-prelude.html">prelude 98 standard</a>. Like other Unix shells, what you see for the prompt is configurable, but I"ll leave the default.<br />
One of the more import things to remember when you are starting is, <strong><span style="color: green; font-family: Arial;">:?</span></strong> This will list commands available from the prompt. To execute an operating system or shell command, type in <strong><span style="color: green; font-family: Arial;">:!</span></strong> So to see what directory you are, type in<br />
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> :!pwd<br />/Users/nathanhoellein/HaskellProjects</span>
<br />
To change directories, you need the <span style="color: green;"><strong>:cd</strong></span> command.<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> :cd ./ch03//<br />Prelude> :!pwd<br />/Users/nathanhoellein/HaskellProjects/ch03</span></code><br />
Another command that's interesting is<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">:browse</span></code><br />
It lists all names loaded by module.
<br />
<strong><span style="color: navy;">Interactive Haskell</span></strong><br /><br />The ghc interpreter functions just like the F# interactive console, you can type in code snippets and perform arithmetic, except you don't have to end each line with ;;.<br />
You can perform calculations using infix or prefix syntax:<br />
infix:<br />
<span style="color: green;"><span style="font-size: 10pt;"><span style="font-family: Arial;"><code>Prelude> 2 + 3<br />5</code></span></span></span>
<br />
prefix<br />
<span style="color: green;"><span style="font-size: 10pt;"><span style="font-family: Arial;"><code>Prelude> (+) 2 3<br />5</code></span></span></span><br />
Integers can be large, see what happens when you want to know what 2 ^ 100 is:
<br />
<span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> 2 ^ 100<br />1267650600228229401496703205376</span><br />
Whereas in F#, you have to use doubles and you get a little different output:
<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">> 2.0 ** 100.0;;<br /> val it : float = 1.2676506e+30</span></code><br />
What I find pleasing is you can see F#'s roots, the keyword "it".
<br />
The "it" variable sort of holds on to the last expression that was evaluated.<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> 2 ^ 100<br />1267650600228229401496703205376<br />Prelude> it<br />1267650600228229401496703205376</span></code><br />
We see the same in F#:
<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">> 2.0 ** 100.0;;<br />val it : float = 1.2676506e+30<br />> it;;<br />val it : float = 1.2676506e+30</span></code><br />
Other arithmetic stuff within Haskell:
<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> 2 - (-8)<br />10<br />Prelude> 2 + (-8)<br />-6</span></code><br />
And booleans:<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> True || False<br />True<br />Prelude> True && False<br />False</span></code><br />
Like basic algebra, order of operations matter:<br />
<code><span style="color: green; font-family: Arial; font-size: 10pt;">Prelude> (1 + 3) ^ 4<br />256<br />Prelude> 1 + (3 ^ 4)<br />82</span></code><br />
That's a nice start for now, next post I'll cover lists.
<br />
<hr />
<sub>1</sub> - Yeah, I know it's really the .Net runtime<br />
<br />Nate Hoelleinhttp://www.blogger.com/profile/13305321864740593607noreply@blogger.com2tag:blogger.com,1999:blog-4580912533583871932.post-28455945741752943482008-10-25T17:11:00.002-04:002009-09-02T09:48:48.391-04:00Test faster with Tools<p>With the release of <a href="http://www.testdriven.net/">TestDriven.Net</a> version 2.16, you can now run your F# unit tests within Visual Studio. Prior to this version, I would execute my unit tests via <a href="http://nunit.org/">NUnit-Gui</a>, or <a href="http://www.codeplex.com/xunit">xUnit</a>'s command line utility. Both tools are wonderful for handling unit tests, but like most, if not all programmers, I am lazy. I was getting very tired of switching windows. I even wrote my own small testing harness, <a href="http://natehoellein.blogspot.com/2008/04/sample-test-runner.html">here</a> but I still had to fuss around with switching windows. </p>
<p></p>I do realize that all it took was a simple keystroke combination of alt-tab, but waiting for my machine to re-paint the windows and the tools to re-load the new assembly became tiresome. To add to my laziness, in order to run my tests when in C#-ville, I assigned keystokes TestDriven.Net run tests method, I didn't even have to use the mouse!
<a href="http://www.jetbrains.com/resharper/index.html">Resharper</a> is another tool I use when I am programming in C#-ville, although Resharper has not yet made it way in to the F# world, there are still parts of the tool you can use.
Consider the blank F# page, when you start a new project. All you get is:
<p><span style=";font-family:Courier New;font-size:100%;color:blue;" >#light</span></p>Not much here to get you started. So I created a ReSharper Live Template called "fixturef".
<p></p><p><a href="http://4.bp.blogspot.com/__XZYVsX1j7E/SQOPyzD7PTI/AAAAAAAAAA8/-DL5OOq0K1I/s1600-h/fixturef.jpg"><img id="BLOGGER_PHOTO_ID_5261206892561775922" style="width: 320px; height: 70px;" alt="" src="http://4.bp.blogspot.com/__XZYVsX1j7E/SQOPyzD7PTI/AAAAAAAAAA8/-DL5OOq0K1I/s320/fixturef.jpg" border="0" /></a>
</p><p>When I press the tab key, I get the following:
</p><p><a href="http://3.bp.blogspot.com/__XZYVsX1j7E/SQOPUr8TQFI/AAAAAAAAAAs/yalGaJ6ZLK4/s1600-h/fixturecomplete.jpg"><img id="BLOGGER_PHOTO_ID_5261206375254671442" style="width: 320px; height: 160px;" alt="" src="http://3.bp.blogspot.com/__XZYVsX1j7E/SQOPUr8TQFI/AAAAAAAAAAs/yalGaJ6ZLK4/s320/fixturecomplete.jpg" border="0" /></a></p>
Viola! I don't have to type any of the setup structure to get my base Test Fixture!
<p>Wait, there's more!</p>I also created another ReSharper Live Template, called "ftest":
<p><a href="http://3.bp.blogspot.com/__XZYVsX1j7E/SQOQM9UCimI/AAAAAAAAABE/DhWDrfYIOuk/s1600-h/ftest.jpg"><img id="BLOGGER_PHOTO_ID_5261207341990316642" style="width: 320px; height: 209px;" alt="" src="http://3.bp.blogspot.com/__XZYVsX1j7E/SQOQM9UCimI/AAAAAAAAABE/DhWDrfYIOuk/s320/ftest.jpg" border="0" /></a></p>When I press tab:
<p><a href="http://3.bp.blogspot.com/__XZYVsX1j7E/SQORDOl94eI/AAAAAAAAABU/KovApvcWFc4/s1600-h/ftestComplete.jpg"><img id="BLOGGER_PHOTO_ID_5261208274341847522" style="width: 280px; height: 262px;" alt="" src="http://3.bp.blogspot.com/__XZYVsX1j7E/SQORDOl94eI/AAAAAAAAABU/KovApvcWFc4/s320/ftestComplete.jpg" border="0" /></a></p><p></p>Viola! All I have to do at this point is type the rest of my test methods name.
<p><span style="font-size:85%;"><span style="color: rgb(51, 102, 255);">By now, I know you're now asking yourself, "it can't possibly get any lazier", but oh yes, it can!</span></span></p><p>When I actually have to type some code to get a unit test ready to run, I got tired of having to reach the 10 inches for my mouse and perform a series of point-and-click operations. TestDriven.Net provides commands that you can assign keyboard shortcuts to. In Visual Studio, go to the options screen and select Keyboard. In the command name text box, start typing TestDriven. There are a series of commands to invoke TestDriven.Net. I assigned the ctl-alt-shift-T keystroke to the TestDriven.Net.RunTests command.</p><p><a href="http://1.bp.blogspot.com/__XZYVsX1j7E/SQOQsizFWdI/AAAAAAAAABM/jYmwCZ5QJhI/s1600-h/keyboard.jpg"><img id="BLOGGER_PHOTO_ID_5261207884628580818" style="width: 320px; height: 186px;" alt="" src="http://1.bp.blogspot.com/__XZYVsX1j7E/SQOQsizFWdI/AAAAAAAAABM/jYmwCZ5QJhI/s320/keyboard.jpg" border="0" /></a></p>
So now when I have a test to run, I can press ctl-alt-shift-t and invoke TestDriven to run my tests. No more window switching, or mouse-clicking!
<p>You get a nice message in the status bar of Visual Studio, letting you know the status of your test run.</p><p><span><a href="http://4.bp.blogspot.com/__XZYVsX1j7E/SQORjhcsIKI/AAAAAAAAABc/zCZHhuh_Ul8/s1600-h/results.jpg"><img id="BLOGGER_PHOTO_ID_5261208829159022754" style="width: 253px; height: 118px;" alt="" src="http://4.bp.blogspot.com/__XZYVsX1j7E/SQORjhcsIKI/AAAAAAAAABc/zCZHhuh_Ul8/s320/results.jpg" border="0" /></a></span>
</p>Oops, one test failed, all I have to do is use the ctl-tab keys to switch between documents in Visual Studio and I see the results of my tests in the Output window.
<p><span><a href="http://3.bp.blogspot.com/__XZYVsX1j7E/SQORtAMxZ_I/AAAAAAAAABk/mZs5tE1QE8M/s1600-h/output.jpg"><img id="BLOGGER_PHOTO_ID_5261208992032581618" style="width: 320px; height: 182px;" alt="" src="http://3.bp.blogspot.com/__XZYVsX1j7E/SQORtAMxZ_I/AAAAAAAAABk/mZs5tE1QE8M/s320/output.jpg" border="0" /></a></span></p><p>Enjoy my laziness!</p>Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-12563159677123002942008-07-24T22:23:00.000-04:002008-12-26T18:00:33.959-05:00Wow – What a trip. F#, C#, TDD, COBOL and enlightenment<span xmlns=""><p><span style="font-family:Georgia;font-size:12;">Life truly has a fantastic humbling ability. A few months ago I was in the midst of a deep dive, swimming in the goodness of F#. I had all sorts of wonderful ideas on future blog posts. I was treading in a veritable pool of functions, records, pattern matching, currying; all while not getting bogged down in semi-colons and missing curly brackets! I was on top of the world.
</span></p><p><span style="font-family:Georgia;font-size:12;">Then life reminds you what is truly important, my wife and I were blessed with our 3rd child at the end of May. What a wonderful addition to our family.
So after one month of anxiety waiting for the baby to arrive and then another two months of interrupted sleep, burping, changing diapers and worrying about poop, (those of you with kids understand!) my thoughts never strayed too far the pool. So here I go, with a great big cannonball, I splash back into the blog waters.
It was during those few months out of the pool, when my only concentration on coding was in C#-ville from 9 to 5, several statements of a profound nature crept into my head.
I have been long since spoiled on the benefits of Test Driven Development (TDD); write a test, write some code, make the test pass, refactor, run tests - beautiful simplicity.
</span></p><p><span style="font-family:Georgia;font-size:12;">As simple as that is, one of my co-workers would always write extra code; code that was not needed to make the tests pass. He could not bring himself to just write the simple code that made the test pass. I would always ask the question, why did you write that? The test would still pass if that block was not there.
</span></p><p><span style="font-family:Georgia;font-size:12;">His reply was always, "We'll need it soon." Rather than argue, because he would be right, and delete the code he had written, we would go on our way and complete the task at hand. (By the way, when teaching TDD to someone new, deleting code that has no coverage is a great way to enforce the rule that you shouldn't write any code that is not a result of a test!)
</span></p><p><span style="font-family:Georgia;font-size:12;">So one day, our group was having a small discussion while taking a break from coding and talking about past jobs and different languages we knew. This guy mentioned he programmed COBOL for several years prior to migrating to java and C#. While I snickered and mentioned my own experience with COBOL; a mere two semesters in college and a professor that couldn't code, he laughed and said, "you had to be careful about your code, if you had a bug, you could crash the entire system for everyone".
So after my casual chuckling, I repeated his statement and added something to the effect of, "wow, I would have surly pissed of a lot of other developers, my code is always buggy, I rely on tests to find them, not the final run." As soon as I said that, the little light switch in my head clicked and I then realized why our coding styles were so different, why he just couldn't write the simple code and trust the tests.
</span></p><p><span style="font-family:Georgia;font-size:12;">Being faced with the situation of crashing an entire mainframe, COBOL developers, at least this one, had to make sure the code was sound before submitting your code to the queue. Comparatively speaking, if I crash my system, 1 person is down for a little while, but if you take down an entire mainframe region, there's a little more impact. (I am not picking on COBOL developers here, it's just part of the story.)
</span></p><p><span style="font-family:Georgia;font-size:12;">Compare that to TDD, where my mindset is, "hey, if I refactor this chunk of code into a method, these two other block are the same, and could be made a delegate. Let's try that!" Or, things like "I don't like that switch statement, lets make it a dictionary". Compile, Run Tests…. oops, the entire test fixture fails, oh well, ctl-z.
</span></p><p><span style="font-family:Georgia;font-size:12;">This tantalizing story leads me up to these few points:
</span></p><p><span style="font-family:Georgia;font-size:12;">Profound statement #1: TDD is an incredible gift. Having a series of unit tests gives you the confidence and comfort to try really crazy things with your code. It also gives you the ability to enforce some of the higher level design patterns to make your code truly awesome; open closed principle, single responsibility, Liskov substitution principle, to name a few.
</span></p><p><span style="font-family:Georgia;font-size:12;">Profound statement #2: TDD has made me lazy. I let my tests find my bugs.
</span></p><p><span style="font-family:Georgia;font-size:12;">Profound statement #3: TDD has made me confident. I realize that this statement might conflict with statement #2, but mixing of these traits just makes me smile. If my QA tester finds a bug, I can write a test to re-produce the issue and can guarantee that bug will not surface again.
</span></p><p><span style="font-family:Georgia;font-size:12;">Profound statement #4: You need productivity tools like ReSharper and TestDriven .Net. Not to sound like a commercial for ReSharper, but man, that stuff is like crack! When you combine those tool suites, with your IDE, you can do really fun things when pairing like "mouse free Thursday's". Once you learn all the keyboard shortcuts within an IDE, you realize the mouse is a distraction. The speed, fluency and pace you can write, and refactor code triples when you are not fumbling around with that little pointy arrow. You find that your thoughts are focused on your end goal and not scrolling through your code looking for those pesky syntax problems like missing curly bracket or missing semi-colon. And yes, it is a bad habit to rely on the compiler to tell you were that missing semi-colon is!
</span></p><p><span style="font-family:Georgia;font-size:12;">So now here's my disclaimers.
</span></p><ol><li><span style="font-family:Georgia;font-size:12;">I have respect for COBOL programmers, my intent here was to not poke fun at them.
</span></li><li><span style="font-family:Georgia;font-size:12;">I am not pushing ReSharper or TestDriven.Net, those are the tools we use. There are productivity tools out there. ( If <a href=http://diditwith.net>Dustin Campbell</a> reads this, I'll have already heard the groans when I mention ReSharper!)
</span></li><li><span style="font-family:Georgia;font-size:12;">Mouse-Free Thursdays is an awesome experience. While pairing, each developer unplugs their mouse, only for Thursday and only while coding. After a few MFT's, you find you are a much more efficient coder.
</span></li></ol><p><span style="font-family:Georgia;font-size:12;">
</span> </p></span>Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com3tag:blogger.com,1999:blog-4580912533583871932.post-56765667863479866262008-04-22T21:39:00.000-04:002008-12-26T18:00:33.959-05:00F# Pattern MatchingAfter my last post on the sample F# test runner, I realized I missed a post on one of the critical constructs F# has to offer; pattern matching.
Pattern matching does exactly what it sounds like, matches patterns.
<blockquote><pre>let action x =
match x with
| "Red" -> "Stop"
| "Green" -> "Go"
| _ -> "I don't know"</pre></blockquote>
In this example, when I pass the colors Red or Green to the action function, it returns the matching value. If I were to pass blue to the function, I would get back "I don't know". <blockquote>
> action "Red";;
val it : string = "Stop"
> action "Blue";;
val it : string = "I don't know"
</blockquote>
Notice the "_" at the end, it is a wildcard and it makes this pattern match exhaustive. If I didn't include the _, F# would complain I had an incomplete match.
You do have to be careful of where you put your wildcard character. The following function would create a scenario where the "Green" match statement would not be evaluated:
<blockquote><pre>let action x =
match x with
| "Red" -> "Stop"
| _ -> "I don't know"
| "Green" -> "Go"</pre></blockquote>
This control structure should seem very familiar to anyone coming from the C language family. Indeed, the action function could be written as an if..else statement or a switch statement in C#:
<blockquote><pre> public static string Action(string color)
{
if (color == "Red")
{
return "Stop";
}
else if( color == "Green")
{
return "Go";
}
else
{
return "I don't know";
}
}</pre></blockquote>
You can include conditions within your matches, take the following function:
<blockquote><pre>let isEven x =
match x with
| _ when x % 2 = 0 -> true
| _ -> false</pre></blockquote>
With conditions however, you need to have a catch all. If I were to change the above function to read like this:
<blockquote><pre>let isEven x =
match x with
| _ when x % 2 = 0 -> true
| _ when x % 3 = 0 -> false</pre></blockquote>
the complier would complain of an incomplete pattern match.
With pattern matching you can decompose structured values. This example breaks down the tuples for the match.
<blockquote><pre>let isCubeEven x =
match x with
| _ when snd x % 2 = 0 -> (fst x,true)
| _ -> (fst x,false)</pre></blockquote>
This function returns the following in fsi:
<blockquote>
> isCubeEven (3,9);;
val it : int * bool = (3, false)
</blockquote>
The example "isCubeEven" highlights two features of what makes F# exciting. First, notice that I didn't need to explicitly annotate any of my variables with types? The F# complier inferrs that x is a tuple because of the way I use it within my function. And second, the fst and snd functions that let me easily work with tuples to get the first and second values.
Pattern matching becomes really powerful when you combine it with rec, the keyword for recursive functions. Take this function for adding up the numbers in a number:
<blockquote><pre>let rec sumDigits x y =
match x with
| x when x = 0 -> y
| x -> sumDigits (x / 10) (x % 10) + y</pre></blockquote>
This particular function I wrote to solve some of the Project Euler problems. With this function y accumulates the running summed value and x gets chopped up from right to left.
<blockquote>> sumDigits 123456789 0
val it : int = 45</blockquote>
When you combine the rec keyword and pattern matching, the possibilities are infinite. Take the fold_left function from the F# list namespace:
<blockquote><pre>let rec fold_left f s l =
match l with
| [] -> s
| (h::t) -> fold_left f (f s h) t</pre></blockquote>
The fold_left function takes a function f, a seed value s, and a list l. The match uses the list processing keys to get the first element h and remainder of the list t. Then calls itself with the same function, the result of the function applied to the seed value and the first element and the rest of the list.
Pattern matching also works great on records, here's a great <a href=http://www.c-sharpcorner.com/UploadFile/mgold/PatternMatchingFSharp04292008183848PM/PatternMatchingFSharp.aspx>post</a> on that by Mike Gold.
Question and comments are welcome!Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com1tag:blogger.com,1999:blog-4580912533583871932.post-76208875752698834532008-04-11T22:41:00.000-04:002008-12-26T18:00:33.959-05:00Sample F# Test Runner (and C# too...)While I was fooling around with F# and testing my functions, I got really annoyed with switching between applications to run my tests, Visual Studio and NUnit Gui. The source of my fustration is during the day I get to use a fantastic tool <a href="http://testdriven.net/">TestDriven.Net</a> to run my unit tests in C# and Visual Studio. With F#, however, TestDriven.Net does not recognize the different syntax and no tests run.
So I decided to write my own test runner, by taking advantage of .Net's FileSystemWatcher class. (Note, I used the FileSystemWatcher.Changed event.<sup>1</sup> ) The first iteration I wrote in C# so I could have an excuse to use <a href="http://www.codeplex.com/xunit">xUnit</a>. I probably over engineered the C# code, but old habits die hard.
In the C# implementation, there are three files. The program class sets everything up, the HarnessRunner class sets up the filesystem watcher and listens for the file changed event, and finally the ProcessStarter to run the process.
The application is configurable to use the app.config or to pass any necessary commands to the program. ( Hence a little of the bloat.)
<blockquote>
<pre>
using System;
using System.IO;
namespace HarnessRunner
{
public class program
{
[STAThread]
public static void Main(string[] args)
{
Settings settings = Settings.Default;
if (ValidateInputValue(settings.TestRunnerCommand))
{
Console.WriteLine("Enter the fully qualified command to run:\r\n");
settings.TestRunnerCommand = Console.ReadLine();
}
if (ValidateInputValue(settings.TestAssembly))
{
Console.WriteLine("Enter the file to test:\r\n");
settings.TestAssembly = Console.ReadLine();
}
if (ValidateInputValue(settings.TestRunnerSwitches))
{
Console.WriteLine("Enter any swtiches to the test runner:\r\n");
settings.TestRunnerSwitches = Console.ReadLine();
}
Console.WriteLine("Setting up the watcher to run: \r\n{0} {1} {2}", Path.GetFileName(settings.TestRunnerCommand),
Path.GetFileName(settings.TestAssembly),settings.TestRunnerSwitches);
try
{
HarnessRunner runner = new HarnessRunner(new FileSystemWatcher(), new ProcessStarter());
runner.InitializeFileSystemWatcher(settings.TestAssembly);
}
catch (Exception e)
{
Console.WriteLine("There was an exception during the run: {0}{1}{2}", e.Message, Environment.NewLine,
e.StackTrace);
}
Console.ReadLine();
}
private static bool ValidateInputValue(string command)
{
return string.Compare(command, string.Empty) == 0;
}
}
}
using System;
using System.Diagnostics;
using System.IO;
namespace HarnessRunner
{
public interface IStartTestHarnesses
{
string Start();
}
public interface IFileSystemWatcher
{
bool EnableRaisingOfEvents { get; set; }
string Path { get; set; }
NotifyFilters NotifyFilter { get; set; }
event EventHandler<filesystemeventargs> Changed;
}
public class ProcessStarter : IStartTestHarnesses
{
public string Start()
{
Settings settings = Settings.Default;
Process process = new Process();
process.StartInfo.FileName = settings.TestRunnerCommand;
process.StartInfo.Arguments = settings.TestAssembly + " " + settings.TestRunnerSwitches;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
return process.StandardOutput.ReadToEnd();
}
}
}
using System;
using System.IO;
namespace HarnessRunner
{
public class HarnessRunner
{
private FileSystemWatcher fileSystemWatcher;
private IStartTestHarnesses startTestHarnesses;
public HarnessRunner(FileSystemWatcher fileSystemWatcher, IStartTestHarnesses startTestHarnesses)
{
this.fileSystemWatcher = fileSystemWatcher;
this.startTestHarnesses = startTestHarnesses;
fileSystemWatcher.Changed += fileSystemWatcher_Changed;
}
private void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
Console.WriteLine(startTestHarnesses.Start());
}
public void InitializeFileSystemWatcher(string filetowatch)
{
fileSystemWatcher.Path = Path.GetDirectoryName(filetowatch);
fileSystemWatcher.Filter = Path.GetFileName(filetowatch);
fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
fileSystemWatcher.EnableRaisingEvents = true;
}
}
}
</pre>
</blockquote>
So, once I had that working, I decided to write the F# equivalent. There are two functions, one that starts the process and one to setup the filesystemwatcher. Other than that, there are just some config options.
<blockquote>
<pre>
#light
open System
open System.IO
open System.Diagnostics
open System.Configuration
let mutable command = ConfigurationManager.AppSettings.Item("TestRunnerCommand")
let mutable testAssembly = ConfigurationManager.AppSettings.Item("TestAssembly")
let mutable commandSwitches = ConfigurationManager.AppSettings.Item("TestRunnerSwitches")
let startProcess f =
let p = new Process()
p.StartInfo.FileName <- command
p.StartInfo.Arguments <- f ^" "^commandSwitches
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardOutput <- true
let started = p.Start()
printfn "%O" (p.StandardOutput.ReadToEnd())
let SetupFileSystemWatcher f =
let fileSystemWatcher = new FileSystemWatcher()
fileSystemWatcher.Path <- System.Environment.CurrentDirectory
fileSystemWatcher.Filter <- f
fileSystemWatcher.NotifyFilter <- NotifyFilters.LastWrite
fileSystemWatcher.EnableRaisingEvents <- true
fileSystemWatcher.Changed.Add(fun _ -> startProcess f)
if command = "" command = null then
printfn "Enter the fully qualified command to run:\r\n"
command <- Console.ReadLine()
if testAssembly = "" testAssembly = null then
printfn "Enter the file to test:\r\n"
testAssembly <- Console.ReadLine()
if commandSwitches = "" commandSwitches = null then
printfn "Enter any swtiches to the test runner:\r\n"
commandSwitches <- Console.ReadLine()
printfn "Setting up watcher for %A" testAssembly
SetupFileSystemWatcher testAssembly
read_line() </pre>
</blockquote>
So, now that the code is posted, I'm left with some sort of follow up point to wrap this post up. The only problem is, I can't seem to come up with any points! I put together this article to show a program that performs the same function, implemented in two separate languages.
Comments, feedback and discussions are welcome!
<sup>1</sup> For some reason, the FileSystemWatcher.Changed event fires three times when my assembly is compiled.Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-81366340352152211182008-03-19T19:49:00.000-04:002008-12-26T18:00:33.959-05:00Visual Studio 2008 launch in DetriotWow - I just came back from Microsoft's <a href="http://www.microsoft.com/heroeshappenhere/register/default.mspx">Hero's Happen Here</a> event in Detroit to launch Visual Studio 2008, Windows Server 2008 and SQL Server 2008. It was a well organized event, but more important to me was to catch up with everyone I met at this years CodeMash event.
I always leave these events with a tremendous sense of community. Special thanks to <a href="http://keithelder.net/blog/">Keith Elder</a>, who hosted the geek dinner afterwards. (An extra special thanks to Randy Pagels!)
At this event I was able to meet fellow F# blogger <a href="http://diditwith.net/">Dustin Campbell</a> and share a few thoughts on F#. I wish I had more time to talk shop.........
I was also able to meet <a href="http://www.mcwherter.net/blog/">Jeff McWherter</a>, <a href="http://joewirtley.blogspot.com/2008/02/you-got-to-be-kidding.html">Joe Wirtley</a> and spend six quality hours in the car with <a href="http://www.blogger.com/www.coreyhaines.com">Corey Haines</a> and <a href="http://blog.prokrams.com/">Michael Letterle</a>. Well, Corey was only awake for three....
Another reason for the feeling of community was the presence and dedication of Microsoft's regional representatives, <a href="http://www.joshholmes.com/default.aspx">Josh Holmes</a>, <a href="http://brianhprince.blogspot.com/">Brian Prince</a>, Darryl Hogan and <a href="http://www.jeffblankenburg.com/index.html">Jeff Blankenburg</a>.
Hope to see you all again soon!Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-37731869411139827782008-03-08T22:59:00.000-05:002008-12-26T18:00:33.960-05:00Records and Discriminated UnionsLike most other programming languages, it is possible with F# to create your own types when needed. Because F# is a blend of both functional languages and imperative languages, you get support for types from a functional perspecive as well as types when you have to deal with OO programming.
<span style="font-size:130%;color:#3366ff;"><strong>Records </strong></span>
Records are concrete type definitions, if you have an OO background, records will look very similar to classes. To create a record, you need to tell F# the type name, the labels and the label type. Here’s an example, using FSI
<blockquote><pre>> type FamilyMember = {Name: string; relation: string};;
type FamilyMember = {Name: string; relation: string;}</pre></blockquote>There are two different ways to create record. The first way:
<blockquote><pre>> {Name = "Nate";relation = "Father"};;
val it : FamilyMember = {Name = "Nate"; relation = "Father";}</pre></blockquote>Or a more explicit syntax:
<blockquote><pre>> {new FamilyMember with Name = "Kelly" and relation = "Mother"};;
val it : FamilyMember = {Name = "Kelly"; relation = "Mother";}</pre></blockquote>F# makes it easy for you to access the record labels:
<blockquote><pre>> let f = {new FamilyMember with Name = "Nate" and relation = "father"};;
val f : FamilyMember
> f.Name;;
val it : string = "Nate"</pre></blockquote>Records can be cloned, and like everything else with F#, it’s amazingly simple!
<blockquote><pre>> let d1 = {new FamilyMember with Name = "reilly" and relation = "daughter"};;
val d1 : FamilyMember
> let d2 = {d1 with Name = "Cora"};;
val d2 : FamilyMember
> d2;;
val it : FamilyMember = {Name = "Cora";
relation = "daughter";}</pre></blockquote>Records can be results of functions as well. Take the following type, which has a count of files and a count of directories:
<blockquote><pre>type FilesAndDirectorys = {Files: int; Directories: int;}</pre></blockquote>We can use it for a function like so:
<blockquote><pre>let GetFilesAndDirectories loc =
let dirs = Directory.GetDirectories(loc)
let files = Directory.GetFiles(loc)
let results = {new FilesAndDirectorys with Files = files.Length and Directories = dirs.Length}
results</pre>
</blockquote>
Next call the function with the path you want to search
<blockquote>let counts = GetFilesAndDirectories @"C:\"
The identifier counts now contains the following data: <p>val it : FilesAndDirectorys = {Files = 9; Directories = 18;}</p></blockquote><p></p>There is another type, discriminated union types, but I'll save those for another blog entry.Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-65858935446958290242008-02-15T23:11:00.000-05:002008-12-26T18:00:33.960-05:00Basic Type conversions with F#As I work my way through the <a href="http://progjecteuler.net/">ProjectEuler</a> problems they forced me to look into working with the different types in F#. F# is a very strongly typed language, but it has the same basic types as the types in the other .Net languages. Here is a list of the basic types and how to tell the compiler you want to use them:
<blockquote><pre>let int = 42
let string = "This is a string"
let char = 'c'
let bool = true
let bytearray = "This is a byte string"B
let hexint = 0x34
let octalint = 0o42
let binaryinteger = 0b101010
let signedbyte = 68y
let unsignedbyte = 102uy
let smallint = 16s
let smalluint = 16us
let integer = 345l
let usignedint = 345ul
let nativeint = 765n
let unsignednativeint = 765un
let long = 12345678912345L
let unsignedlong = 12345678912345UL
let float32 = 42.8F
let float = 42.8</pre></blockquote>
(Definitions for the types are listed <a href="http://research.microsoft.com/fsharp/manual/quicktour.aspx#QuickTourTypes">here.</a>)
F# also has BigInt and BigNum types, they stand for arbitrary large integer and arbitrary large number respectively. (I don't know how big they are yet.)
<blockquote><pre>let bigInt = 9876543219876I
let bigNum = 123456789987654N</pre></blockquote>
The F# compiler will determine the types you are working with, a feature called Type Inference. To see what types are inferred, compile your fs files using the –i switch to create an FSI (F# Interface file) or use the mouse in Visual Studio.
Most of the F# programming you will do, inference will work. Now, I know some of you might be thinking; “Yeehaw! I don’t have to worry about declaring types! I’m free!!” Well…some of you might have, I did.
If you want force a type and not let inference handle it for you, you have to use the conventions above like so:
<blockquote><pre>> 3423456573476<strong>N</strong>;;
val it : <strong>bignum</strong> = 3423456573476N
> "This will be a string of bytes"<strong>B</strong>;;
val it : <strong>byte []</strong>
= [84uy; 104uy; 105uy; 115uy; 32uy; 119uy; 105uy; 108uy; 108uy; 32uy; 98uy;
101uy; 32uy; 97uy; 32uy; 115uy; 116uy; 114uy; 105uy; 110uy; 103uy; 32uy;
111uy; 102uy; 32uy; 98uy;121uy; 116uy; 101uy; 115uy]
> 0x06D;;
val it : int = 109</pre>
</blockquote>
But what happens if you have to convert between types? Well, F# has conversion methods like so:
<blockquote><pre>> let x = 42;;
val x : int
> let bigx = Int64.of_int x;;
val bigx : int64
> bigx;;
val it : int64 = 42L</pre>
</blockquote>
The first statement let x = 42 and the resulting line val x : int is an example of type inference. The F# compiler infers that 42 is of type Int32. OK, not really too much here to write home about.
The second statement Int64.of_int actually converts x to a type of Int64, as demonstrated by the output “42L”. Again, not too much here to write home about.
There are methods to convert the types between each other. I just didn't write them all.
Type inference is great, but you have to be careful when you try things like this:
<blockquote><pre>> let reallybignum = 123456789456123789;;
let reallybignum = 123456789456123789;;
-------------------^^^^^^^^^^^^^^^^^^^
stdin(4,19): error: error: This number is outside the allowable range for 32-bit signed integers</pre>
</blockquote>
Oops, I tried to stuff a number larger than what a 32 bit number can hold. To fix this, we need to specify a 64 bit integer:
<blockquote><pre>> let reallybignum = 123456789456123789L;;
val reallybignum : int64</pre>
</blockquote>
OK, as exciting as writing about types and type inference are there is another part to this post. I was poking around through the source code and came across the conversion code F# uses.
Here’s the method for converting an int to other data types:
<blockquote><pre>let inline int32 (x: ^a) = (^a : (static member ToInt32: ^a -> int32)(x))
when ^a : string = (System.Int32.Parse(castToStringx,System.Globalization.CultureInfo.InvariantCulture))
when ^a : float = (# "conv.i4" x : int32 #)
when ^a : float32 = (# "conv.i4" x : int32 #)
when ^a : int64 = (# "conv.i4" x : int32 #)
when ^a : int32 = (# "conv.i4" x : int32 #)
when ^a : int16 = (# "conv.i4" x : int32 #)
when ^a : nativeint = (# "conv.i4" x : int32 #)
when ^a : sbyte = (# "conv.i4" x : int32 #)
when ^a : uint64 = (# "conv.i4" x : int32 #)
when ^a : uint32 = (# "conv.i4" x : int32 #)
when ^a : uint16 = (# "conv.i4" x : int32 #)
when ^a : unativeint = (# "conv.i4" x : int32 #)
when ^a : byte = (# "conv.i4" x : int32 #)</pre></blockquote>
Wow, there’s a lot going on here, but overall it should look familiar; it's a function. The <strong>inline</strong> keyword is a pseudo-function marker for code expansion. Which means the compiler will copy the function inline to the call site. The <strong>^a</strong> parameter designates a static head-type, which means the type must be known at compile time. The <strong>: <i>type</i></strong> parameter in this case is a type constraint on the value. The <strong>(# “conv.i4” : int32 #)</strong> is a special syntax for a feature of the F# language, <strong>inline il.</strong>
<span style="font-size:85%;">I know I went through that fast, but at this point a lot of this stuff is specific to the compiler. More detail than I can explain.</span>
<p>You could read this line: <strong>when ^a : int64 = (# "conv.i4" x : int32 #)</strong> as "when ^a is a type of int64 use the il instruction conv.i4 passing in the value (x) to convert and tell the compiler the type is an int32".</p><p>A little about the IL part of the line; (# “conv.i4” x : int32 #). The (# #) block tells the compiler, here comes an IL instruction. The conv.i4 is the il opt code for convert to an int32, x is value to convert and the : int32 completes the IL instruction to enforce the int32 type. </p><p>Even though this example if fairly implicit, I ran and got my copy of <a href="http://www.apress.com/book/view/1590596463">Expert .Net 2.0 IL Assembler</a> book by Serge Linden and found conv is indeed the IL code for convert operations and i4 is the int32 type. Conv takes the value from the stack, converts it and puts it back.
Type conversions are tricky, if you reduce the size of a value, i.e. – int64 -> int32, the most significant bytes are throws away. Likewise if you increase the size of the value int32 -> int64 the value is zero extended.
</p><blockquote><pre>let reallybignum = 123456789456123789L;;
val reallybignum : int64
> let truncated = Int32.of_int64 reallybignum;;
val truncated : int32
> truncated;;
val it : int32 = -1062963315</pre></blockquote>If we look at how F# handles these conversions, we find the code:
<blockquote><pre>when ^a : int64 = (# "conv.ovf.i4" x : int32 #)</pre></blockquote>
The optcode <strong>conv.ovf.i4</strong> is the IL overflow conversion operator. If the conversion truncates, an Overflow exception is thrown.
That’s all for now, comments, questions and corrections are welcome!Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-28951889533689565502008-02-10T09:29:00.000-05:002008-12-26T18:00:33.960-05:00Project EulerWow - If you are looking for a great web site for exercising you skills in F#, or your programming language of choice, then sign up for <a href="http://projecteuler.net/">ProjectEuler</a>.
I've made it through a few of the problems, and they are mind stretchers. I’ve had to try to remember stuff I haven't had to think about for over 15 years!
Another advantage of this site is once you solve the problem, you can see how others have solved them in a variety of languages.Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-19835722239255601462008-01-27T14:16:00.000-05:002008-12-26T18:00:33.961-05:00Walking the F# List namespace - Post #3This will probably be my last series on examining the source behind the List namespace. Only because I was running out of interesting functions that have interesting implementations, or functions that I feel I could adequately explain. And frankly, writing that List.filter actually imlements List.filter from another namespace is not too interesting.
So, I took a look inside list.fs to find some interesting implementations and found a few more functions to walk through.
<strong>List.assoc:</strong> List.assoc is roughly equivalent to a hashtable or dictionary lookup in c#, except the list is a list of tuples. (Also, I’m not sure if there are any index optimizations either.) Throws a not_found() exception if the key is not found. The signature for List.assoc is ‘a -> (‘a * ‘b) list -> ‘b
<blockquote>
<pre>‘a – the key value to find
(‘a * ‘b) list – the source tuple list
‘b – the value for the key.</pre></blockquote>
Here’s an example, using FSI:
<blockquote><pre>> let list = [for x in 1 to 50000 -> (x,x*x)];;
val list : (int * int) list
>let findSquare s = List.assoc s list;;
val findSquare : int -> int
> findSquare 14513;;
val it : int = 210627169</pre></blockquote>
If we look at the source code, List.assoc is implemented as:
<blockquote><pre>let rec assoc x l =
match l with
|[] -> not_found()
|((h,r)::t) -> if x = h then r else assoc x t</pre></blockquote>
The interesting code block with this function is the ((h,r)::t) syntax. The syntax of (h,r) is breaking up the tuple in the first element on the list, with h getting the key and r getting the value. If the key matches the passed in value, then return r. Also, if the list is empty ([]), then raise the not_found() exception. (I didn’t go into any detail about the rec or match, I describe them in further detail in my previous posts.)
The documentation for List.assoc suggests we use List.try_assoc. So, lets try.
<strong>List.try_assoc:</strong> essentially the same as List.assoc, with two main differences. First, try_assoc, will not throw a not_found() exception if the key is not found. Second, try_assoc returns an option type. When using F# code from other .Net languages, the empty option type (None) is equalivant to the null value. To create a value of the option type, you need to use Some or None.
The signature for List.try_assoc is: ‘a -> (‘a * ‘b) list -> ‘b option
<blockquote><pre>‘a – the first tuple element to find
(‘a * ‘b) list – the soure list
‘b option – the returned value</pre></blockquote>
Here’s an example, from FSI.
<blockquote><pre>> let list = [for x in 1 to 50000 -> (x,x*x)];;
val list : (int * int) list
> findSquare 50001;;
val it : int option = None
>findSquare 23;;
val it : int option = Some 529</pre></blockquote>
If we look at the source code, List.try_assoc is implemented as
<blockquote><pre>let rec try_assoc x l =
match l with
|[] -> None
|((h,r)::t) -> if x = h then Some(r) else try_assoc x t</pre></blockquote>
Wow, this looks surprisingly similar to List.assoc, with the exception of the return types of None and Some(r).
<strong>List.assq:</strong> List.assq is almost like List.assoc, except is used the PhysicalEquality operator. PhysicalEquality is defined in as “Reference/physical equality. True if boxed versions of the inputs are reference-equal, OR if both are value types and the implementation of Object.Equals for the type of the first argument returns true on the boxed versions of the inputs.” as defined in: http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.LanguagePrimitives.html
So, generally speaking, List.assq does reference equality on values on the stack, whereas value equality compares values on the heap. I posted a question on an implementation of PhysicalEquality <a href=http://cs.hubfs.net/forums/thread/4699.aspx>here</a> (Kudos to zakaluka!)
Anyway here’s how List.assq is implemented:
<blockquote><pre>let rec assq x l =
match l with
|[] -> not_found()
|((h,r)::t) -> if PhysicalEquality x h then r else assq x t</pre></blockquote>
List.try_assq is exactly the same as List.try_assoc, except the return type is an option type. Here’s the implementation:
<blockquote><pre>let rec try_assq x l =
match l with
|[] -> None
|((h,r)::t) -> if PhysicalEquality x h then Some(r) else try_assq x t</pre> </blockquote>
<strong>List.for_all:</strong> Returns true if all the elements in the list satisfy the given predicate, false if one fails. The list elements are anded together, visualized as p iO && p i1 && .. p iN.
The signature for list.for_all is (‘a -> bool) -> ‘a list -> bool
<blockquote><pre>(‘a -> bool) – A function that evaluates the list element and returns a bool
‘a list -> the list to process
Bool -> return value</pre></blockquote>
Here’s an example:
<blockquote><pre>[<Test>]
member t.For_allExample () =
let list1 = [0 .. +2 .. 20]
let list2 = [1 .. 10]
let evens = List.for_all (fun x -> x % 2 = 0) list1
let notevens = List.for_all (fun x -> x % 2 = 0) list2
Assert.IsTrue(evens)
Assert.IsFalse(notevens)</pre></blockquote>
List.for_all implements
<blockquote><pre>let rec for_all f l1 = Microsoft.FSharp.Primitives.Basics.List.for_all f l1</pre></blockquote>
Hmm, not so much fun to describe.....so on we go.
<strong>List.for_all2:</strong> Returns true if all the elements in two lists satisfy the given predicate, false if one fails. The lists must have the same length.
The signature for list.for_all2 signature is (‘a -> ‘b -> bool) -> ‘a list -> ‘b list -> bool.
<blockquote><pre>(‘a -> ‘b -> bool) – A function that takes an element from the first list and the second list and returns a bool
‘a list – the first list
‘b list – the second list
Bool -> the return value</pre></blockquote>
Here’s an example:
<blockquote><pre>[<Test>]
member t.For_all2Example () =
let list1 = [0 .. +2 .. 20]
let list2 = [20 .. +2 .. 40]
let list3 = [1 .. 10]
let evens = List.for_all2 (fun x y -> x % 2 = 0 && y % 2 = 0 ) list1 list2
let notevens = List.for_all2 (fun x y -> x % 2 = 0 && y % 2 = 0) list2 list3
Assert.IsTrue(evens)
Assert.IsFalse(notevens)</pre></blockquote>
List.for_all2 implements:
<blockquote><pre>let rec for_all2 f l1 l2 =
match l1,l2 with
|[],[] -> true
|(h1::t1),(h2::t2) -> f h1 h2 && for_all2 f t1 t2
|_ -> invalid_arg "for_all2"</pre> </blockquote>
This recursive function is interesting, in particular the line (h1::t1),(h2::t2) -> f h1 h2 && for_all2 f t1 t2. The function aggregates the results of the function and the list elements!Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-47226697770322153842008-01-18T20:24:00.000-05:002008-12-26T18:00:33.961-05:00Dustin Campbell on F#I caught Dustin Campbell's presentation @ Code Mash. It was a great experience for me to just watch someone talk and type F# code for 40 minutes. Dustin has started <a href="http://diditwith.net/default.aspx">blogging</a> about F# also.
Here's his <a href="http://www.hanselman.com/blog/HanselminutesPodcast96StartingSmallWithFWithDustinCampbell.aspx">podcast</a> with Scott Hanselman.Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-74960085400258599762008-01-17T20:48:00.000-05:002008-12-26T18:00:33.962-05:00A few F# basicsI was driving to the <a href="http://www.blogger.com/www.codemash.org">Code Mash</a> conference with a colleague last week and I started talking about F# and how I was really getting into it. He asked generally, "What's the main difference between F# and C#?". After drawing a complete blank and a long pause, I stammered out something like, there's really no one difference between the two languages, and began to ramble some of the differences I could recall.
A few days later I went back and nosed through my copy of <a href="http://www.strangelights.com/">Robert Pickering's</a> book; I refreshed what some of the main differences are. So I thought I'd jot some down.
<span style="font-size:78%;">Disclaimer: I am just beginning to learn this language, everything here is my interpretation and I am sure there are more differences than the few I list.</span>
<span style="font-size:100%;"></span>
<span style="font-size:100%;">Identifiers and expressions - Identifier is the keyword to define a value. Expressions are any chunk of code that returns something.</span>
<blockquote>let myname = "Nate"</blockquote>
<span style="font-size:100%;">In F#, as with other functional languages, all values are immutable. Once a value is assigned to an identifier the value never changes. Of course, like all languages, there are ways to let identifiers be mutable using the keyword mutable. </span>
<span style="font-size:100%;"><blockquote><p><span style="font-size:100%;">let mutable myName = "Nate"</span></p><p><span style="font-size:100%;">myName <- "Etan"</span></p></blockquote></span>
Functions are identifiers- Functions in F# are first class entities and are treated just like identifiers.
<blockquote><pre>let squares x = x * x
let cubes x = squares x * x</pre></blockquote>
In this example, squares is the name of the function and x is the parameter. The function cubes takes it's parameter passes it to the square function. The result of the squares function gets included in the rest of the expression for cubes.
Functions can also be curried. Currying is the process of passing a function with some arguments that returns you a function with a single argument. Consider the following snippet:
<blockquote><pre>let p = 20
let add x y = x + y
let add13 = add 13
let answer = add13 p
answer = 33
</pre></blockquote>
Huh?? Let's take a walk through that. The add function has the signature of int -> int -> int, which reads; this function takes two ints and returns an int. The add13 function has the signature (int -> int) which reads; this function takes a function that returns an int and returns an int. The expression answer calls the add13 function, which calls the add function giving 1 parameter which gets assigned to x then p gets assigned to y on the add function.
Type inference - F# is very strongly typed, but you don't have to explicitly declare the variable types. The F# compiler handles all that for you. Using FSI, you can see what the complier infers
<blockquote><pre>
> let s = "S"
val s : string
> let double = 2.3
val double : float
> let x = 0
val x : int
> let c = 'c'
val c : char
> let whatisthis q = q
val what : 'a -> 'a</pre>
</blockquote>
The 'a means the complier could not infer what the type is so it uses a generic type. (Not to be confused with generics in C#.)
Pattern matching and recursion - These two traits deserve their own respective posts. Pattern matching is conducive to if..elseif..else and switch statements in procedural languages and recursion means a function calls itself.
Anonymous functions - anonymous functions, also called lambdas, that don't get an identifier. These functions are used as arguments to other functions. The keyword fun identifies these.
<blockquote>let divide q = (fun x y -> x / y) q 2</blockquote>
That's all for now, comments and feedback are welcome!Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com0tag:blogger.com,1999:blog-4580912533583871932.post-22158329402357273282008-01-17T19:49:00.000-05:002008-12-26T18:00:33.962-05:00Walking the F# List namespace - Post #1This will be the first part of a many part posting as I learn F#. Still being a research language, it's immense. So I thought, why not just pick a namespace and write a small bit of code to learn all the new functions in the FSharp.Collections.List namespace.
F# comes complete with the source code, which is written in F# and one of the best ways to learn a new language and to find the "best" or "right" ways of writing new code is to spend as much time reading code as you do writing code. (Scott Hanselman has a great <a href="http://www.hanselman.com/blog/ReadingToBeABetterDeveloperTheCoding4FunDevKit.aspx">blog entry</a> on reading code.)
I took a TDD approach to help make my way through, so each code snippet is actually a small NUnit test. To get a project configured for vs2008, take a look <a href="http://natehoellein.blogspot.com/2008/01/sample-setup-for-visual-studio-2008-for.html">here</a>. For some of the simpler syntax, I used F# Interactive (FSI).
Lists, like everything in F#, are immutable, which means once one is created, you cannot change them. Also, lists can only contain members of the same type, you do have the ability to create a list of an obj type. Lists are a built in data structure that is basically a concatenation of the head and tail. The head being the first element and the tail the remainder of the list, as you'll see later on as we get into the source code.
The syntax to create a list is use the :: followed by an empty list []. The :: syntax stands for cons.)
<blockquote>let list = "blue" :: "red" :: "green"</blockquote>Like most programmers, I'm a lazy typer, so this shorthand also works.
<blockquote>let list = ["blue";"red";"green"]</blockquote>To concatenate two lists, use the @ symbol
<blockquote>let list = ["blue";"red";]@["yellow";"green"]</blockquote>
<p>To bring out some of the power of F# you can also create lists using comprehensions:</p><blockquote>
<pre>let numbers = [1 .. 10] = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
let chars = ['a' .. 'f'] = ['a'; 'b'; 'c'; 'd'; 'e'; 'f']
let cubes = [ for x in 1 .. 5 -> x * x * x] = [1; 8; 27; 64; 125]</pre></blockquote>
So, on to the first function!
<strong>List.append:</strong> This function returns a new list from two lists that are passed to the function in the order they are passed. The method signature of append is
<blockquote><p>'a list -> 'a list -> 'a list</p></blockquote>
<p>A little on the signature, List.append first and second arguments are of type 'a list and returns 'a list (remember 'a is how the compiler infers a generic type.) </p>
<blockquote><pre>
let list1 = [2 .. +2 .. 10]
let list2 = [1 .. +2 ..9]
let appended= List.append list1 list2</pre>
</blockquote>
combined = [2;4;6;8;10;1;3;5;7;9;]
Lets take a look at how this function is implemented:
<blockquote>let append l1 l2 = l1 @ l2</blockquote>
<strong>List.exists:</strong> Tests if any element in the list statisy the given predicate. (A predicate is a statement that returns true or false.) The signature of exists is ('a -> bool) -> 'a list -> bool.
<blockquote>('a -> bool) is the function that applies the predicate to item 'a
'a -> list is your list
bool is the return value
</blockquote>
Here's an example:
<blockquote><pre>[<Test>]
member t.Listexists() =
let list1 = ["The";"quick";"brown";"fox";"jumped";"over";"the";"lazy";"dog"]
let answer = List.exists (fun x -> x = "fox") list1
let wrong = List.exists (fun x -> x = "Fox") list1
Assert.IsTrue(answer)
Assert.IsFalse(wrong)</pre></blockquote>
Lists.exists under the covers is:
<blockquote>let rec exists f l1 = Microsoft.FSharp.Primitives.Basics.List.exists f l1</blockquote>
<p>The signature of Microsoft.FSharp.Primitives.Basics.List.exists is the same of the List.exists function</p>
<p>Here we the first use if the rec keyword. Rec stands for recursion, which means this function calls itself. F# recursion is a core concept, it works with lists by getting the head which is the first element and the tail which is the rest of the list, so until tail is empty [], the function will be called with each element in the list.</p><strong>Lists.exists2:</strong> Same as List.exists, but works with two lists. If the lists don't match in length, it throws an Invalid_ArgumentException. Exists2 signature is: ('a -> 'b -> bool) -> 'a list -> 'b list -> bool.
<blockquote><pre>('a -> 'b -> bool) is the function that applies the predicate to item 'a and item 'b
'a -> list is your first list
'b -> list is your second list
bool is the return value</pre>
</blockquote>
Here's an example:
<blockquote><pre>[<Test>]
member t.Listexists2() =
let list1 = ["The";"quick";"brown";"fox";"jumped";"over";"the";"lazy";"dog"]
let list2 = ["Some";"other";"thing";" ";"jumped";"around";"another";"restless";"mammal"]
let list3 = ["Some";"other";"thing";"Jumped";"winking";"around";"another";"tired";"mammal"]
let answer = List.exists2 (fun x y -> x = y) list1 list2
let wrong = List.exists2 (fun x y -> x = y) list1 list3
Assert.IsTrue(answer)
Assert.IsFalse(wrong)
[<Test;expectedexception(type Invalid_argumentException)>]
member t.Listexists2exception() =
let list1 = ["The";"quick";"brown";"fox";"jumped";"over";"the";"lazy";"dog"]
let list2 = ["Some";"other";"thing";"jumped";"around";"another";"restless";"mammal"]
let answer = List.exists2 (fun x y -> x = y) list1 list2
Assert.IsTrue(answer)</pre>
</blockquote>
List.exists2 under the covers:
<blockquote><pre>let rec exists2 f l1 l2 =
match l1,l2 with
| [],[] -> false
| (h1::t1),(h2::t2) -> f h1 h2 exists2 f t1 t2
| _ -> invalid_arg "exists2"</pre></blockquote>
Ahh - the rec keyword again, but this time paired with match. Match is F# pattern matching. The match statement is working with each list, the first condition [],[] says if both lists are empty then return false. The (h1::t1),(h2::t2) -> f ht h2 exists2 f t1 t2 gets the head and tail for each list and applies the function to h1 and h2 then passes the function and the rest of each list back to exists. The _ character basically is a wildcard to catch everything else.
<strong>List.filter:</strong> Returns a new list that only contains the elements that the given predicate returns true. The signature ('a -> bool) -> 'a list -> 'a list.
<blockquote><pre>('a -> bool) = the function that each element is applied to the
predicate
'a list = the list supplied to List.filter
'a list = the new list</pre>
</blockquote>
Here's an example:
<blockquote>
<pre>[<Test>]
member t.Listfilter() =
let list1 = [1 .. 10]
let list2 = List.filter (fun x -> x % 2 = 0) list1
Assert.AreEqual([2 .. +2 .. 10],list2)</pre>
</blockquote>
So what's happening internally?
<blockquote>let filter f x = Microsoft.FSharp.Primitives.Basics.List.filter f x</blockquote>
The signature for Microsoft.FSharp.Primitives.Basics.Lists.filter function is the same for List.filter.
<strong>List.find:</strong> Returns the element in the list where the given predicate returns true. Throws a Not_Found exception if no element is found. The signature is: ('a -> bool) -> 'a list -> 'a.
<blockquote><pre>('a -> bool) the function to evaluate 'a
'a list = the list to work with
'a = the return value</pre>
</blockquote>
<p>Here's an example:
<blockquote><pre>[<Test><test>]
member t.ListFindTest() =
let list = [1 .. 9]
let a = List.find (fun x -> x = 2) list
Assert.AreEqual(a,2)</pre>
</blockquote>
Internally, what is implemented is once again our rec and match expressions!
<blockquote><pre>let rec find f l =
match l with [] -> not_found()
¦ h::t -> if f h then h else find f t</pre>
</blockquote>
The find function takes a function and the list, checks for an empty list if it's empty then throw a not_found() exception, otherwise get the head and tail. Apply the value in h to the function, if it's true, it returns h, otherwise pass the function and the tail back to find. You again see here the power of functional languages core functions of rec, match and list processing. Being able to get the first element in a list with simply stating h::t; what a change from having to enumerate lists with for or foreach loops!
<strong>Lind.find_all:</strong> Returns a new list of all the elements where the given predicate returns true. The signature is ('a -> bool) -> 'a list -> 'a list.
<blockquote><pre>('a -> bool) the function to evaluate 'a
'a list = the list to work with
'a list = the new list with all the elements that met the predicate</pre>
</blockquote>
Here's an example:
<blockquote><pre>[<Test>]
member t.ListFind_All() =
let list = [1;2;3;5;7;11;13;16;17;19;23]
let evens = List.find_all (fun x -> x % 2 = 0) list
Assert.AreEqual([2;16;],evens)</pre></blockquote>
Behind the scenes List.find_all implements:
<blockquote>let find_all f x = Microsoft.FSharp.Primitives.Basics.List.filter f x</blockquote>
Which is the same method that List.filter uses!
<strong>List.partition:</strong> This is an interesting function, it splits a list based on the predicate, the first is contains all elements that return true, the second list is all the elements that return false. The signature is: ('a -> bool) -> 'a list -> 'a list * 'a list.
<blockquote><pre>('a -> bool) the function to evaluate each element
'a list - the source list
'a list * 'a list - the returned list that contains a tuple of the
elements.</pre>
</blockquote>
The 'a list * 'a list signature identifies a tuple, not multiplication. The returned list contains two lists. Here's an example:
<blockquote>
<pre>let list = [1;2;3;5;7;11;13;16;17;19;23]
let newlist = List.partition (fun x -> x % 2) list
newlist = ([2; 16], [1; 3; 5; 7; 11; 13; 17; 19; 23])</pre>
</blockquote>
With F# you can add on the identifiers like such:
<blockquote>
<pre>let list1,list2 = List.partition (fun x -> x % 2 = 0) list
list1 = [2;,16;]
list2 = [1; 3; 5; 7; 11; 13; 17; 19; 23]</pre>
</blockquote>
Wow! The partition function returns a list of tuples, which the let statement is asking for each identifier to get one. By separating the identifiers by commas, it tells the compiler to assign one of the tuple values to each of the identifiers. If I enter the following statement into fsi
<blockquote><pre>let list1, list2,list3 = List.partition (fun x -> x % 2 = 0) list
-------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(8,25): error: FS0001: Type mismatch. Expecting a
'a * 'b * 'c
but given a
'd list * 'd list.
The tuples have different lengths</pre>
</blockquote>
Under the covers List.partiation uses:
<blockquote>let partition p x = Microsoft.FSharp.Primitives.Basics.List.partition p x</blockquote>
Enough for now, comments and feedback are welcome!Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com2tag:blogger.com,1999:blog-4580912533583871932.post-12864700323283888082008-01-15T20:25:00.000-05:002008-12-26T18:00:33.963-05:00Walking the F# List namespace - Post #2Continuing on with my walkthrough of the Microsoft.FSharp.Collections.List namespace, I thought I’d give the folding functions a shot. It took me some to time to understand what the functions were accomplishing, but after a few tests, they became clear.
<strong>List.fold_left:</strong> This applies a function to each element in the list and starts an aggregate argument to apply through the rest of the elements. Additionally, the function is given a seed value. The seed value and the first element are passed to the function, the result and the second element are passed to the function, that result and the third element….you get the point. Fold_left can be described as
<blockquote><pre>f(..f(f((f s i0 ) i1)i2)..) in</pre></blockquote>
The signature for List.fold_left is (‘b -> ‘a -> ‘b) -> ‘a list -> ‘b
<blockquote><pre>(‘b -> ‘a -> ‘b) - the function that takes the seed value (‘b) and the
first element (‘a). The function returns ‘b.
‘a list - the source list
‘b - the result</pre>
</blockquote>
<p>Here’s an example:
<blockquote><pre>[<Test>]
member t.Listfold_left() =
let list = [1 .. 4]
let answer = List.fold_left (fun x y -> x*y) 2 list
Assert.AreEqual(48,answer)</pre>
</blockquote>Behind the scenes, List.fold_left is implemented as:
<blockquote><pre>let rec fold_left f s l =
match l with
¦ [] -> s
¦ (h::t) -> fold_left f (f s h) t</pre></blockquote>
Sweet, fold_left is simply a recursive match! The parameters to fold_left are the function (f), the seed (s) and the list (l). If the list is empty, simply return the seed value, because the seed value applied to nothing is the seed value. The (h::t) statement is a thing of beauty, it gets the first element in the list (h) and the rest of the list (t), then calls itself with the function (f), the result of function applied to the seed value and the first element, (f s h) and the tail.
<strong>List.fold1_left:</strong> This applies a function to each element in the list and starts an aggregate argument to apply through the rest of the elements. It takes the first and second elements applies the function, the result and the third function are then given the function, until the end of the list returning the result.
<blockquote><pre>f(..f(f((f i0 i1) i2)i3)..) in </pre></blockquote>The signature for the function is (‘a -> ‘a -> ‘a) -> ‘a list -> ‘a
<blockquote><pre>(‘a -> ‘a -> ‘a) - the function to apply the first element to the second
element and return the value
‘a list - the source list
‘a - the return value</pre></blockquote>
Here’s an example:
<blockquote><pre>let list = [1 .. 9]
let total = List.fold1_left (fun x y -> x * y) list</pre>
</blockquote>Total = 362880
You can also do a short hand operator with fold1_left, like so:
<blockquote>let total = List.fold1_left (+) list</blockquote>Total = 45
List.fold1_left behind the scenes is implemented like so:
<blockquote><pre>let fold1_left f l =
match l with
¦ [] -> invalid_arg "List.fold1_left"
¦ (h::t) -> fold_left f h t</pre>
</blockquote>
Ahhh simplicity! Note the fold1_left function does not have the rec keyword. Given the function (f) and the list (l), the match statement checks for an empty list, if so, throw an invalid argument exception. Next split the list (h::t) and then call fold_left with the function (f), first element (h) and the rest of the list (t).
<p><strong>List.fold_left2:</strong> This applies a function to each element in two lists and starts an aggregate calculation based on a seed value and each corresponding list element. Then takes the result and applies it to the second element, and so on. Returning the result. The lists must be the same size. List.fold_left2 can be displayed as
</p><blockquote>f(..f(f((f s i0 j0 ) i1 j1)i2 j2)..) in jn</blockquote>
The signature for fold_left2 is (‘c -> ‘a -> ‘b –> ‘c) -> ‘c -> ‘a list -> ‘b list -> ‘c
<blockquote>(‘c -> ‘a -> ‘b –> ‘c) - This is a function that takes arguments of ‘c; the seed value, ‘a; an element from list1 and ‘b; an element from list2 and returns ‘c.
<pre>‘c – The seed value
‘a list – The first List
‘b list – The second list
‘c – The return value</pre></blockquote>
Here’s an example:
<blockquote><pre>let list1 = [1 .. +2 .. 9]
let list2 = [2 .. + 2 .. 10]
let answer = List.fold_left2 (fun c a b -> c + a + b) 10 list1 list2</pre></blockquote>
Answer = 65
Here is how is this function implemented.
<blockquote><pre>let rec fold_left2 f acc l1 l2 =
match l1,l2 with
| [],[] -> acc
| (h1::t1),(h2::t2) -> fold_left2 f (f acc h1 h2) t1 t2
| _ -> invalid_arg "List.fold_left2"</pre></blockquote>
This looks very much like the fold_left function above. Fold_left2 takes the parameters of a function (f), the seed value (acc) and two lists (l1) and (l2). The first condition of the match statement checks if both the lists are empty, if so, it returns the seed value (acc). Next it splits the lists by using the (h::t) function and calls itself, by passing the function (f), the result of the function, the seed value and the heads of both lists, (f acc h1 h2) and both list tails.Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com1tag:blogger.com,1999:blog-4580912533583871932.post-66357621564543167542008-01-15T19:07:00.000-05:002008-12-26T18:00:33.963-05:00Sample setup for Visual Studio 2008 for F# Unit Testing with NUnitHere is an example of how I configured a vs2008 solution for building a small F# application using Test Driven Development (TDD) techniques and NUnit. I thought I’d share.
Here’s the directory structure layout:
C:\Projects\F#Projects\myApp
· contains the sln file
C:\Projects\F#Projects\myApp\myApp
· contains the “production” fs files and fsharp project files
C:\Projects\F#Projects\myApp\myApp_Tests
· contains the test fs files and fsharp project files
C:\Projects\F#Projects\myApp\Output
· has a copy of nunit.framework.dll
I started with a new F# solution and added two projects, myApp and myApp_Tests, both projects have their output paths set to the output directory.
The myApp project I configured to be an exe and the myApp_Tests project I configured it to be a dll. (What the myApp project is compiled to really doesn’t matter, it all depends on your final use.)
There’s a few additional configuration tasks I had to setup before I could start coding. In the myApp project I qualified it with module myApp so my code and tests could be in separate files. In the myApp_Tests project, I updated the DLL references section with these two entries:
-r "C:\Projects\F#Projects\myApp\Output\Nunit.framework.dll"
-r "C:\Projects\F#Projects\myApp\Output\myapp.exe"
If you don’t want to update the dll references properties, you can add the references in your fs file as listed below.
#r @"..\Output\nunit.framework.dll"
#r @"..\Output\myapp.exe"
I also had to set a project dependancy order to build myApp first then myApp_Tests second, via the solution properties menu.
Whew, at last I can new write some code!
(The formatting is a little off due to the encoding.)
Here’s the myApp_Tests.fs file:
<blockquote>
#light
open NUnit.Framework
[<TestFixture>]
type myAppTests = class
new() = {}
[<Test>]
member t.ShouldReturn2() =
Assert.AreEqual(2,myApp.AddTwoNumbers(1,1))
[<test>]
member t.ShouldReturn45() =
Assert.AreEqual(45,myApp.AddTwoNumbers(13,32))
end</blockquote>
Here’s the myApp.fs file:
<blockquote>
#light
module myApp
let AddTwoNumbers a b =
a + b
</blockquote>
Once you build your solution you can open Nunit Gui, find your test assembly and run your tests untill your in the green! (Make sure you enable NUNit’s shadow copy, so you can keep you project and Nunit open at the same time.)
When you add a test, go back to NUnit and re-run, your new test will automatically show up.
Feeback and comments are welcome! Enjoy!Nate Hoelleinhttp://www.blogger.com/profile/00167651568399351008noreply@blogger.com3