21 December 2010

Lazy programming « Otaku, Cedric's blog

Lazy programming « Otaku, Cedric's blog
Maybe it’s because static typing is so ingrained into my brain, but when I write something like:

def raise_salary(employee)

I really, REALLY, REALLY want to type:

def raise_salary(Employee employee)

My fingers are just screaming to add this type information. Same for local variables or return types. It’s in my head, it’s in my code, why can’t I just give this information to the compiler, the tools and to future readers and reviewers of this code? It’s really not that much to type and it buys me so much. Think about it: refactorings that are guaranteed 100% correct.

I know, amazing, right?

Java Code Geeks: Things Every Programmer Should Know

Java Code Geeks: Things Every Programmer Should Know. Some interesting points amongst others:
1. Act with Prudence
Technical debt is like a loan: You benefit from it in the short-term, but you have to pay interest on it until it is fully paid off. Shortcuts in the code make it harder to add features or refactor your code. They are breeding grounds for defects and brittle test cases. The longer you leave it, the worse it gets. By the time you get around to undertaking the original fix there may be a whole stack of not-quite-right design choices layered on top of the original problem making the code much harder to refactor and correct. In fact, it is often only when things have got so bad that you must fix it, that you actually do go back to fix it. And by then it is often so hard to fix that you really can't afford the time or the risk.


2. Apply Functional Programming Principles
Mastery of the functional programming paradigm can greatly improve the quality of the code you write in other contexts. If you deeply understand and apply the functional paradigm, your designs will exhibit a much higher degree of referential transparency.
Referential transparency is a very desirable property: It implies that functions consistently yield the same results given the same input, irrespective of where and when they are invoked. That is, function evaluation depends less — ideally, not at all — on the side effects of mutable state.

5. Beauty Is in Simplicity by Jørn Ølmheim
There is one quote that I think is particularly good for all software developers to know and keep close to their hearts:
Beauty of style and harmony and grace and good rhythm depends on simplicity. — Plato
In one sentence I think this sums up the values that we as software developers should aspire to.

7. Beware the Share by Udi Dahan
It was my first project at the company. I'd just finished my degree and was anxious to prove myself, staying late every day going through the existing code. As I worked through my first feature I took extra care to put in place everything I had learned — commenting, logging, pulling out shared code into libraries where possible, the works. The code review that I had felt so ready for came as a rude awakening — reuse was frowned upon!
How could this be? All through college reuse was held up as the epitome of quality software engineering. All the articles I had read, the textbooks, the seasoned software professionals who taught me. Was it all wrong?
It turns out that I was missing something critical.Context.
The fact that two wildly different parts of the system performed some logic in the same way meant less than I thought. Up until I had pulled out those libraries of shared code, these parts were not dependent on each other. Each could evolve independently. Each could change its logic to suit the needs of the system's changing business environment. Those four lines of similar code were accidental — a temporal anomaly, a coincidence. That is, until I came along.
The libraries of shared code I created tied the shoelaces of each foot to each other. Steps by one business domain could not be made without first synchronizing with the other. Maintenance costs in those independent functions used to be negligible, but the common library required an order of magnitude more testing.
While I'd decreased the absolute number of lines of code in the system, I had increased the number of dependencies. The context of these dependencies is critical — had they been localized, it may have been justified and had some positive value. When these dependencies aren't held in check, their tendrils entangle the larger concerns of the system even though the code itself looks just fine.
These mistakes are insidious in that, at their core, they sound like a good idea. When applied in the right context, these techniques are valuable. In the wrong context, they increase cost rather than value. When coming into an existing code base with no knowledge of the context where the various parts will be used, I'm much more careful these days about what is shared.
Beware the share. Check your context. Only then, proceed.

14. Code Reviews
You should do code reviews. Why? Because they increase code quality and reduce defect rate. But not necessarily for the reasons you might think.
Instead of simply correcting mistakes in code, the purpose of code reviews should be to share knowledge and establish common coding guidelines. Sharing your code with other programmers enables collective code ownership.

15. Coding with Reason
More generally, each unit of code, from a block to a library, should have a narrow interface. Less communication reduces the reasoning required. This means that getters that return internal state are a liability — don't ask an object for information to work with. Instead, ask the object to do the work with the information it already has. In other words, encapsulation is all — and only — about narrow interfaces.

18. Continuous Learning by Clint Shank
We live in interesting times. As development gets distributed across the globe, you learn there are lots of people capable of doing your job. You need to keep learning to stay marketable. Otherwise, you'll become a dinosaur, stuck in the same job until, one day, you'll no longer be needed or your job gets outsourced to some cheaper resource.
# Read books, magazines, blogs, twitter feeds, and web sites. If you want to go deeper into a subject, consider joining a mailing list or newsgroup.
# If you really want to get immersed in a technology, get hands on — write some code.
# Always try to work with a mentor, as being the top guy can hinder your education. Although you can learn something from anybody, you can learn a whole lot more from someone smarter or more experienced than you. If you can't find a mentor, consider moving on.
# Use virtual mentors. Find authors and developers on the web who you really like and read everything they write. Subscribe to their blogs.
# Get to know the frameworks and libraries you use. Knowing how something works makes you know how to use it better. If they're open source, you're really in luck. Use the debugger to step through the code to see what's going on under the hood. You'll get to see code written and reviewed by some really smart people.
# Whenever you make a mistake, fix a bug, or run into a problem, try to really understand what happened. It's likely that somebody else ran into the same problem and posted it somewhere on the web. Google is really useful here.
# A really good way to learn something is to teach or speak about it. When people are going to listen to you and ask you questions, you'll be highly motivated to learn. Try a lunch-n-learn at work, a user group, or a local conference.
# Join or start a study group (à la patterns community) or a local user group for a language, technology, or discipline you are interested in.
# Go to conferences. And if you can't go, many conferences put their talks online for free.
# Long commute? Listen to podcasts.
# Ever run a static analysis tool over the code base or look at the warnings in your IDE? Understand what they're reporting and why.
# Follow the advice of The Pragmatic Programmers and learn a new language every year. At least learn a new technology or tool. Branching out gives you new ideas you can use in your current technology stack.
# Not everything you learn has to be about technology. Learn the domain you're working in so you can better understand the requirements and help solve the business problem. Learning how to be more productive — how to work better — is another good option.

