Sunday, September 25, 2011

Determining Your Value

This summer I took a break from my extra-vocational studies to reflect upon my career and my plans for the future. There are a surprising number of software career books out there, but I turned to the Pragmatic Press for the Passionate Programmer by Chad Fowler, a saxaphonist/programmer (with no relation to Martin Fowler). I love that the Pragmatic Programmers are passionate about things other than programming, such as woodworking, aviation, or music, but I'm not crazy about the name of the book. I guess the idea is to play off of the Pragmatic Programmer.

A lot of Fowler's advice is common sense, though common sense is not always so common. One of Fowler's most interesting suggestions for me was: your value depends upon your ability to give different people what they need. Writing elegant code, keeping up on the latest technologies, or other technical skills are only a small part of your value as an employee of a company, as you are likely to have a lot of different demands from a lot of different people.

Salespeople could care less about how elegant your code is unless your poor skills lead to performance issues with their reports. Your managers are primarily concerned about managing you. If you are difficult to manage--such as by not showing initiative or not keeping them informed of your bottlenecks--you become less valuable. Your users need someone who understands what they actually do and who can speak their language. If you don't learn their vocabulary, you're not a good programmer. Your teammates need someone they can count on, such as when the production system goes down or you break the build. HR needs you to fill out timesheets. Finance needs you to bring in more money than you cost. If you can't do any of those things, you're not a good programmer.

This piece of advice really hit home with me because, as a philosophical pragmatist, I've long held that there are many factors that could determine a thing's value. Whether or not that thing is valuable to you depends upon how those factors impact you. We often think of a rotten tomato as being bad, but it's only bad if you want to eat a tomato. If you want something to throw at a comedian, it might be just what you need. There's nothing intrinsically good or bad about a rotten tomato. There's no category of 'tomato-ness' that it's not living up to. It's just a rotten tomato.

In the same way, there's no one thing you must do in order to be an excellent programmer--not even programming. Many developers think that they're under-appreciated geniuses who should get paid proportionately to how smart they are. They don't have to worry about writing coherent emails, filling out paperwork, dressing appropriately, or staying after 5:00 PM when the server goes down at 4:59.

If you don't think about your value in the right way, you will not be able to articulate your value when it's time to talk about raises or starting salaries. A great interview question is: "I see you cost X dollars last year. How did you return on that investment?" Often, we're so used to being bombarded with technical questions and thinking about our value from a technical perspective that we cannot answer such questions very well. This is a habit that you should try to break.

It does take some work to become a great programmer. A good way to start is: instead of asking yourself what you need to accomplish today, ask yourself what you need to do for the people who depend on you. Prioritize accordingly.

Links:

-William James's Pragmatism: A New Name for Some Old Ways of Thinking. The first two chapters are classic.

Sunday, September 18, 2011

Io, Syntactic Sugar, and Performance

I had never heard of Steve Dekorte's Io language until coming across it in Bruce Tate's book. Io uses the prototype-based or classless paradigm, which is a flavor of the Object Oriented paradigm. In classless programming, classes are not declared but are cloned from the base object class. Such languages are usually interpreted and dynamically typed. The most popular classless language is JavaScript.

Io is interesting for a number of reasons, such as its actor-based concurrency model, but what struck me the most in working through Bruce Tate's examples was the ugliness of the code. There's no way around it. It's just ugly. This was especially noticeable after learning some Ruby. If you want a complex class structure, you have to do a lot of cloning. Here's an example that clones the root object class and then clones that clone in order to actually do something:
Account := Object clone do(
balance := 0
deposit  := method(v, balance = balance + v)
withdraw := method(v, balance = balance - v)
show := method(writeln("Account balance: $", balance))
)

myAccount := Account clone
myAccount show
"Depositing $10\n" print
myAccount deposit(10)
myAccount show
While the words "programming" and "aesthetics" are not often used in combination, we do regularly talk about the elegance of code--meaning its ability to solve a problem in a creative and concise manner. Elegance can come at the price of readability, since it typically involves doing something complex in a short number of lines. Io does concurrency elegantly, but its classless model doesn't allow for a lot of concision or elegance more generally. If you want to create a number of classes with a number of methods, this will take many more lines than in a language like Ruby.

