Friday, December 11, 2009

Is this a bad design?

Suppose we have this class.

public class Class1{
public int Foo(){
Class2 c2 = new Class2();
int x = c2.Bar();
return c2.Baz(x);
}
}


Seems simple enough, right? Now the question: how do you unit test this? Like, really unit test it. Assume that Bar and Baz hit a database or something. You want to write a test to _just_ make sure that that those methods are called. You can't really mock out Class2. Yet this meets even one of the strictest standards of coding, the Law of Demeter. So what's the deal?

Saturday, February 14, 2009

Resources for folds

Reading this post by Matthew Podwysocki, who's a super smart guy, inspired me. I figure, even if I don't manage to come up with interest blog posts on my own, I can at least piggyback on other really smart people, and blog about their blogs.

So, in that spirit, I thought I'd at least make some comments about some great resources for understanding and experimenting with folds. For example, on #haskell on the freenode IRC, there's a bot called lambdabot, which can interpret haskell. One cool thing it can do is give a bit better idea of how an expression would be evaluated, via the SimpleReflect module (which is quite cool, and explained here). Below is a sample session:
09:28:42 <chessguy> > foldl f 1 [1..5] :: Expr
09:28:43 <lambdabot> f (f (f (f (f 1 1) 2) 3) 4) 5
09:28:56 <chessguy> > foldl' f 1 [1..5] :: Expr
09:28:58 <lambdabot> f (f (f (f (f 1 1) 2) 3) 4) 5
09:29:17 <chessguy> > foldr f 1 [1..5] :: Expr
09:29:19 <lambdabot> f 1 (f 2 (f 3 (f 4 (f 5 1))))
Also, speaking of really smart guys, here's a resource from Cale Gibbard. This shows diagrams of how various folds are evaluated.

Here's a link to the Real World Haskell discussion of folds.

And finally, for the only bit of original work in this entry, here's a (very inefficient) logical entailment algorithm, written as a fold, by yours truly:


-- one sentence entails a second sentence if negating the second
-- and inserting its clauses, and the clauses that can be deduced, into
-- the first, results in a contradiction (which we'll represent as an
-- empty list of clauses)
entails :: (Show a,Eq a) => Sentence a -> Sentence a -> Bool
entails s1 s2 = any null $ foldr insert s1 (neg s2)

insert :: (Show a,Eq a) => Clause a -> [Clause a] -> [Clause a]
insert x y | x `elem` y = y
insert x [] = [x] -- inserting a clause into a tautology gives just that clause
insert x y | contradiction x = [[]] -- inserting a clause which is contradictory is also a contradiction
| otherwise = foldr insert (nub$x:y) (filter (not . (`elem` (x:y))) $ concatMap (resolve x) y)

contradiction :: Clause a -> Bool
contradiction = null

-- a list of all the ways the resolution law can be applied:
-- http://en.wikipedia.org/wiki/Resolution_(logic)#Resolution_in_propositional_logic
resolve :: Eq a => Clause a -> Clause a -> [Clause a]
resolve xs ys = [combine x (xs ++ ys) | x <- xs, (neg_term x) `elem` ys]

combine :: Eq a => Term a -> Clause a -> Clause a
combine x = nub . delete x . delete (neg_term x)

Thursday, August 21, 2008

An intro

"Journey of learning"...wow, doesn't that sound sophisticated? The fact is, in the world of technology, it's not what you know, but whether or not you can learn, that determines how far you can go.

I recently spent about 6-weeks on a job hunt (more on this another time, perhaps), and I was amazed at how few recruiters understand this. I got a lot of "how many years of experience do you have in technology X". While that's great to know, I think it's much more telling to ask questions that reveal how much you learned during your experiences. Anybody can spent a year tip-toeing around, trying not to get in the way. The talented will find smart people, question their assumptions, learn how they think, learn how they work, and, overall, improve how they themselves work and think.

That's what this blog will be about - my struggle to learn, improve, challenge myself and others, and hopefully make some useful contributions to the industry along the way. Such a journey is always more fun when you've got someone traveling along, so the purpose of this blog is to invite you to come along with me.