19. Think carefully about the design of your api

20. Deploy Early and Often (Continuous Deployment)
Debugging the deployment and installation processes is often put off until close to the end of a project. In some projects writing installation tools is delegated to a release engineer who take on the task as a "necessary evil." Reviews and demonstrations are done from a hand-crafted environment to ensure that everything works. The result is that the team gets no experience with the deployment process or the deployed environment until it may be too late to make changes.

21. Distinguish Business Exceptions from Technical
An unresolvable technical problem can occur when there is a programming error.
A variant of this situation is when you are in the "library situation" and a caller has broken the contract of your method, e.g., passing a totally bizarre argument or not having a dependent object set up properly. This is on a par with accessing 83rd element from 17
A different, but still technical, situation is when the program cannot proceed because of a problem in the execution environment, such as an unresponsive database.
In contrast to these, we have the situation where you cannot complete the call for a domain-logical reason.
Mixing technical exceptions and business exceptions in the same hierarchy blurs the distinction and confuses the caller about what the method contract is, what conditions it is required to ensure before calling, and what situations it is supposed to handle.

26. Don't Ignore that Error!

19 December 2010

Google Caliper

Google Caliper
Caliper is Google's open-source framework for writing, running and viewing the results of JavaMicrobenchmarks.

It is quite rough around the edges (June 2010), but we have already found it quite useful, and the API should be pretty stable.

The simplest complete Caliper benchmark looks like this:

public class MyBenchmark extends SimpleBenchmark {
     public void timeMyOperation(int reps) {
         for (int i = 0; i < reps; i++) {
             MyClass.myOperation();
         }
     }
}

Joshua Bloch: Performance Anxiety – on Performance Unpredictability, Its Measurement and Benchmarking | Javalobby

06 December 2010

DealHub Announces New eFX Price Distribution Customer

DealHub Announces New eFX Price Distribution Customer « A-Team Group
DealHub today announced that Société Générale Corporate & Investment Banking (SGCIB) has selected DealHub as its eFX price distribution system.

The DealHub Connectivity Manager solution supplied by Option Computers Ltd (OCL) provides a low latency price distribution backbone servicing SGCIB customers across the Bank’s newly launched Alpha FX platform, FIX API and multi-bank ECNs.

Broken Windows and collective code ownership

Evolutionary architecture and emergent design: Environmental considerations for design, Part 2
In The Pragmatic Programmer (see Resources), Dave Thomas and Andy Hunt borrow the concept of broken windows from studies about abandoned buildings. Deserted buildings generally aren't damaged until a window is broken. That first broken window indicates that no one cares about the property, and the general disrepair and abuse of the building accelerate thereafter.

Broken windows occur in software development too. When you see some code that's not technically a bug but isn't quite right from a design standpoint, you've found a broken window. Collective code ownership says that you must fix that code. Part of the reason that software projects tend to become more fragile and brittle over time is the presence of hundreds (or thousands) of broken windows. If you fix them routinely, your code can get stronger with age, not weaker.

My projects always use pair programming, and we're always on the lookout for broken windows. But we don't automatically drop what we're doing to attack those problems as soon as we find them. When my pair and I discover an error, we assess how long it will take to fix it. If it will consume less than 15 minutes, we'll go ahead and fix it inline with whatever other story we're working on. If the change is more involved, we add it to a technical-debt backlog. All my projects have a technical-debt backlog, maintained by the technical lead. When we get slack time on the project, the tech lead assigns stories from this backlog to eat away at accrued technical debt gradually.

Collaborative design also suggests that developers are responsible for the correctness and quality of the parts of the overall application they create. Correctness has two facets: adherence to the business requirements and technical suitability. Business-requirements correctness is determined by whatever verification mechanism your company ecosystem has in place to judge the software's suitability to the problem it was written to solve. Technical correctness is left to the development team.

Different teams put their own procedures and mechanisms in place to ensure technical quality, such as code reviews and automated metrics tools run via continuous integration. One practice that many agile teams employ that's a key enabler of emergent design is collective code ownership (http://www.martinfowler.com/bliki/CodeOwnership.html), which suggests that every person on the project has ownership responsibilities for all the code, not just the code he or she has written. (Another benefit of ... collective code ownership is bringing up everyone's skill level to that of the most skilled team member.)

More specifically, it requires:
* Frequent code reviews (or real-time code reviews such as pair programming) to make sure everyone is leveraging common idiomatic patterns and other useful design discoveries by the collective group.
* Awareness by everyone on the project of at least some of the details of all parts of the project.
* Willingness for anyone on the project to jump in and fix broken windows regardless of the original author(s) of the code.