Unlike Io, Ruby has a lot of syntactic sugar, or programming shortcuts that make code more readable and concise. This is different from elegance, since syntactic sugar has to do with syntax while elegance has to do with logic. For instance, instead of defining a bunch of get and set statements for a class's properties, you can define them all in one line using the attr_accessor command in Ruby. These shortcuts can make the learning curve a little steeper, since there are more commands to learn, but this might be a trade-off worth taking. Io takes minimalism to the extreme, so you can learn the basics in a short amount of time. However, understanding how to turn the small bits into something bigger is another question entirely!

Besides having a more gradual syntactic learning curve, Io's lack of syntactic sugar enables it to have a very small virtual machine (about 9k semicolons). This means it can fit on small embedded systems, though I'm not sure how many production environments use it. I should also mention that, despite its small footprint, it is not known for being performant, given its message-passing structure and the fact that it is not compiled.

Io has helped me to understand and appreciate JavaScript better, instead of simply thinking of it as a more difficult to debug version of C++, but it made me pine for more readable languages like Ruby or VB.NET.

Links:
-The Io Language

Sunday, September 4, 2011

Software Gardening

The Pragmatic Programmer has a lot of nuggets. Here's one:
The most common metaphor for software development is building construction. Using construction as the guiding metaphor implies these steps:
  1. An architect draws up blueprints.
  2. Contractors dig the foundation, build the superstructure, wire and plumb, and apply finishing touches.
  3. The tenants move in and live happily ever after, calling building maintenance to fix any problems.
Well, software doesn't quite work that way. Rather than construction, software is more like gardening--it is more organic than concrete. You plan many things in a garden according to an initial plan and conditions. Some thrive, others are destined to end up as compost. You may move plantings relative to each other to take advantage of the interplay of light and shadow, wind and rain. Overgrown plants get split or pruned, and colors that clash may get moved to more aesthetically pleasing locations. You pull weeds, and you fertilize plantings that are in need of some extra help. You constantly monitor the health of the garden, and make adjustments (to the soil, the plants, they layout) as needed.
I'm trying to think this metaphor through, as, until now, I had not questioned the metaphor of architecture. Intuitively, I have a sense for what Hunt and Thomas mean. After all, these guys started the Agile Alliance, which takes the 'waterfall' or linear model of software development as its main target. The four main principles of the Agile Manifesto are:
  1. Individuals and interactions over processes and tools
  2. Working software over comprehensive documentation
  3. Customer collaboration over contract negotiation
  4. Responding to change over following a plan
I have done some organic gardening, so I have a little experience to draw upon to understand what Hunt and Thomas are getting at.

The first thing I learned gardening is that you cannot start from scratch. No matter how much pesticide you spray or soil you import, there are soil, drainange, water, sunlight, insect, animal, and other conditions that shape what will grow and what won't. The earth has been here a lot longer than your garden has. In the software world, you don't begin at the beginning either. You have a team's knowledge and relationships, IT infrastructure, available languages and platforms, customer expectations, and the market of existing competitors and third party vendors, to name a few. And, of course, the majority of work as a software developer is not development but refactoring existing code.

The second thing I learned is that things rarely work out the way you planned and that you have to adjust to these events. One year, a groundhog ate almost all our butternut squash. Another year there was a tomato blight. We built an electrified fence to cut our squash losses, and we made sure to not plant tomatoes in the same place next year. In software, you have to do what you can to contain unexpected events. This happens at a macro and a micro level. For instance, on a micro level, code should be robust enough to handle exceptional situations. At a macro level, it should be flexible enough to handle change. For instance, in order to best adapt to increasing demand, your system should designed to scale. If you might have 10 million new customers in a month, you must make sure that your database architecture can adapt to that demand.

