Monday, June 25, 2012

Language Envy

At work, I build software in C#.  At home I play with languages like Ruby and F#.  I still believe C# is an amazing language.  It has seen enormous advances in .NET 3.5, 4, and the upcoming 4.5.  And I suspect alot of the people who claim they don't like it probably haven't used it since 2.0.

But for how wonderful it is, there are still lots of great things about some of the other language paradigms out there, and I definitely have a bit of language envy for some of their features.  I'll list some of these features, in context with why I think they're useful.  And though I'm not a language designer, I'll also mention how I could see C# accomplishing some of this.  Eric Lippert eat your heart out!

Dynamic Envy:
Constructor Stubbing
I'm a big believer in TDD, which requires object mocking.  But mocking in a static language can be annoying because it requires:
  1. Defining an interface for every class that must be mocked
  2. Injecting an instance of the interface into the objects that use them
This is why IoC is so popular.  And while this is annoying (I've written enough about this in the past), it works.  One of the most painful things about this, at least for me, is that you can't call a constructor, which precludes simple code like: var thing = new Thing(otherThing);  Instead, a factory class has to be introduced: IThingFactory.New(otherThing) : IThing.  And you inject an instance of IThingFactory into the class that wanted to call Thing's constructor.  UGH!

But in a dynamic language, none of this is necessary.  Anything can be mocked, and the most paradigm shifting example of this is mocking the constructor of a class so it returns a stub!
MyClass.Stub(:new) {...}
Something like this can be accomplished in .NET through IL re-writing, as seen in the new Fakes (previously Moles) from MS in what they call Shims.  But I haven't used this yet, because when it was Moles, it required the code to be run in an "instrumented" process, which couldn't be accomplished with the NUnit GUI.  I think this is still true in Fakes.  But I hope this Fakes framework keeps getting some attention, because this is just what I've always wanted:  To be able to tell my runtime, "Instead of the class name "MyClass" actually meaning "MyClass", I want it to mean "MyStubClass" for the duration of this test."

Partial "Compilation"
Sometimes when doing TDD or refactoring you'll want to change the public API of a class.  Maybe by changing a method name, or the parameters a method takes, etc.  If you have many calls to that method, this will cause lots of compiler errors in a static language.  And this makes it impossible to TDD out the API change without fixing all the calls first

Dynamic languages don't suffer from this problem because they don't have a compilation step.  Only the files you load at execution time are interpreted, and only the lines that are actually executed will fail due to api signature issues.  This can be a blessing or a curse, but in the example I gave above it's a blessing.

I would love to be able to tell my compiler, "I'm only going to be executing the tests in this one file, so just compile that file and it's dependencies and leave everything else alone, K? Thx!"

Not only would that allow me to update my APIs calls one at a time, running tests along the way, but it might also speed up the code -> compile -> test loop!

Sentinel Values
Gary Bernhardt used this technique in the Sucks/Rocks series in Destroy All Software.  It's a technique for dealing with null, but it's not the same as the Null Object pattern.

As an example, lets say you were implementing a solution to the Word Ladder problem.  What should the "Ladder FindLadder(string startword, string endword)" method return when it doesn't find a ladder?  In C#, it would return null.  The only allowable values for an object of type "Ladder" are a Ladder instance or null.

Since a dynamic language infers types at runtime, the method doesn't have a typed return value, so you can return anything you want.  The Sentinel Value technique takes advantage of this and instead of returning nil, it returns an instance of a NoLadder class.  NoLadder is an empty class with no methods or fields or properties.  How is this different than returning nil?  It's different in the exception you'll get. Instead of "NoMethodError: undefined method `first' for nil:NilClass" you'll get "NoMethodError: undefined method `first' for #<noladder:0x000001010652f0>".

That's awesome!  It says right there that your problem is you're holding a NoLadder.  And NoLadder only comes from one place in your code, so you know exactly and immediately what the problem is.  Contrast that with a null reference exception, which could come from anywhere.

In a static language we can approximate this with the Null Object pattern by creating a Ladder singleton instance called NoLadder.  But this is not the same thing.  The Null Object pattern usually returns an instance which wouldn't cause an exception, but instead would do nothing.  Personally, I've always found this a bit confusing and scary, especially if the object returned would normally have behavior.  The other major difference, is there may be times where the sentinel is very specific to a given function,  and defining a null object on your class for just one little function isn't very cohesive.

In C#, null is not an object like it is in Ruby.  But if it WAS, maybe we could do something like:
public class NoLadder : Null { }
Then we could return "new NoLadder()" in place of null.  Crazy I know, but the ability to put a name on null would be huge!

Metaprogramming
Just look at ActiveRecord and you'll see the amazing power of Metaprogramming in Ruby.  C# has reflection, but it can't even come close to the ability to generate types.  Ruby style metaprogramming can't exist in a static language, so I think what I really want instead is Macros.

Or if not full fledged Macros, then F#'s type providers.  If you haven't seen these yet, you should totally take a look.  They're amazing!  They generate types at compile time.  That may not seem too exciting, until you see the IDE integration...  They generate types AS YOU TYPE!  It's very cool, and you never need to re-generate a generated code file or anything, it's totally seamless.  Like ActiveRecord, but with compile time types!

Functional Envy:
No Nulls
What's the most common exception you encounter in a static language like C# or Java?  NullReferenceException.

F# does have null, but only for interoperating with .NET.  F# code itself doesn't allow null, values must have a value at all times.  This is accomplished with option types, which are the same as .NET's Nullable.  So with enough discipline, you could do this in C#.  But I think it would be awesome if you could turn on a compiler switch in C# to disallow null values.

I should point out that this is a much more strict form of the Sentinel Values mentioned above.  Sentinel Values still blow up when you hit them, they just make it easy to understand why.  No Null prevents the blowup entirely.  Between the two, I think I'd go for No Nulls because it completely eliminates an entire class of programmer error.  However, the cost is some more syntax noise.  Nullables arn't pretty:
var ladder = FindLadder("nice", "mile");
if (ladder.HasValue)
  PrintLadder(ladder.Value);
else
  PrintNoLadder();
Sentinels would be "nicer" and "more elegant" and more "aesthetically pleasing" in cases where the null is a rare degenerate case.

Also worth noting is that while the compiler doesn't exactly have that "no nulls" switch I mentioned, you can approximate this with Code Contracts and static checking.  I haven't tried this yet, but it looks pretty useful and it's on my list.

Immutability
After NullReferenceException, I'd wager the next most common programmer error stems from side effects: "How did the value of this variable change?!"  As I've been studying and practicing functional programming I've been stunned by how ingrained mutable side-effect programming is in my head.  Simply put, I think that way, and thinking any other way is very difficult.

I'm not convinced yet that immutability is better for all problems in all places, but I am convinced that it's a less bug prone way to develop.  So I wish C# had widely used immutable data structures.

Of course, what this really means is you're writing recursion instead of loops.  I find recursion to be more declarative, especially when combined with pattern matching, which I like.  But I also find it requires more thinking to understand, which makes it "harder".

Pattern Matching
I don't think I really need to say much here.  Pattern Matching is just completely and totally awesome.  It requires dramatically less code, is much easier to understand and read, and just generally rules.  However, it does require more advanced language-integrated data structures.

Advanced Integrated Data Structures
Can we get a freaking dictionary syntax?!

Admittedly, F# doesn't have one either, but F# DOES have a beautiful list and tuple syntax, which can be used to easily get you a map:
let d = [1, 'a'; 2, 'b'; 3, 'c'; 4, 'd']
let m = Map.ofSeq d
I desperately wish I had nice syntax for basic data types like this.  This is one of the things I love about powershell too!  And when you have pattern matching that also understands this syntax, that's an amazingly expressive and powerful mix!

So there's a sampling of some of my language envy.  I'm sure there are others I forgot to include, and I bet you have yours too, so leave 'em in the comments, or on your blog, or tweet at me!

Wednesday, June 20, 2012

Don't trust your instincts

Ours is a young discipline with no rules or laws except the ones we choose for ourselves.  We are still living in the wild wild west of software development.  There is no exam to pass to become a software developer.  There are no standard evaluation procedures, or checks and balances.  If you can make your software execute, you can install it, host it, and sell it.  This is one of the things I find very attractive about our industry, but also occasionally frustrating.

There have been many attempts to standardize engineering in the form of processes and methodologies.  But process is only a small -- and very uninteresting -- portion of building software.  Code itself is far more challenging, interesting, and diverse.  But it is very lacking in recognized rules or techniques or principles or even just ideas.  Certainly there are some code principles and practices, but how successful or accepted are they?

It's hard to get a true sense of the opinions and practices of our industry, but there is clearly a very vocal minority that eschews "software engineering" practices in favor of a loosely defined aesthetic.  I'll use "software engineering" as a label for structured principles, patterns, and practices.  For example, consider the Gang of Four's design patterns, or Bob Martin's SOLID principles.  But the vocal minority, which seems to me at least to be getting increasingly vocal these days, would argue these concepts (patterns and principles) are more harmful than helpful.  That a better approach is to simply take the time to feel the pain in your code, and adjust, rewrite, and refactor as needed.

A really solid example of this argument being made can be heard in this Ruby Rogues podcast interview of DHH.  If you stick with it, the conversation covers a lot of really interesting topics including how DHH applies this thinking to rails and basecamp, YAGNI, thoughts on education and the necessity of stubbing your toe to learn, and more (Thanks to Lee Muro for referring me to that podcast).

I agree that stubbing your toe is a good teacher, but I don't think it's the only way to learn.  I agree that abstract concepts are easy to over use and misapply, especially after first learning about them, but I don't think that's inevitable.  While I find the refactoring and continuous learning part of this attitude very pragmatic, there is one element I do disagree with: the idea that we don't need abstract rules and principles and guidance and science.  That all we need is our sense of aesthetic.  The idea that by simply looking at some code, maybe comparing it to a different version, you can derive an intuitive understanding of which code is better.

I don't buy this, because I don't think that's how humans work, as outlined by Malcolm Gladwell's book Blink and this article by Jonah Lehrer.  I recommend them both, but if you're short on time, just read the Jonah Lehrer article as it's short and the most directly relevant.

Blink is all about the influence our subconscious mind has on us.  We like to think that we are rational and in full conscious control of what we do and what we think.  But Blink has plenty of research to prove that this simply is not the case.  We depend on our subconscious to make snap decisions and influence our general mood and thoughts much more than we realize.  And Blink goes to great lengths to present the fact that this can be both very powerful and harmful.  Your mind is capable of "thin slicing" a situation, pulling out many relevant factors from all the thousands of details, and coming to a conclusion based on those details.  But, not surprisingly, you need both extensive practice AND exposure to all the needed factors for this to work.  And it's worth mentioning that even when it does work, your conscious mind may never understand what it was your unconscious did to come to it's conclusion!

You might read that and think, "Experts can use their unconscious to recognize good and bad code, the vocal minority is right!"  I believe that is true, but only on a local level.  When you look at code, you are always drilled in to the lowest level.  I think you could intuit a fair amount at this level, but it's the higher concepts that have the larger influence, and I'm not sure you can effectively thin slice that stuff.  Many of the concepts of good architecture are about higher level structure: low coupling, high cohesion, SRP, ISP, DRY.  But if I showed you one code file and asked you to tell me if the application suffered from coupling issues, you wouldn't be able to say.  And that's because you haven't been provided with enough information.  And without that information, how can you possible thin slice your way to an intuitive understanding of good code?  I worry that a focus on "aesthetic" and "elegance" leans too heavily on this intuitive feel for code, and carries a serious risk of leading you down a path that feels smooth and easy, but ultimately leads straight into the woods.

But I would take this argument even further.  Jonah Lehrer's article tells a story of a psychology experiment that went something like this.  Study participants were shown two videos, both showed two different sized balls, one larger than the other, falling toward the ground.  In one video the balls hit the ground at the same time, and in the other the larger ball hit the ground first.  The participants were asked which video was a more accurate representation of gravity.



And the answer is: the video where they hit the ground at the same time is the correct one.  This is not intuitive, most of us would expect the larger ball to hit first.  So the way the world actually works comes as quite a surprise.  But where this gets interesting is in the second part of the study.  This time, the participants were all physics majors, who had studied this and learned the correct answer.  The participants brains were being monitored with an fMRI machine and what the researchers discovered is that in the non-physics majors a certain part of the brain was lighting up which is associated with detecting errors, the "Oh-shit! circuit" as Jonah calls it.  When they saw the video of the balls hitting the ground at the same time, their brains raised the bull shit flag.  So what was different with the physics majors that allowed them to get the right answer?
But it turned out that something interesting was happening inside their brains that allowed them to hold this belief. When they saw the scientifically correct video, blood flow increased to a part of the brain called the dorsolateral prefrontal cortex, or D.L.P.F.C. The D.L.P.F.C. is located just behind the forehead and is one of the last brain areas to develop in young adults. It plays a crucial role in suppressing so-called unwanted representations, getting rid of those thoughts that aren’t helpful or useful.
This other section of the brain allows us to override our intuitive primal expectations, the Oh-shit! circuit, and replace them with learned ones.  But in order for this circuit to work, you must have studied and learned the material!  Which requires that there be something to learn!

The connection to the aesthetic instinctive approach to software should be pretty clear.  If you shun what "science" our industry has to offer, however admittedly weak and young it may be, you're not training your brain to suppress the intuitive but worse-for-you-in-the-end code!

So I think it's important to be cautious when relying on your intuition and sense of aesthetic, especially in an industry as young as ours with so little widely accepted guidance.  We need to follow that pragmatic approach of continuing to learn, but at the same time we have to continue to question our intuition.  And just as important, we should take the science/engineering of our industry seriously, even while recognizing it's limitations.  


Software is hard, be careful how much you trust your instincts!

Monday, June 11, 2012

Word Ladder in F#

Anthony Coble sent me his solution to this in Haskell before his Haskell talk at Burning River Developers.  The problem was to find a Word Ladder between two words.  A word ladder is a chain of words, from a start word to an end word, in which each word in the chain is one letter different from the word before it and is a real word.  The goal is to find the shortest ladder between the start and end word.  It's a neat problem, made even neater by the fact that it was invented by Lewis Carroll!  So I couldn't resist giving it a try in F#.  And fortunately, I don't know Haskell so I couldn't understand Anthony's solution, so I had to figure it out all on my own.

Speaking of which, this is a fun problem.  So if you want to give a try, you should stop reading here and come back after you've solved it!

I found this problem to be surprisingly difficult.  I kept coming up with ideas but inevitably they were over simplified and wouldn't work.  I was visualizing it as a tree.


It's an interesting problem because it has three different cases to consider.  It's normal for a problem to have two cases, like the first item in the list, and every other item.  But at least with the way I approached it, this problem had three cases: the first node (which has no parent node), the nodes in the first level of the tree (which all have the same parent), and every level after that (where there are many different parents).  This kept causing me to come up with ideas that only worked for the first level, or ideas that worked for one of those levels and not the others...

I knew that I needed a breadth first search but I was really struggling with how to implement it while also keeping track of the path to each node.  Usually a breadth first search effectively just loops over all the nodes in each level, and then calls the next level recursively.  But I need to know what the parent of each node is, and what that parent's parent is, etc up to the root.  My solution to this was to represent each node as a tuple containing the list of it's full path from root to that node, and the word of that node.  This is what I passed through the recursive calls, therefore I always knew the full path to each node.  This was simple, but has the downside of wasting memory since it duplicates a significant portion of the parent list on each node.

Another interesting element of this solution is that I prune words out of the tree that I've already seen, like the two red nodes in the picture above.  This means I don't have to worry about "infinite loops" (they're not really loops, but you get what I mean) in the graph, so I can search until I run out of nodes.  And its safe, because I need to find the shortest ladder, so if I've already encountered a word earlier in the graph, that same word can't be part of the solution later in the graph.

The git repo with my solution is here: https://github.com/kberridge/word-ladder-kata-fs
And here's the code:


Here are some notes on some of the things I found interesting about this code:

  • The array slicing code in the findChildren function was fun.
  • And using the range operator in the generateCandidates ['a'..'z'] was fun too.
  • The findValidUniqueChildren function is an excellant example of something I've been struggling with in F#.  What parameters does this function take?  What does it return?  It's NOT easy to figure this out, is it?  This is also the first time I've used function composition for real!
  • Notice in the queuechildren method how I'm using the concatenate list operator: "let newSearchNodes = searchNodes @ childnodes"?  The Programming F# book says if you find yourself using this it probably means you're doing something in a non-idiomatic way...  I suppose I could have written buildNodes to append the nodes to a provided list, but that seemed awkward.
  • The match of findLadderWorker is pretty typical, but demonstrates another little pattern I keep finding.  For the second match, I created a function to call since it's longer than 1 line, so I had to make up a name.  I went with "testnode" which I don't really like, but I had to name it something!
Here's Anthony Coble's Haskell solution.  His is very different and shows a great example of a different way to approach the problem.


If you solve it, in any language, send me the link to your solution and I'll add it to the post!

Wednesday, June 6, 2012

Book: Object Thinking



Object ThinkingObject Thinking by David West
My rating: 2 of 5 stars

There were two things I really enjoyed about this book.  The first was the discussion of different schools of thought in philosophy and how those ideas appear in software.  The second was the history sidebars that introduced different computer scientists and explained their contributions to the field.

The basic thrust of the book was simply that you should write your applications as a a bunch of objects whose intercommunication results in the emergent behavior of your application.  And further, that your models should attempt to model the real world objects and concepts of your domain.

That's great and all, but the book provides no concrete examples.  None.  And it makes a huge number of assertions about how much better this approach is and how everything else is inferior, but with nothing to back those statements up.  Nothing.

So in the end, I'm left feeling like there are probably some good ideas in there, but I'm totally unconvinced that the author has ever written a real business application.  And further, I think he might be just a grumpy old dude who's sad that Small Talk lost out to more mature and practical languages like C++ and Java.

View all my reviews

The primary things I found interesting and took away from this book are:

Hermeneutics
"According to the hermeneutic position, the meaning of a document—say a Unified Modeling Language (UML) class diagram—has semantic meaning only to those involved in its creation".  The author argues that XP methods are influenced by Hermeneutics and are therefore better suited to software creation than traditional software engineering formal methods.  "One of the most important implications was the denial of “intrinsic truth or meaning” in any artifact—whether it was a computer, a piece of software, or a simple statement in a natural language. This claim is also central to the school of thought that has been labeled postmodern. It is also one of the core claims of all the hermeneutic philosophers."

Traits of Object Culture
  • A commitment to disciplined informality rather than defined formality
  • Advocacy of a local rather than global focus
  • Production of minimum rather than maximum levels of design and process documentation
  • Collaborative rather than imperial management style
  • Commitment to design based on coordination and cooperation rather than control
  • Practitioners of rapid prototyping instead of structured development
  • Valuing the creative over the systematic
  • Driven by internal capabilities instead of conforming to external procedures
Given how little of the rest of the book I was able to buy into, I was surprised by how closely this list of culture traits aligns with my own ideals.

Emergent Behavior
"Traffic management is a purely emergent phenomenon arising from the independent and autonomous actions of a collectivity of simple objects—no controller needed."  This is really the core of what the entire book is arguing for.  That the behavior of the system should emerge from the communications between simple objects.  It's a very interesting concept.  But I'm not 100% sure it's one I'm ready to totally buy into.  He uses a model for an intersection with cars and a traffic light as an example.  The traffic light doesn't know anything about the cars.  It's just a glorified timer that notifies any subscribers by lighting different colored lights.  Cars, in turn, don't know anything about the other cars, or the other streets.  They just monitor the traffic light.  There are two huge benefits I see to this.  First, the loosely coupled nature of the design allows you to introduce new kinds of cars (trucks, motorcycles, even pedestrians!) without changing any of the other participating objects.  And second, it allows arbitrarily complicated intersections to be modeled without requiring any complex code.

But in the back of my head, I'm always a little bit nervous about this...  The fact that the behavior is emergent is a benefit, but also a draw back because there is no one code file you can read that will describe the behavior.  You must figure it out by running simulations in your head of how all the participants interact.  There are certain problems where these clearly would not be acceptable, and Object Thinking does make this point: "Specific modules in business applications are appropriately designed with more formalism than most. One example is the module that calculates the balance of my bank account. A neural network, on the other hand, might be more hermeneutic and object like, in part because precision and accuracy are not expected of that kind of system."  So the bigger question for me, not addressed in the book, is what types of problems would this emergent be acceptable for?  Ultimately I suspect it's a razor's edge issue, at some point the complexity of the solution may make the switch to emergent result in simpler and more understandable code.

Monday, June 4, 2012

Finding Connected Graphs in F#

I've been learning F# and functional programming.  I first got interested in functional languages when Ben Lee introduced me to Erlang at CodeMash by doing the greed kata with me.  Then I bought Programming F# and started to learn the F# language.  As I was going through the book, I was playing with a little Team City/FogBugz integration script in F#.  Then Anthony Coble told me he wanted to do a talk at Burning River Developers on Falling In Love With Haskell.  His talk was great, and Haskell looks like a mind-blowing language.

So that is how I got interested in playing with this stuff.  In order to actually learn it, and not just read about it, I've been finding and inventing little exercise problems and solving them in F#.  F# is a multiparadigm language, but I've been focusing on the pure Functional portions of the language for now.  I thought I'd share these problems and my solutions on the blog.  The best thing that could come from this is if you, dear reader, would also solve these problems in the language of your choice and share back your solution.  Or if you know F# but don't want to actually fully implement a solution to these, I'd love feedback on how you might have solved the problems differently.

The first problem I want to share is a Graph parsing problem:
Given a graph G, return a list of all the connected graphs in G: [G1, G2, ...].
Here's an example input graph and the expected output:
 The git repo with my solutions is here: https://github.com/kberridge/find-connected-graphs-kata-fs

And here's the code:

Some of things I really enjoy about this code:

  • I love nesting simple little functions inside other functions to give names to boilerplate code (ex: isSeen and notSeenOnly)
  • The recursive walk method is stunningly elegant
  • "Map.ofList g" is a cool line of code.  g is a Graph record, but it's defined as a list, and so can be treated like a list.
  • List.collect combines all the returned lists into one list
  • It's also cool that the map variable is in scope inside of the walk function because it's closed over from the findConnectedGraph method.
  • The recursive list comprehension of findAllConnectedGraphsWorker totally blows my mind.  Using yield as expected, but then calling itself with yield! is crazy!
I'm sure there is a lot about this code that could be improved.  There are probably better algorithms too. I'd love to hear your ideas and read your implementations of this problem!