tag:blogger.com,1999:blog-75945488814891503262024-03-05T01:37:47.984-05:00zdsbsZachary D. Shaw<br>
Just Another Software DeveloperZachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.comBlogger63125tag:blogger.com,1999:blog-7594548881489150326.post-86456245488579961522013-12-05T16:03:00.002-05:002013-12-05T16:03:59.414-05:00Software Crafty Articles That Inspired MeHere's a set of random things that inspired me over the years. There is some other set of random things that have inspired me that are also things that didn't occur to me at this instant.<br />
<br />
J.B. Rainsberger<br />
<br />
<ul>
<li><a href="http://blog.thecodewhisperer.com/blog/archives">http://blog.thecodewhisperer.com/blog/archives</a></li>
<li><a href="http://blog.thecodewhisperer.com/2010/10/16/integrated-tests-are-a-scam/">http://blog.thecodewhisperer.com/2010/10/16/integrated-tests-are-a-scam/</a></li>
<li><a href="http://www.jbrains.ca/permalink/the-four-elements-of-simple-design">http://www.jbrains.ca/permalink/the-four-elements-of-simple-design</a></li>
</ul>
<br />
<br />
Nat Pryce & Steve Freeman<br />
<br />
<ul>
<li>Growing Object Oriented Software </li>
</ul>
<br />
Uncle Bob<br />
<br />
<ul>
<li>SOLID Principles</li>
<li><a href="http://www.objectmentor.com/resources/publishedArticles.html">http://www.objectmentor.com/resources/publishedArticles.html</a> (look for the craftsmanship article)</li>
</ul>
<br />
Gary Bernhardt<br />
<br />
<ul>
<li><a href="http://blog.extracheese.org/archive.html">http://blog.extracheese.org/archive.html</a></li>
<li>Destroy All Software Screencasts</li>
</ul>
<br />
Michael Feathers<br />
<br />
<ul>
<li><a href="http://michaelfeathers.typepad.com/">http://michaelfeathers.typepad.com/</a></li>
<li><a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2011/01/the-thing-of-software-development.html">http://michaelfeathers.typepad.com/michael_feathers_blog/2011/01/the-thing-of-software-development.html</a></li>
</ul>
<br />
Jay Fields<br />
<br />
<ul>
<li><a href="http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html">http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html</a></li>
<li><a href="http://blog.jayfields.com/2008/01/testing-one-expectation-per-test.html">http://blog.jayfields.com/2008/01/testing-one-expectation-per-test.html</a></li>
</ul>
<br />
<br />
Fowler<br />
<br />
<ul>
<li><a href="http://martinfowler.com/articles/mocksArentStubs.html">http://martinfowler.com/articles/mocksArentStubs.html</a></li>
<li>Lot's of other stuff on his site... but good luck, it's terrible to navigate it</li>
</ul>
<div>
Joel Spolsky</div>
<div>
<ul>
<li>So much good stuff here, especially from around the 2002 era -<a href="http://www.joelonsoftware.com/">http://www.joelonsoftware.com/</a></li>
</ul>
</div>
<br />
<div>
Oh and The Pragmatic Programmer & Domain Driven Design.</div>
Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-26546669005943445262013-10-14T17:32:00.000-04:002013-10-17T00:23:56.846-04:00Trampolining - An exercise in recursion and not blowing your stack!This exercise was developed for the October 2013 <a href="https://groups.google.com/d/forum/boston-software-craftsmanship">Boston Software Craftsmanship Group Meeting</a><br />
<h3>
</h3>
<h3>
Discussion:</h3>
<ol>
<li>Tail call optimization</li>
<li>Tail calls vs tail recursion</li>
<ol>
<li><a href="http://stackoverflow.com/questions/12045299/what-is-difference-between-tail-calls-and-tail-recursion">http://stackoverflow.com/questions/12045299/what-is-difference-between-tail-calls-and-tail-recursion</a></li>
</ol>
<li>Continuation Passing Style & Continuations</li>
<ol>
<li><a href="http://en.wikipedia.org/wiki/Continuation_passing_style">http://en.wikipedia.org/wiki/Continuation_passing_style</a></li>
<li><a href="http://en.wikipedia.org/wiki/Continuation">http://en.wikipedia.org/wiki/Continuation</a></li>
</ol>
<li>Trampoline</li>
<ol>
<li>Trampolining is a technique to implement tail-recursive optimization without consuming stack space (under the hood you're turning your recursive calls into a loop). It's commonly used in lisp compilers that compile down to C. If you implement your own trampoline you'll be able to make trampolined tail calls without blowing your stack.</li>
<li>A trampoline is an outer function which iteratively calls an inner function. The inner function returns a thunk (or a continuation) of another function to call or the result. To turn a tail recursive function into one that can be trampolined all you need to do is return a thunk wrapping your recursive call. It's called a trampoline because it bounces from function to function. Boing, boing, boing, boing, omg I got a result.</li>
</ol>
</ol>
<h3>
THE EXERCISE</h3>
<ul>
<li>Pick a stack based language of your choice (I'd recommend something with functions as first class objects)</li>
<li>Write the following two recursive functions:</li>
<ul>
<li>Factorial</li>
<li>isEven / isOdd a mutually recursive function see: <a href="http://en.wikipedia.org/wiki/Mutual_recursion#Basic_examples">http://en.wikipedia.org/wiki/Mutual_recursion#Basic_examples</a> for details</li>
</ul>
<li>Blow your stack!</li>
<li>Re-write to be tail recursive (you may need an accumulator)</li>
<li>Blow your stack!</li>
<li>Write a trampoline, re-write your recursive functions to operate in that world</li>
<li>No more blowing your stack!</li>
</ul>
<h3>
LEARNINGS</h3>
You should come away from this exercise with a better understanding for a good number of functional programming terminology. Experience thinking about recursion and how to rewrite recursive functions as tail recursive. And maybe after we run the exercise you'll help me update this section!<br />
<br />
<h3>
HANDY LINKS</h3>
<h4>
Blogs:</h4>
<a href="http://volgarev.me/blog/62412678347">http://volgarev.me/blog/62412678347</a><br />
<a href="http://raganwald.com/2013/03/28/trampolines-in-javascript.html">http://raganwald.com/2013/03/28/trampolines-in-javascript.html</a><br />
<a href="http://pramode.net/clojure/2010/05/08/clojure-trampoline/">http://pramode.net/clojure/2010/05/08/clojure-trampoline/</a><br />
<a href="http://jakemccrary.com/blog/2010/12/06/trampolining-through-mutual-recursion/">http://jakemccrary.com/blog/2010/12/06/trampolining-through-mutual-recursion/</a><br />
<a href="http://kix.in/2007/12/30/the-trampoline/">http://kix.in/2007/12/30/the-trampoline/</a><br />
<a href="http://blog.functionalfun.net/2008/04/bouncing-on-your-tail.html">http://blog.functionalfun.net/2008/04/bouncing-on-your-tail.html</a><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>"The one kind of message says, "I want to bounce: please call me again with these parameters"; the other kind says, "I've had enough bouncing: here's the final answer"."<br />
<a href="http://programmers.stackexchange.com/questions/157684/what-limitations-does-the-jvm-impose-on-tail-call-optimization">http://programmers.stackexchange.com/questions/157684/what-limitations-does-the-jvm-impose-on-tail-call-optimization</a><br />
<h4>
Wikipedia:</h4>
<a href="http://en.wikipedia.org/wiki/Tail_call">http://en.wikipedia.org/wiki/Tail_call</a><br />
<a href="https://en.wikipedia.org/wiki/Thunk_(functional_programming)">https://en.wikipedia.org/wiki/Thunk_(functional_programming)</a><br />
<h4>
Academic:</h4>
"No assembly required : compiling Standard ML to C" <a href="http://repository.cmu.edu/cgi/viewcontent.cgi?article=3011&context=compsci">http://repository.cmu.edu/cgi/viewcontent.cgi?article=3011&context=compsci</a><br />
"CONS Should Not CONS Its Arguments, Part II: Cheney on the M.T.A." <a href="http://home.pipeline.com/~hbaker1/CheneyMTA.html">http://home.pipeline.com/~hbaker1/CheneyMTA.html</a><br />
<h3>
</h3>
<h3>
</h3>
<h3>
NOTES</h3>
Depending on your language and chosen implementation, it may be helpful to be able to check if variable is a function. In clojure you can do that easily with fn? In javascript the following code should work:<br />
<pre>function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}</pre>
<br />
If you need a little help see <a href="https://github.com/zdsbs/trampoline-exercise">https://github.com/zdsbs/trampoline-exercise</a> for some sample code.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-72991867789703112662013-09-14T12:52:00.002-04:002013-09-14T12:52:54.233-04:00Reactive Programming Exercise With baconjs<br />
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
Kata & bootstrap code: <a href="https://github.com/zdsbs/reactive-programming-exercise">https://github.com/zdsbs/reactive-programming-exercise</a> </div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
For the September 2013 <a href="https://groups.google.com/d/forum/boston-software-craftsmanship">Boston Software Craftsmanship Group</a> meeting I ran an exercise in Reactive Programming. Reactive programming is a programming paradigm that is all about data streams. It's getting a lot of attention these days, from people using it in iOS development to deep interest in the Scala community and even a coursera course on it <a href="https://www.coursera.org/course/reactive">https://www.coursera.org/course/reactive</a>. </div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
The basic idea of Reactive Programming is stream processing. It allows for declarative programming about streams of events and calculations / transformations that are declared on a stream and triggered with events from that stream. Once you start thinking about it (or at least once I started thinking about it) you realize data streams are everywhere. Streams are so fundamental to programming it surprises me we don't model with them more often. Or maybe it doesn't surprise me, maybe this is yet another point in the history of software engineering that programmers of the 70s & 80s are head-desking that as an industry we're "discovering" a concept. But, better late than never!</div>
<div style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25px; margin-bottom: 15px; margin-top: 15px;">
In 2+ hours we took a room full of 8 programmers, gave them some hands on experience, and a taste of what modeling with streams might be all about. From what folks said after the meeting it was a success. I know it was one for me: Streams man, they're everywhere.</div>
Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-30575952690567617912012-04-26T14:27:00.000-04:002012-04-26T14:29:22.949-04:00Pair Programming Madness<br />
<h2>
Pair programming madness (or musical chairs for programmers)</h2>
<div id="yui_3_2_0_7_1335206920999595" style="color: #454545; font-family: 'times new roman', 'new york', times, serif; font-size: 16px;">
<br />
I've been meaning to write about this game I developed at the Boston Software Craftsmanship Meetings for a long time and apparently the time for writing is now! It's a fun, silly, chaotic way to pair with friends and strangers. Without further ado here's the description:</div>
<div id="yui_3_2_0_7_1335206920999595" style="color: #454545; font-family: 'times new roman', 'new york', times, serif; font-size: 16px;">
Pair programming madness is a collaborative coding game similar to musical chairs.</div>
<div id="yui_3_2_0_7_1335206920999606" style="color: #454545; font-family: 'times new roman', 'new york', times, serif; font-size: 16px;">
<div id="yui_3_2_0_7_1335206920999605">
Rules:</div>
<div id="yui_3_2_0_7_1335206920999605">
<ol>
<li>Select a code kata. At Boston SC we've used: https://github.com/moss/messaging-exercise and found it well suited.</li>
<li>Everyone brings a laptop with their favorite language setup with a testing framework</li>
<li>Present a code kata and everyone pairs up</li>
<li>We’ll work on the kata for 15 minutes, then rotate pairs. One person stays + one person goes</li>
<li>Repeat step 4</li>
</ol>
</div>
<div id="yui_3_2_0_7_1335206920999618">
What's this look like? Well, you'll only work on one code base max 2 times and pair with 3-4 different people. Additionally you'll both be in the position of explaining current (legacy) code to a new pair or coming up to speed with a code base / env you're not familiar with. (Basically controlled chaos, but fun)</div>
<div id="yui_3_2_0_7_1335206920999624">
Important note: Because it’s possible that two people will be working in a language + env that they’re not familiar with, you should make sure to have either an easy to use IDE, that’s kind of point and clicky or a vanilla text editor (no vim / emacs) and an easy way to run the tests.</div>
<div id="yui_3_2_0_7_1335206920999643">
Running 3 iterations will take ~90 minutes.</div>
<div id="yui_3_2_0_7_1335206920999649">
Enjoy!</div>
<div id="yui_3_2_0_7_1335206920999649">
<br /></div>
</div>Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com1tag:blogger.com,1999:blog-7594548881489150326.post-25452609804712644482012-02-23T15:33:00.005-05:002012-02-23T17:42:26.224-05:00Certifications<p>The topic of programming / agile / IT certifications seems to make the rounds every few years. At least in the circles I hang out in we're in a lull, no one's complaining about certifications or coming up with alternative ideas. Which in my opinion makes it a perfect time for an alternative idea. <a href="#tldr">tl;dr</a></p>
<p>As a programmer what might a meaningful certification of your skills look like? Is it something like <a href="http://www.scrumalliance.org/CSD">http://www.scrumalliance.org/CSD</a> becoming a certified scrum developer? Is it a social network of recommendations, Bob says Fred is a great programmer and you trust that Bob is a great programmer so the transitive property of programmer greatness goes into effect? Should we look to other industries like engineering or medicine? These are the kinds of arguments I remember hearing in the past.</p>
<p>Why do we care? Why does the topic keep coming around? The answer, demand. Companies have caused a demand in certifications, and other companies (e.g. scrum alliance) have looked to fill that demand. </p>
<p>The debate about certifications always seems to come down to: How can you certify that someone is a good programmer? That's a flawed question. There will never be some metric that you can say this person is a good programmer because of X,Y,Z (or maybe there will but we're no where close to that as an industry). </p>
<p>There is demand, there are certifications, they're of limited value and possibly misleading. Our job as an industry is to provide good alternatives. Meaningful certifications that have teeth behind them. My solution, domain specific programmer certifications. </p>
<p>Assume I'm a bank I have two very similar resumes in front of me, I only have time to phone screen one of the candidates. The difference one candidate worked their whole career in finance, the other bio informatics. I'm going to call the finance guy.</p>
<p>Different scenario, I'm a bank again, the two resumes in front of me are both pros who've been coding in finance. One of the guys has a the Financial Programming Certification with a focus in trading (it's the most difficult financial certification to get with a 75% failure rate for first time test takers), the other guy doesn't have it. I'm going to call the certified guy. </p>
<a name="tldr">tl;dr</a>
<p>So what is a domain specific certification? It is a difficult to achieve certification focused on verifying knowledge in a domain as it pertains to writing software. One could imagine them in finance, bio-informatics, medicine, healthcare, education, etc. They are business focused, not technology focused. They validate that you know the important domain concepts and the subtleties of those domains. That you understand common client needs. That you know common design pitfalls.</p>
<p>What about CSD? The content looks great, the name is misleading. Because what does it certify? It certifies that you are familiar with the daily practices and language of a scrum team. It's a domain specific certification for being part of a scrum team. Which is useful, but does it really mean that you're a good developer? That you can abstract well?</p>
<p>Certifications are about filling a need for businesses, they're not going to go away. Businesses have made that clear, and we can't ignore them. We have a choice as an industry do we have certifications like CSD or do we certify that programmers know about certain domains and the pitfalls of programming in those domains. We can either shape the certifications towards something useful or allow them to be shaped for us.</p>Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com3tag:blogger.com,1999:blog-7594548881489150326.post-4583992957284507002010-08-19T16:03:00.003-04:002010-08-19T16:04:44.967-04:00Starting an XP Team<p>Driving home on July 4th weekend I had the sudden realization, not only did I desperately want to work as a part of an XP team, I thought it might be possible. If I could get two other devs, they could move into my office, we could get one more computer and we could all practice XP. Do pair programming, become a tight knit team, everything a guy could ask for. The challenge was convincing management and getting the two other people. I had a feeling getting the resources was going to be the most difficult part.
<p>I had a few prerequisites for forming an XP team that was going to make it hard:
<ol>
<li>Everyone needed to be full-time on the team
<li>No remote devs
<li>I wanted particular devs to be on the team
</ol>
<p>
Why these prerequisites?
<ul>
<li>"Everyone needed to be full-time on the team" - To me this was a no brainer. I wanted to build a team, and I couldn't see how to build a cohesive group when you had people popping on and off constantly.
<li>"No remote devs" - I've never been on an XP team or any team for that matter, never mind starting one. Having the additional challenge of working with remote people I felt would have set me up for failure. No point in trying if it's going to fail.
<li>"I wanted particular devs to be on the team" - First off, I like and enjoy working with all my co-workers (Hi all!). There were going to be plenty of issues to work out that come with starting a new team. I felt it was important that we didn't spend too much time arguing about XP practices (TDD, pairing, etc.). There were a few co-workers I had worked closely with and I felt confident we were on the same page. For this first attempt at an XP team I thought it was important to have them be a part of it.
</ul>
<p>
Why were these challenges for my company?
<ul><li>"Everyone needed to be full-time on the team" - Traditionally people work on 2-3 projects at one time, this means getting full-time resources requires some serious shifting of work.
<li>"No remote devs" - Every project leader at my company prefers on-site devs. Giving my project 2 full-time devs means other projects have to rely more on remote devs. I like the other project leaders, I didn't want to make them mad by "stealing" their resources (Nor did management).
<li>"I wanted particular devs to be on the team" - The two developers had some other commitments to projects, so it was going to be difficult to free them from those commitments.
</ul>
<p>
Anyway enough background. Monday morning I was still bubbling with excitement. I talked with our VP of Operations to see if she thought I was crazy or if it might be possible. She seemed to think the idea was interesting, but there was a wrinkle, a big wrinkle. I could get a smattering of part time in house devs or some full-time remote devs, but getting two full-time in house devs on one project was just impossible. The question I asked myself was, "Is there something that can be done to still make this team a reality?" The company didn't have the resources to have three people full-time on one project, but what if the team worked on two projects? Two projects, three people, two computers and one office. Two projects would be more challenging for the team, but it still seemed doable. Our VP also thought it was a possibility.
<p>
I floated the idea a little more, people seemed interested especially our new VP of Technology. He was fully on-board and championed the creation of the team. Everyone thought it was an experiment worth trying, and now I'm a member of a three person XP team. Last Friday we completed our first iteration and I couldn't be having more fun.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com2tag:blogger.com,1999:blog-7594548881489150326.post-26571934836172432652010-05-03T18:58:00.005-04:002010-05-03T19:29:34.838-04:00I hate looping / iterating / eaching<p>I really hate looping. I mean I really hate looping. Why is that you ask? Because most of the time our looping is not looping. You're filtering, you're transforming or you're calculating, you're not looping. Looping is a means to an end. You loop to perform those actions. But syntactically it's quite common in many languages to see something like: for (blah in blahs) do some filtering / transforming / what ever. Why does the statement "for (blah in blahs)" come first? why isn't it blahs.filter(some predicate) or filter(blahs predicate) or blahs.transform(some stuff) or really so many other options. Why isn't the intent of transforming / filtering / calculating brought to the forefront?
<p>
I love clojure's solutions to the issue: filter, map, reduce. You can get rid of 99% of all your looping and describe better what you're trying to do. I've been trying this in java (I know I know it's a mistake)... with <a href="http://code.google.com/p/google-collections/">google collections</a>. I mean great they have filter, transform, this will look great. It really doesn't:
<pre><blockquote>
List<Foo> filtered = new ArrayList<Foo>(
Collections2.filter(foos, new Predicate<Foo>() {
@Override
public boolean apply(Foo foo) {
return foo.isBar() && foo.isBaz();
}
}));
</blockquote></pre>
vs
<pre><blockquote>
List<foo> filtered = new ArrayList<Foo>();
for (Foo foo : foos) {
if (foo.isBar() && foo.isBaz()) {
filtered.add(foo);
}
}
</blockquote></pre>
<p>
Well fine I'm maintaining intent (I guess) by using a filter method and a predicate, but the whole filter mechanism gets completely lost in all the boiler plate java cruft. I love that I can just implement an apply method, highlighting the boolean expression, and the magic is done for me, but I need so much more code to get my work done. Sure I'm removing duplication of looping (which is nice) but at such a legibility cost. Maybe I'll get used to all the crazy syntax, and it will just fade into the background, but for the moment I'm really doubting it.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com4tag:blogger.com,1999:blog-7594548881489150326.post-52835635847307886632010-04-08T10:00:00.003-04:002010-04-08T10:36:33.936-04:00TDD Starting Points + Roman Numerals Kata<p>I worked on the <a href="http://github.com/zdsbs/roman-numerals">roman numerals kata</a> this week with danp, and learned some new things about TDD and approaching a problem. Where you start with TDD and what kind of insights you can draw from a domain before you start really effect your direction. As I'm typing this it seems incredibly obvious, but it was still a good lesson for me to learn.</p>
<p>We started the kata few times and scrapped our code each time as we started realizing our approach wasn't quite what we were looking for. Honestly if I hadn't had a pair, I probably wouldn't have started over so many times, or pushed quite so hard to find a better way to look at the problem.</p>
<p>What did we start with? We started with the tests. Each time we tried the problem, we picked what we thought was the simplest test and then picked what we thought was the next simplest test. What we found was that we were backing ourselves into corners in our implementation because our tests weren't actually very good starting points.</p>
<p>I'm thinking TDD is like a <a href="http://en.wikipedia.org/wiki/Hill_climbing">hill climber</a> where you start really matters. In a way that is the challenge TDD presents you with: What is simplest thing to start with?Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-71213050572397039462010-01-30T16:39:00.008-05:002010-01-30T19:21:42.768-05:00Generating EJB3 classes from a database<p>Generating EJB3 classes from a database is not that hard. Yay! First you need to download and unzip <a href="https://www.hibernate.org/6.html">hibernate tools</a>. You'll want to have the <a href="https://www.hibernate.org/hib_docs/tools/reference/en/html/ant.html">hibernate tools docs</a> at hand. Next you need to grab a bunch of jars. Almost all the jars can be found in /plugins/org.hibernate.eclipse.x.x.x/lib/tools/hibernate-tools.jar . Then download ejb3-persistence.jar. Below are all the jars I collected. Don't worry about overkill, you're not going to include any of these jars in your distribution.
<pre><blockquote>
antlr-2.7.6.jar dom4j-1.6.1.jar hibernate3.jar jtidy-r8-20060801.jar
asm-attrs.jar ehcache-1.2.3.jar jaas.jar log4j-1.2.15.jar
asm.jar ejb3-persistence.jar javassist.jar lucene-core-2.2.0.jar
bsh-2.0b1.jar freemarker.jar jboss-cache.jar oscache-2.1.jar
c3p0-0.9.1.jar hibernate-annotations.jar jboss-common.jar postgresql-8.4-701.jdbc3.jar
cglib-2.1.3.jar hibernate-commons-annotations.jar jboss-jmx.jar proxool-0.8.3.jar
commons-collections-2.1.1.jar hibernate-entitymanager.jar jboss-system.jar swarmcache-1.0rc2.jar
commons-logging-1.0.4.jar hibernate-search.jar jdbc2_0-stdext.jar
concurrent-1.3.2.jar hibernate-tools.jar jgroups-2.2.8.jar
connector.jar hibernate-validator.jar jta.jar
</blockquote></pre>
<p>Now create your build.xml file:
<pre><blockquote>
<?xml version="1.0" encoding="UTF-8"?>
<project name="my-proj" default="gen_hibernate" basedir=".">
<property name="src" location="src" />
<property name="build" location="build" />
<property name="generated" location="generated" />
<path id="toolslib">
<fileset dir="${basedir}">
<include name="lib/*.jar"/>
</fileset>
</path>
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="toolslib" />
<target name="gen_hibernate">
<hibernatetool>
<jdbcconfiguration
packagename="com.my.proj"
configurationfile="hibernate.cfg.xml"
detectManytoMany="true"
detectOptimisticLock="true">
</jdbcconfiguration>
<hbm2hbmxml destdir="${generated}" />
</hibernatetool>
</target>
<target name="gen_java" depends="gen_hibernate">
<hibernatetool destdir="${src}">
<annotationconfiguration configurationfile="hibernate.cfg.xml">
<fileset dir="${generated}">
<include name="**/*.hbm.xml"/>
</fileset>
</annotationconfiguration>
<hbm2java jdk5="true" ejb3="true"/>
</hibernatetool>
</target>
<target name="compile" depends="gen_java">
<mkdir dir="${build}/classes" />
<javac srcdir="${src}" destdir="${build}/classes" classpathref="toolslib" />
</target>
<target name="jar" depends="compile">
<jar destfile="my-proj.jar" basedir="${build}/classes" />
</target>
<target name="clean">
<delete dir="${build}" />
<delete dir="${src}" />
<delete dir="${generated}" />
</target>
</project></blockquote></pre>
<p>If you're using postgres your hibernate.cfg.xml file should look like:
<pre><blockquote>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="myproj">
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://your-url</property>
<property name="hibernate.connection.username">your-username</property>
<property name="hibernate.connection.password">your-password</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
</session-factory>
</hibernate-configuration>
</pre></blockquote>
</blockquote></pre>
<p>run ant jar and you should be good to go!
<p>Depending on how you're setup you should also consider running <hbm2cfgxml ejb3="true"> it creates a nice hibernate.cfg.xml file with all the classes and your DB connection info.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com1tag:blogger.com,1999:blog-7594548881489150326.post-66410822188757899162010-01-19T22:45:00.003-05:002010-01-19T23:31:35.908-05:00Dependency Injection Frameworks - A Rant<p>Uncle Bob has a great post on <a href="http://blog.objectmentor.com/articles/2010/01/17/dependency-injection-inversion">dependency injection frameworks</a>. I'm so glad he wrote that article. There is precious little out there (maybe this is the only article) about why the DI frameworks suck and why DI is great. To be clear DI by hand works very well. And if all you need to do is DI, rolling it by hand is just as good as using a framework. In fact it wasn't until recently that I even saw a point to DI frameworks at all.
<p>The only argument about DI frameworks that ever made much sense to me was that DI frameworks are great if you want to run your application with different configurations. But when do you want different configurations? Seriously when? For me, the only time I've wanted different configurations is for testing. Not unit or automated testing, but testing in the sense of I want to run the app and I don't want to hit prod.
<p>But why do you need a framework to do that? Maybe you have a different main method. Or maybe you have a properties file. But if all you need are different configurations, a DI framework is an expensive price to pay.
<p>What are the costs? Besides needing to learn a new framework, the DI frameworks are like a cancer. Once you start using them they invade and don't stop invading. You start @Autowiring and @Inject-ing and soon your whole app is cluttered with that crap. Not to mention the XML configs or Guice modules floating around. Maybe I'm doing it wrong, but why do I even want to invest the time to learn how to do it right? The benefits of using the frameworks seem so slim it's doesn't seem worth my time.
<p>However, I did get convinced recently that using Spring DI was the correct choice for a web app I'm working on. Why? Because when Spring manages your objects it does some magic with transactions and sessions and it's all pretty convenient. I still hate it! And it feels wrong. And I believe you can get the magic without the DI. It's a question of how much do you want to fight against your framework. For my current project the answer was clear, not that much.
<p>The only value I get out of using Spring's DI is the magic it does in the background. Their DI is total crap. If you don't need the magic, it's hard to understand why you need the framework.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-71216090222583893632009-10-28T17:54:00.008-04:002009-10-29T11:09:00.428-04:00Abstract Class Smell<p>PLEASE SEE THE UPDATES BELOW, I didn't realize that my issue was with the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>.
<br>------------------------------------------------------------------------
<br>Original Post:
<p>I coded up a smell today, I had an abstract class who's public methods were calling the abstract implementations. Here's kind of what it looked like:
<blockquote><pre>
public abstract class Foo {
abstract SomeObj foo();
abstract SomeObj bar();
public void somethingFooDoes() {
SomeObj a = foo();
SomeObj b = bar();
//do some stuff with a + b
}
}
</pre></blockquote>
<p>How did I get here you might ask. Well, there were going to be two implementations of Foo, a prod implementation and a sandbox implementation. I started off with Foo as an interface and began coding up the Prod + Sandbox impls. It turned out that the prod and sandbox implementations had really similar structures. So, I made Foo an abstract class and moved the common stuff in there. A few more refactorings and Foo ended up looking like it does above. It then dawned on me, Foo was really using different strategies to get at the SomeObjs, I refactored to the strategy pattern:
<blockquote><pre>
public class Foo {
private final SomeObjProducer someObjProducer;
public Foo(SomeObjProducer someObjProducer) {
this.someObjProducer = someObjProducer;
}
public void somethingFooDoes() {
SomeObj a = someObjProducer.foo();
SomeObj b = someObjProducer.bar();
//do some stuff with a + b
}
}
</pre></blockquote>
<p>Now Foo has become concrete and is configurable with the different strategies for producing SomeObjs. To me this code is much more flexible and it now has collaborators. Where in the Abstract implementation it was kind of collaborating with itself (yuck!)<p>What's the moral of the story? If you have an abstract class and you find yourself calling abstract methods in your concrete methods (whoa that's a mouthful) consider refactoring to the strategy pattern.
<p>UPDATE: a co-worker correctly pointed out that the first code snippet of Foo was the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>. Maybe it's too broad a statement, but it seems that anytime you have a template method pattern you could refactor it into the strategy pattern. Taking your inheritance based code and refactoring it into composition based code. Context is king, but these days I certainly favor composition over inheritance.
<p>UPDATE AGAIN: I received some good complaints regarding my code sample.
<p>Imagine using the more standard Game example from wikipedia (but simplified for brevity)
<blockquote><pre>
public abstract class Game {
public void playOneGame() {
while(!endOfGame()) {
makePlay();
}
}
public abstract boolean endOfGame();
public abstract void makePlay();
}
</pre></blockquote>
This could be refactored to use composition instead of inheritance, where Game is now an interface.
<blockquote><pre>
public class GamePlayer {
private Game game;
public GamePlayer(Game game) {
this.game = game;
}
public void playOneGame() {
while(!game.endOfGame()) {
game.makePlay();
}
}
}
</pre></blockquote>Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com1tag:blogger.com,1999:blog-7594548881489150326.post-4920536894817092222009-10-13T22:52:00.007-04:002009-10-14T11:18:44.378-04:00Hollywood DilemmaAt <a href="http://sdtconf.com">sdtconf</a> over the weekend I led an open spaces discussion about the Hollywood Principle and testing. <a href="http://www.agiledeveloper.com">Venkat Subramaniam</a> took the time to post a really thoughtful <a href="http://www.agiledeveloper.com/blog/CommentView.aspx?guid=8b6d0c24-1b69-4df2-9ddd-de86c3556688">article about it</a>. I'll quote it below, but it is worth reading!
<p>
The discussion was around the cost and reason for inverting control, Venkat provided a toy problem which we twisted for our own purposes, we modeled a paper boy. The paper boy requests payment from a customer and the customer can either pay or stiff the paper boy.
<p>
I argued for the following:
<p>
<blockquote><pre>
public class PaperBoy {
public void collectPayments(List customers) {
for(Customer customer : customers) {
customer.getPayment(this, 200);
}
}
//...
</blockquote></pre>
And the test
<blockquote><pre>
Customer customer = mock(Customer.class);
PaperBoy paperBoy = new PaperBoy();
//set up a payment to be collected;
paperBoy.collectPayments(customer);
verify(customer).getPayment(paperBoy,$$$);
</blockquote></pre>
and the Customer
<blockquote><pre>
public class Customer {
public void getPayment(PaperBoy paperBoy, int amount) {
if (hasNoMoney || doesNotCareToPay)
paperBoy.stiff(this);
else {
deductMoney(amount);
paperBoy.acceptPayment(this, amount);
}
}
//...
</blockquote></pre>
and the Test
<blockquote><pre>
Customer customer = new Customer(someMoney and a bad attitude);
PaperBoy paperBoy = mock(PaperBoy.class);
customer.getPayment(paperBoy,$$$);
verify(paperBoy).stiff(customer);
</blockquote></pre>
etc. for the other cases.
Venkat points out some issues with this kind of implementation that I'd like to address:
<blockquote>
Problem 1. The above code has some unnecessary coupling and bi-directional relationship. The Customer depends
on PaperBoy. That is a coupling that I would seriously question.
<p>
Problem 2. The unit test is now made to do more. It has to create a mock of the PaperBoy. Even if you tell me it is not
much code, a single line of code that is not absolutely needed is a lot of code IMHO. You don't have to maintain code
that you do not write.
<p>
Problem 3. Are you really stiffing the PaperBoy? Who decides that? Can a paperboy decide that under very hard economic
conditions, a loyal customer may be deserves a break? I have no problem the customer deciding to pay or not, but if that is
stiffing or not is for the paperboy to decide IMO.
</blockquote>
<p>
I'd like to address problem 3 first. The paper boy can still cut the guy a break, he just does it in his stiff method. Or maybe it shouldn't be a stiff method, maybe it should be an iWontPayMethod().
<p>
Problem 1. I really don't like the coupling! The coupling would be limited if the Customer was talking to a debt collector interface, and the PaperBoy was talking to a Payee(uhg) interface. But it's still a little smelly. I don't fundamentally see a problem with the bi-directional relationship, but maybe that's just because I haven't coded too much with bi-directional relationships (and maybe there's a good reason for that).
<p>
Problem 2. Let's take a look at Venkat's code + what some tests would look like.
<blockquote><pre>
public class PaperBoy {
public void collectPayments(List customers) {
for(Customer customer : customers) {
int payment = customer.getPayment(200);
if (payment > 0)
acceptPayment(customer, payment);
else
stiff(customer);
}
}
//...
public class Customer
{
public int getPayment(int amount) {
if (hasNoMoney || doesNotCareToPay)
return 0;
else {
deductMoney(amount);
return amount;
}
}
//...
</blockquote></pre>
The Customer Tests:
<blockquote><pre>
Customer customer = new Customer(someMoney and a bad attitude);
assertEquals(0,customer.getPayment($$$);
</blockquote></pre>
So Venkat is correct in this example the mocks add 2 extra lines per test which isn't great. But that's not the whole story. Let's take a look at the PaperBoy tests.
<blockquote><pre>
Customer customer = new Customer(someMoney and a bad attitude);
PaperBoy paperBoy = new PaperBoy();
//set up a payment to be collected, let's assume this is one line
paperBoy.collectPayments(customer);
assertTrue(paperBoy.wasStiffedBy(customer);
Customer customer = new Customer(someMoney and a good attitude);
PaperBoy paperBoy = new PaperBoy();
//set up a payment to be collected, let's assume this is one line
paperBoy.collectPayments(customer);
assertTrue(paperBoy.collectedPaymentFrom(customer, $$$);
</blockquote></pre>
I have two issues with the PaperBoy tests:
<ol>
<li>There is an extra test needed, which in terms of maintence is not such a good thing.
<li>The PaperBoy tests are highly coupled to the implementation of the Customer. This means anytime you change some behavior of the Customer you might have to change your PaperBoy test, not such a big problem for the 2 tests, but if there are 50? if there are 100? that can be bad news.
</ol>
<p>It's not clear to me that inverting the control is the "right" thing to do, but I think if you're careful (and you want 100% unit test coverage), inverting the control and using mocks can help you cut down on test complexity and test maintenance, so... mock-on?
<p>
Thanks everyone who participated in the discussions!Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com2tag:blogger.com,1999:blog-7594548881489150326.post-32765112532036674072009-09-22T17:34:00.003-04:002009-09-24T08:33:05.449-04:00Contract Tests<p>I had a post almost a year ago <a href="http://zdsbs.blogspot.com/2008/11/hard-contracts-vs-soft-contracts.html">Hard Contracts vs Soft Contracts</a> that was I reminded of when I came across this post on <a href="http://www.markhneedham.com/blog/2009/09/18/tdd-testing-with-generic-abstract-classes/">Testing with generic abstract classes</a>. At our company we've been using the abstract test case pattern for a while, but have been struggling with naming... why not just call it FooAbstractTest you ask? Because, well, our build looks for classes that are named Foo*Test* in our test package and tries to run the abstract test cases and it breaks our build. So like any good software engineer instead of solving the problem, we just tried to work around it (sigh).
<p>Anyway, we were struggling for a good naming convention, the best we could come up with was FooBase (terrible) but then as I mentioned I came across Mark's post, which in turn lead me to this wonderful page on c2 <a href="http://c2.com/cgi-bin/wiki?AbstractTestCases">http://c2.com/cgi-bin/wiki?AbstractTestCases</a>. The first line says it all, "Contract Tests" and really I knew it all along. I had been thinking of them in terms of hard contracts vs. soft contracts. So now I can feel good about myself and continue being a good software engineer, I have a better name, FooContract.
<p>UPDATE - If you followed the link to the c2 page, you'll see that J. B. Rainsberger is referenced all over the place. Well he just republished his initial thoughts on the <a href="http://www.jbrains.ca/permalink/281">Contract Test</a>. Also, if it wasn't clear, I was being very tongue in cheek about not fixing our build, we should do it, but finding a good name for these kinds of tests is also important.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com2tag:blogger.com,1999:blog-7594548881489150326.post-8553744993188823302009-08-27T09:57:00.003-04:002009-08-27T10:23:18.988-04:00Builder Pattern in Clojure<p>We've been working steadily on our toy <a href="http://github.com/zdsbs/trafficsimulation">traffic simulator</a> and doing TDD along the way. Of course a major concept in a traffic simulator is a car, so we of course have a car struct + cars have some behavior patterns so we also have a behavior struct. They look like:
<blockquote><pre>
(defstruct behavior :accel-dist :decel-dist)
(defstruct car :name :position :length :speed :behavior)
</pre></blockquote>
<p>So to construct a valid car you need to do something like:
<blockquote><pre>
(struct car :a 1 1 1 (struct behavior 10 5)))
</pre></blockquote>
<p>Yikes, we constantly wanted cars for our tests and constructing a car like that was often more code than the real stuff we wanted to test. So, we made a bunch of convenience methods (object mother type stuff), like:
<blockquote><pre>
(defn slow-car [name position]
(struct car name position 1 1 (struct behavior 10 5)))
(defn car-with-speed-position [speed position]
(struct car :a position 1 speed (struct behavior 10 5)))
</pre></blockquote>
<p>Suddenly we started creating lots of car-with-* methods. We got annoyed and accidentally started implementing the builder pattern.
<blockquote><pre>
(defn default-car []
(struct car :a 1 1 1 (struct behavior 10 5)))
(defn car-with
([key value]
(assoc (default-car) key value))
([key1 value1 key2 value2]
(assoc (car-with key1 value1) key2 value2)))
</pre></blockquote>
<p>Ignore the total ugliness of the car-with function for a moment, this let us do things like:
<blockquote><pre>
(def a-car (car-with :speed 1 :position 4))
</pre></blockquote>
<p>as opposed to:
<blockquote><pre>
(def a-car (car-with-speed-position 1 4))
</pre></blockquote>
<p>Our new version, was not only easier to read, and didn't make us create new methods for each different thing we wanted to do, but hey, that looks really similar to the builder pattern. Now I'm sure there are better ways to implement car-with, but it works for now.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-88428074597494206422009-08-26T08:22:00.002-04:002009-08-26T09:09:01.304-04:00Null once again<p>InfoQ has a nice talk by <a href="http://en.wikipedia.org/wiki/C._A._R._Hoare">Tony Hoare</a>, <a href="http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare">Null References: The Billion Dollar Mistake</a>. I've been in a few arguments in that past that languages would be much better without null, so it's nice to hear someone much smarter than myself, who also happens to have invented the null reference regret their existence. But he doesn't feel as bad as he thinks the C language designers should feel, because he says, they allowed the for the buffer overflow by abusing the get routine. And that allowed for viruses, which have cost industry much more than his billion dollar mistake. He's tough on the language designers (and himself): "Language designers should be responsible for the mistakes programmers make". Thanks Tony, for giving me someone to blame when I muck things up :)Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-40909097667192274512009-08-01T23:20:00.002-04:002009-08-01T23:27:22.267-04:00Returing Null... again<p>so... thinking more about returning null. I'm thinkin' returning null is allowing you to return a second type from a method. And a null pointer exception is equivalent to a class cast exception. AND a null check if (foo == null) is the same as an instance of check.
<p>nulls are syntactic sugar for a type! I refuse to think of them as values for references any longer. They are types, returning them from functions is returning multiple types from a function (not in a polymorphic way, but in a type system abusing way) and null checks are instance checks.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com2tag:blogger.com,1999:blog-7594548881489150326.post-69979839038216316662009-08-01T14:17:00.005-04:002009-08-01T14:52:50.033-04:00Returning Null<p>I've always had a problem with returning null from a method. And I was reminded of this when reading a post at Misko Hevery's blog about <a href="http://misko.hevery.com/2009/07/31/how-to-think-about-oo/">how to think about OO</a>
<p>I think returning null is a problematic, it's often abused as a way to have two different return types from one method. A quick googling of "returning null" has the suggestion of returning a null object implementation of your return type. Returning a Null Object is appropriate in some cases, but not when you need to signal to your client two different things. Misko's code refactoring show's an example of this. He refactors some login code (I really like the steps he took btw) down to something like:
<blockquote><pre>
Cookie login(Ldap ldap) {
if ( ldap.auth(user, password) )
return new Cookie(user);
return null;
}
</pre></blockquote>
<p>When I read this code I see two things (structurally that is)
<ol><li>If authentication succeeds then notify the client of the successful authentication with a new Cookie
<li>If authentication fails notify the client by returning null
</ol>
<p>What could a client of this method look like?
<blockquote><pre>
public void authenticateUser(User user) {
Cookie userCookie = user.login(ldap);
if (userCookie == null) {
//notify someone that auth failed
} eles {
//register them as logged in
}
}
</pre></blockquote>
<p>We're doing the same work twice in each place, but with slightly different syntax, each place we need to check if login failed or not. What if instead we used <a href="http://martinfowler.com/bliki/InversionOfControl.html">IoC</a> / "Tell Don't Ask" / "Hollywood Principle"
<blockquote><pre>
Cookie login(Ldap ldap, AuthenticationRegistry authenticationRegistry) {
if ( ldap.auth(user, password) )
authenticationRegistry.authSucceeded(new Cookie(user));
authenticationRegistry.authFailed(user);
}
</pre></blockquote>
<p>and the client
<blockquote><pre>
public void authenticateUser(User user) {
user.login(ldap,this);
}
public void authSucceeded(Cookie cookie) {
//register them as logged in
}
public void authFailed(User user) {
//register them as auth failed
}
</pre></blockquote>
<p>This new code is a little more complicated, but I think it is clearer, and more straight forward to implement. Now we have two entities that are communicating with each-other and we've defined the way in which they are communicating. Again I liked Misko's refactorings, I'd just take it one step further. It's all definitely arguable, but I think if you're ever in a situation where you want to be returning two types of data from a method using IoC is the way to go.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com16tag:blogger.com,1999:blog-7594548881489150326.post-24106994481865452672009-07-21T22:43:00.005-04:002009-07-21T23:18:47.326-04:00Clojure + Bowling Kata<p>Just the other day (yesterday) Uncle Bob had a post about <a href="http://blog.objectmentor.com/articles/2009/07/19/uncle-bob-jsps-learning-clojure">Learning Clojure</a>. He implemented <a href="http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata"> a bowling scoring kata</a>. So Dan P. and I decided to try it ourselves, but since we're from Boston we implemented candle pin bowling rules:
<p>
As we were talking through designs for this, and as we talked about scoring frames, we realized that there were three cases:
<ol>
<li>Strike – score the first ball, plus the next two ‘bonus’ balls, then remove the first ball (the strike) from the list, then continue scoring.
<li>Spare – score the first two balls, plus the next ‘bonus’ ball, then remove the first two balls (the spare) from the list, then continue scoring.
<li>No-mark – score all three balls in the frame, then remove them from the list, then continue scoring. (Remember: candlepin!)
</ol>
In all these cases you want to score three balls, the only difference was in how many balls you remove from the list before you continue scoring (i.e., how many balls were in the frame you are removing from the yet-to-be-scored list). So this is what we came up with:
<a href="http://github.com/zdsbs/candlepin-bowling/tree/master">http://github.com/zdsbs/candlepin-bowling/tree/master</a>
<blockquote>
<pre>
(ns scorecard)
(defn third [rolls]
(first (next (next rolls))))
(defn first-two [rolls]
(+ (first rolls) (second rolls)))
(defn strike? [rolls]
(= 10 (first rolls)))
(defn spare? [rolls]
(= 10 (first-two rolls)))
(defn remove-strike [rolls]
(rest rolls))
(defn remove-spare [rolls]
(rest (rest rolls)))
(defn remove-normal-frame [rolls]
(rest (rest (rest rolls))))
(defn remove-frame [rolls]
(if (strike? rolls)
(remove-strike rolls)
(if (spare? rolls)
(remove-spare rolls)
(remove-normal-frame rolls))))
(defn score [input-rolls]
(loop [rolls input-rolls score 0 frame-counter 0]
(if (or (empty? rolls) (= 10 frame-counter))
score
(recur
(remove-frame rolls)
(+ score (first rolls) (second rolls) (third rolls)) (inc frame-counter)))))
</pre>
</blockquote>
<p>And the tests:
<blockquote>
<pre>
(ns scorecard-test
(:use clojure.contrib.test-is
scorecard))
(deftest test-third
(is (= 3 (third [1 2 3 4]))))
(deftest test-first-two
(is (= 3 (first-two [1 2 3]))))
(deftest test-remove-frame
(is (= [3 4 5] (remove-frame [0 1 2 3 4 5])))
(is (= [3 4] (remove-frame [10 3 4])))
(is (= [5] (remove-frame [6 4 5]))))
(deftest test-remvo-two-frames
(is (= []
(remove-frame
(remove-frame [0 1 2 0 0 0])))))
(deftest test-scores
(is (= 0 (score [])))
(is (= 6 (score [1 2 3])))
(is (= 15 (score [1 2 3 4 5 0])))
(is (= 19 (score [10 1 2 3])))
(is (= 17 (score [5 5 1 2 3])))
(is (= 300 (score [10 10 10 10 10 10 10 10 10 10 10 10])))
(is (= 19 (score [5 5 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 ])))
(is (= 21 (score [10 1 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 ]))))
</pre>
</blockquote>
<p>Also check out:
<br>Stuart Halloway's <a href="http://blog.runcoderun.com/post/145675117/tdd-in-a-functional-language-uncle-bobs-bowling">implementation</a>. Besides just an implementation, he has a great discussion on how to approach the problem in a functional way. (his implementation is much nicer than this one)
<br>Uncle Bob's son over at 8th light also wrote up an <a href="http://blog.8thlight.com/articles/2009/7/20/bowling-in-clojure">implementation</a>Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-52066399929278994822009-07-19T23:55:00.004-04:002009-07-20T00:15:32.346-04:00Git Commands Part I<p>I'm always forgetting a very useful git command, so I'm posting it here in the hopes that: a) writing it down will help me remember and b) if I forget again, at least I can just goto my blog.
<p>git add -u
<br>(if you're like me and you rename or delete files without calling git rm git add -u takes care of staging the changes)
<p>and thank you Stack Overflow: <a href="http://stackoverflow.com/questions/492558/git-rm-multiple-files-that-have-already-been-deleted-from-disk">git rm multiple files that have already been deleted from disk</a>
<p>Oh and if you're pushing a Java project into a git repository, the .git/info/exclude file is very useful to ignore all the generated .class files.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-74256857756363175412009-07-15T15:07:00.002-04:002009-07-15T15:22:53.665-04:00Block Editing in Eclipse Galileo<p>Eclipse now has block editing hooray!
<p>Ummm, what's the key binding for it? There's nothing in eclipse help, nothing in cmd-shift L, too many of my google searches took me to a crappy <a href="http://www.reddit.com/r/programming/comments/8uksy/eclipse_galileo35_comes_out_on_wednesday_and/">reddit page</a> which doesn't tell you what the key binding is. Eventually someone decided to be helpful with <a href="http://blog.goyello.com/2009/06/25/6-reasons-why-you-should-use-the-new-eclipse-galileo/"> this post</a>. The key binding on OS X is cmd-alt-a
<p>Anyway, hooray for block editing. Boo for wasting time looking for the keybinding, I hope this saves someone some time.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com2tag:blogger.com,1999:blog-7594548881489150326.post-30158014814103768262009-07-08T11:25:00.003-04:002009-07-08T11:33:00.766-04:00Hawthorne Effect<p>
Apparently my post on <a href="http://zdsbs.blogspot.com/2008/09/measuring-things.html">measuring things</a> was really about the <a href="http://en.wikipedia.org/wiki/Hawthorne_effect">Hawthorne Effect</a>. Which in brief is: The simple action of measuring peoples productivity will increase their productivity. If you read that article though, there are lots and lots of criticism, but I prefer the BS approach, it's a cool idea, let's run with it!
<p>
I've been enjoying trying the <a href="http://www.pomodorotechnique.com/">Pomodoro Technique</a> and have noticed a change in my productivity. Honestly, I'm not following it strictly, I haven't even read much of the website, but I did download a little app and I'm measuring tasks. I'm guessing one of two things is a result of the change in productivity:
<ol>
<li>The Hawthorne Effect has some merit and by measuring my tasks, and measuring my goofing off, I'm improving the amount of time I'm staying on task
<li>There's something about a change in process that makes you notice inefficiencies in the way you do things
</ol>
<p>
For the time being I'm going to assume #1 is true :) and that the Hawthorne Effect probably isn't valid in a general sense. You can always game metrics / measurements etc. etc. But on a personal level, if the metric you're measuring is of value to you, if you don't game your own personal game, then I think those metrics do have value and the Hawthorne Effect does apply. Or at least that's the BS I'm slinging today.
<p>This post took 30 minutes to write, I'm now taking a 5 minute break.Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com2tag:blogger.com,1999:blog-7594548881489150326.post-78610326881214006742009-06-30T15:47:00.005-04:002009-06-30T15:55:26.511-04:00Corey Haines Visit to Icosystem<p>Friday the 26th was a fun day at <a href="http://icosystem.com">Icosystem</a>. Through a random chain of events <a href="http://www.coreyhaines.com/">Corey Haines</a> stopped by as part of his <a href="http://programmingtour.blogspot.com/">pair programming tour</a>. I had the opportunity to pair with him for a few hours and talk a lot of shop.
<p>Pairing is always a fun activity and it's really fun to pair with someone you've never paired with before. Not only do you get some work done, but you get a nice view into some else's coding process, asthetic, and you always learn a few new tricks. I picked up two things from Corey that I'll be trying out:
<ul>
<li>When doing a refactoring, only allowing one test to be failing at a time. It's hard to do, but I liked how it felt.
<li>The <a href="http://www.pomodorotechnique.com/">pomodoro technique</a> - Work for 25 min, take a 5 min break, use a timer. I installed <a href="http://www.apple.com/downloads/macosx/development_tools/pomodoro.html">Pomodoro 0.24</a> for OS X. It puts a nice little timer in my application (what is that thing called?) bar. Maybe it's a great process or maybe it's just something new, but so far it's a nice tool and is keeping me focused. Another nice feature of it is you note what the task is you're working on. I don't know about you but I have to fill out timesheets for billing, any tool that helps with that is great!
</ul>
I'm sure there were other things I picked up but they're not coming to me right now.
<p>Because of Corey's visit I met a bunch of the Ruby folk in the Boston area. It really made me realize how lacking the Java community is in having a... community. I might have to start going to the <a href="http://bostonrb.org/">bostonrb</a> meetings just to hang out with folks who like to talk about coding. Maybe they won't mind having a Java hacker in their midst :P
<p>Writing this post took me, 27 minutes, I'm terrible at the Pomodoro techniqueZachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com2tag:blogger.com,1999:blog-7594548881489150326.post-89286830975402030082009-06-23T22:41:00.002-04:002009-06-23T22:44:05.643-04:00The Downfall of Agile Hitler<p>
Who knew Agile could be so hilarious: <a href="http://www.youtube.com/watch?v=l1wKO3rID9g">The Downfall of Agile Hitler</a>
<p>
Also a little less funny but also great: <a href="http://www.youtube.com/watch?v=T-Qn_-F2x1c">Hitler Does Unit Testing</a>Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0tag:blogger.com,1999:blog-7594548881489150326.post-18609881177163784072009-06-12T13:45:00.004-04:002009-06-13T19:49:51.008-04:00Learning Clojure - Calling Clojure From Java<p>Last night, we played with some of Clojure's interop with Java. We tried out with great success Jay Fields little <a href="http://blog.jayfields.com/2009/05/calling-clojure-from-java.html">example</a>. Next up was compiling Clojure to Java class files (this was much trickier).
<p>The documentation is pretty good and can be found at: <a href="http://clojure.org/compilation">http://clojure.org/compilation</a> and under the <a href="http://clojure.org/API#gen-class">(gen-class)</a> API entry. There are two tricky bits, 1) the extra 'this' arg 2) the classes compilation directory.
<p>But first the code sample:
<blockquote><pre>
(ns printer
(:gen-class
:methods [[printString [String] void]]
)
)
(defn -printString [this arg]
(println arg))
</pre></blockquote>
<p>:gen-class is the directive to the clojure compiler that it should compile this .clj file into a java class. The :methods section allows us to define methods, we're defining the printString method which is a void and takes a String as it's arg.
<p>The clojure function must begin with a '-' and then there's the 'this' arg. It took a little bit to find the 'this' gem in the documentation on the compilation entry (seriously, who reads everything before they start experimenting)
<blockquote>
hasNext and next are implementations of methods in the Iterator interface. While the methods take no args, the implementation functions for instance methods will always take an additional first arg corresponding to the object the method is called upon, called by convention 'this' here. Note how the state can be obtained using an ordinary Java field access.</blockquote>
<br>So no matter what method you expose to java it will alway have at least one arg which is the instance of the object. I can't tell you how many times we were so confused why we were getting wrong number of arg error messages when first trying this out.
<p>Now to compile:
<br>java -cp clojure.jar:. clojure.main -r
<br>user=>(compile 'printer)
<br>java.lang.RuntimeException: java.lang.ClassNotFoundException: printer$_printString__4 (NO_SOURCE_FILE:0)
<p>This is because you didn't create 'classes' directory and add it to your classpath, it's exactly what the error says right?
<br>create the directory, add it to your class path and try again
<br>java -cp clojure.jar:.:classes clojure.main -r
<br>user=>(compile 'printer)
<br>printer
<p>Great, hopefully there are no more exceptions, try javap on printer.class you should see something like:
<blockquote><pre>
zacharyshaw$ javap classes/printer
public class printer extends java.lang.Object{
public static {};
public printer();
public java.lang.Object clone();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public int hashCode();
public void printString(java.lang.String);
public static void main(java.lang.String[]);
}
</pre></blockquote>
<p>Now you should be all set to call through to your printer.class
<blockquote><pre>
public class Foo {
public static void main(String[] args) {
new printer().printString("hello world");
}
}
</pre></blockquote>
<p>There's loads of different things you can do, like implementing interfaces, extending classes etc. I'm really looking forward to seeing how I can integrate clojure into one of my projects (only where it makes sense of course :P )Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com6tag:blogger.com,1999:blog-7594548881489150326.post-74992516046479194252009-06-08T15:28:00.004-04:002009-06-08T15:57:41.922-04:00Regurgitation<ul>
<li><a href="http://www.notesfromatooluser.com">Mark Levinson</a> has a nice blog <a href="http://www.notesfromatooluser.com/2009/06/agile-mailing-lists.html">post on agile mailing lists</a>, it's a good collection of interesting lists.
<li>Started a new project and am using <a href="infinitest.org">infinitest</a> it's great! <br> I love how hard-core it makes testing. When I suggested to a few co-workers that they install it, I started getting questions: "so how do I turn off those compilation errors it creates?" Answer: "fix the tests or turn off the plugin"
<li><a href="http://www.threeriversinstitute.org/blog/">Kent Beck</a> had an interesting blog post <a href="http://www.threeriversinstitute.org/blog/?p=187">To Test or Not to Test? That's a Good Question.</a> <br> I really recommend checking out his blog, the content is great (I think I'll have to suck it up soon and try out junitmax, maybe for my next project)
<li>My weekly Clojure learning sessions are still going strong, got my <a href="http://pragprog.com/titles/shcloj/programming-clojure">Programming Clojure book</a> in the mail last week, it's nice to have a paper copy. <br>We're <a href="http://github.com/zdsbs/learningclojure/tree/master">working</a> on putting penalties (in the form of delays) if you hit the direction keys too frequently. I finally feel like I'm getting a feel for the language.
<li>and apparently Rich Hickey doesn't like testing:
<a href="http://blog.objectmentor.com/articles/2009/06/05/rich-hickey-on-testing">http://blog.objectmentor.com/articles/2009/06/05/rich-hickey-on-testing </a>
</ul>Zachary D. Shawhttp://www.blogger.com/profile/11739142419934264380noreply@blogger.com0