The last main thing I learned is that to be a good gardener, you have to be able to learn. No one is born with a green thumb, but some people learn more quickly than others what works and what doesn't. It's a lot easier to start gardening if you know some people who already garden. And no matter how much reading you do, there is always more to learn, because there are always new things you have to deal with. The same is true for software development. Many programmers are 'book-learned' and can't apply their knowledge, or they are narrowly knowledgeable about a handful of languages or platforms. It amazes me when I hear people describe themselves as either back-end and front-end programmers, because a good programmer must be both. If you follow Hunt and Thomas's advice, you'll learn a language a year!

Of course, gardening doesn't sound quite as cool as architecture, but good architecture follows many of the same practices outlined here. For example, modernist architects are accused of ignoring site specificity and simply plopping down skyscrapers in the middle of thriving urban ecosystems. If you don't learn from previous projects, you'll get a bunch of haunted shells like those that make up Dubai's skyline. Buildings are much less malleable than code, but that is all the more reason not to use them as a model.

Links
-An interview with Andy Hunt and David Thomas about software gardening

Erlang and Concurrency

I was excited to learn me some Erlang, since the mysterious language has recently gotten a lot of press for being the tool of choice for Facebook Chat. It's often cited as a way to break the performance barriers of multi-processor architecture and mainstream programming languages that use multi-threading. A program is as fast as its slowest part, and this is typically the resources shared by threads. These resources also require some fancy coding techniques to ensure their integrity. And, of course, the more complicated the code, the more likely it is to break and be difficult to maintain.

Erlang's simple model is based around processes that pass messages to each other, crash, and respawn very quickly. After compiling a module, you spawn a process using:
handle = spawn(module, function, parameters).
The process is defined as a function that shreds out the parameters with a series of case statements:
function -> receive
	{parameter1} ->
		%do something
	{parameter2} ->
		%do something else
	Unexpected ->
		%handle exceptions
end.
You can pass messages to a spawned process using:
handle ! parameters.
This architecture allows you to quickly create, monitor, message, and respawn processes whenever they fail. Because Erlang is a functional language, there are no variables or any other shared resources that can form a bottleneck between processes liked global variables. Processes communicate using messages, and these can be processed asynchronously or independent of any other processes.

Erlang's concurrency model is similar to Service Oriented Architecture, except that concurrency is built into the system at the lowest level, not added on top of an Object Oriented framework and requiring several other technologies. Note also that concurrency is very different from parallelism. If you need to crunch a lot of numbers, you'd need to use a parallel processing system, not a concurrency model.

Erlang is best for soft real-time, distributed, and highly-available applications that could be composed of message-handling systems, like Facebook Chat or low-level telecommunications software. (These are very specific applications that I tend not to think about very often, so I don't have a mock-up like I have tried to have in other posts.)

For these reasons, Erlang is not a cure-all for performance-related problems, though it is important to note that there are limits to any concurrent or parallel approach. Amdahl's law states that even with 95% parallelism, performance benefits will quickly plateau as the number of processors increase.  E.g., if your program takes 20 seconds to run, and 1 second of it cannot be parallelized, the least amount of time it could run in is 1 second.  No matter how many processors you add, you cannot break that 1 second barrier without further parallelizations.


As a side note, I had not heard of Amdahl's law before researching Erlang. Interestingly, I also just learned of IBM's SyNAPSE project, which has the grand aim of functionally replicating the human brain. One argument for a new hardware architecture based on neural networks is that, though the firing of individual neurons is slow, the massively parallel processing power of a brain more than makes up for the performance of any individual part. I'm not sure how this argument stacks up against Amdahl's.

I'll be looking for opportunities to write me some Erlang, but--given my own limits to processing in parallel--this may not be any time soon.

Links:
-Erlang home page
-Eugene Letuchy's notes on designing Facebook Chat
-Learn You Some Erlang, a free online book
Related Posts Plugin for WordPress, Blogger...