Archive for August, 2011
In my last post, I started to look at the Scheme language. We finished up with a simple if statement. Its syntax is like this: (if (condition) result1 result2).
In our last example, “result1” and “result2” were simple return types. If you wanted, the “result1” or “result2” could also be functions that are evaluated to get a return value. Let’s look at that.
In this case, if 4 is greater than 0, we are going to multiply 4 times 4, if 4 isn’t greater than 0, we are just going to add 4 plus 4.
(if (> 4 0) (* 4 4) (+ 4 4))
You can see that because 4 is greater than 0, it executed the first block which evaluated 4 * 4 which is 16. Like last time, here is the equivalent C# version to hopefully add clarity.
if (4 > 0)
return 4 * 4;
return 4 + 4;
One of the most powerful things you can do in a functional language is – of course – to define your own functions. Here is a simple function that defines a function named pete that squares a number passed to it.
(define pete (lambda (x) (* x x)))
So here, we are calling the define language construct (which is how you declare variables, functions, etc in Scheme) and defining “pete” which is a lambda that takes one parameter – x – and returns the output of the * function being passed x and x. You see that if we call the pete function and pass in 7, it returns 49 as you would expect.
Functions are first class citizens in Scheme, so you can pass them around as arguments. Let’s see this example where I’m going to let us “do-stuff-to-four-and-nine”. My goal here is that we are going to create a function that takes a function as a parameter. It then calls that function, passing it 4 and 9.
So, first the function. (I used a hard return in the REPL window so that the screenshot below would definitely fit. It does not cause a problem in the language to have it there).
(define do-stuff-to-four-and-nine (lambda (our-func) (our-func 4 9)))
All I’ve done is define “do-stuff-to-four-and-nine” as a function that takes a parameter (our-func) that I then use in the body of the lambda, calling it and passing 4 and 9 as arguments. Next, let’s define 4 functions that we can pass to our “do stuff” function.
You should be able to simply read these by now. All four take two parameters, and are plainly named for the simple operations they perform on them.
Now, all that is left is to call the “do-stuff” function and pass it each of these functions in turn.
Interestingly, the function must take the right number of arguments. If not, the language throws up on you. Notice here that I define a function that only takes one argument. Then when I try to pass it in to our “four and nine” function, I get an error.
I hope that you’ve learned a little bit more about how Scheme works and how powerful it can be. My next post is going to take a look at recursion in Scheme and putting a lot of these lessons together.
The other night, I was reading through Hacker News or Programming Reddit or something and I found an article about writing compilers that supposedly simplified it enough that it could be taught to beginner-level computer science students. It uses potentially hundreds of complier passes to make simple transforms to the code until it has completed its task.
I thought that I’d check it out and I saw that it was written in Scheme. I personally hadn’t spent any time in LISP or any LISP dialects, so it seemed like something interesting to dive in to.
On my Mac, using Homebrew, it was a breeze to get started. At first, I just typed
brew search scheme
I found what I was looking for and then typed
brew install scheme48
Here is an example of what you would see installing it on a Mac.
That’s it! (if you are on Windows, you can get install instructions here)
The only things I knew about Scheme were that it was functional and there were a lot of parentheses. I was right on both accounts. Aside from a few exercises where you were to type a number and have it spit back out to you, the first thing you run into is this:
(* 2 2)
Well, at first glance, stuff like that will throw you a little bit. However, with only a little bit of thought, you can see that it makes perfect sense. We have to think functionally. The parentheses tell us that this group is all one function call and reading left to right we see that we are calling the multiplication function – the * – and passing in the numbers 2 and 2 as arguments. That’s it. So (* 2 2) outputs 4 and (* 2 3 4) outputs 24. Also, we need the parentheses. Without them, you don’t get the desired result as you can see below.
What about control flow? That, too, is very simple. The syntax is simply (if (condition) result1 result2). It is very similar to an IIF statement, but without the commas. If you take this code, you get the result pictured below.
(if (< 4 5) "four is less than 5" "four is not less than five")
If you are having any trouble making sense of it, it might be helpful to think of this code in terms of how it breaks out in C#
if (4 < 5)
return "four is less than five";
return "four is not less than five";
I hope that if the Scheme code was confusing to you, that the C# translation helped a bit. You'll notice that just as a Ruby function returns the last thing that was evaluated, so too does Scheme. That's why there are no return statements in my Scheme example, but there are in the C# example.
Next time, we'll look at more complex if statements and travel down the functional road a little further.
I just read a post over at The Hundred Minute Hack called Do Programming Language Skills Exist?. The basic premise is that you don’t have Java Skills or Python Skills or Ruby Skills, you have object oriented skills, functional skills, etc. These languages are just tools.
If we keep the “Software Developer As Craftsman” metaphor, a carpenter might have 10 years of general carpentry skills, or 20 years at furniture making. What a carpenter would never really need to put on a resume is:
- Hammer – 20 years experience
- Manual Saw – 20 years experience
- Table Saw – 18 years experience
- Router – 14 years experience
- Clamp – 20 years experience
- Sandpaper – 20 years experience
- Belt Sander – 19 years experience
For an experienced carpenter, it very rarely matters what his toolset is, it matters what skills he possesses. The tool often just offers an easier or faster way to do something he already knows how to do.
With so many things changing so quickly in software development, it really is the skills that matter. It is possible to have almost 30 years of object oriented programming skills. You can have 15 years of skills with the web. You can’t have 5 years of experience with .Net 4 or 10 years of experience with Rails.
As “new and better” things are constantly released, it really is the skill that is transcendant, while the tools come and go. The proven ability to learn the tool is even a skill, but the act of knowing the tool alone is not. I am great with a hammer, but I couldn’t build you anything from scratch. In that same way, someone who only knows the C# language isn’t necessarily going to be any good in some enterprise shop or someone who only knows Ruby isn’t necessarily going to be the person you want to have as the only employee at your start up.
I think that I’ve almost always agreed with Phil, but I never really had the idea codified in my head so succinctly. I’m not saying the tools are worthless (obviously, a carpenter becomes very familiar with his tools – as should we), but I do think that we as programmers are almost worthless if we don’t hone the things that are transcendent skills.
A while back, I read a blog post on Big Bang Technology’s blog written by Max Cameron titled “Why We Don’t Work Overtime“. I will give a full disclaimer here at the outset, I probably work too many hours, so I have a little bit of skin in this game. Namely, I could be accused of only responding because my work choices were being invalidated by someone else. That certainly isn’t my impetus for this blog. I merely wanted to offer a different perspective to Max Cameron’s blog post.
Cameron is writing from the perspective of a Startup Company. He does make an exception to the overtime rule for the founders, but for his employees he says,
There are no heroes at our office. When the clock strikes five,
the team goes home. If they try to keep working, I tell them that
the game's over and they lost. They either put too much on their
plate, got taken off-task, or were wasting time. None of those
justify working past five, on a holiday, or over a weekend.
I certainly applaud his motiviations. He sticks to this rule even when clients ask for it, when they’d need it to win new business, etc. It is one of his company’s core values and they stick to it. Everyone realizes that when an employee (especially a salaried one) works overtime, he is “doing more than he agreed to” and is “taking away family time” and “upsetting the work/life balance”. However, what I find interesting are some of the reasons that their company takes that choice away from their employees.
One major reason that Cameron cites is that to persuade employees to work overtime, the noble concept of “sacrifice” is invoked. In his mind, soldiers, firefighters, and police officers sacrifice, and to try to align that concept with “expected overtime” is a dangerous habit to get in to.
He points out that the employees who work over are the “heroes” and those who don’t are “losers who let you down”. In his words, “Yearly reviews just got a whole lot easier”. Later he says, “How could I promote a loser when they’re surrounded by winners?”.
I want to deal with that point first. He is obviously being rhetorical and a little sarcastic with those last quotes, arguing his point to ad absurdum. However, I think there is a point to be investigated there. My current boss has taught me a lot about managing people and the value of making “the hard decision”. It sounds to me like Cameron is welching a little bit on managing employees. Sometimes, you have to make the hard choices. As my boss likes to say, “Who do we pay to do the hard stuff?”.
Imagine on one hand that you have an employee who works only 40 hours and is very productive, gets along well with others, is a leader, and so on. Now, imagine you have another employee who works a ton of overtime, but you know that it is because he isn’t very efficient. He has a good work ethic and to make up for his lack of efficiency (and “social time” during work hours), he tries to even it out with that overtime. Now, if you are a manager who can’t promote Mr. Productive Forty and explain to Mr. Compensating why he didn’t get the job, you aren’t much of a manager and should rethink your career path.
Let’s pretend there is another scenerio. This time, you have two very equal employees. One of them is a “5:01 Developer” (gone by 5:01 every day) and the other works over to make sure things get done on time, or to add special features off of the “nice to have” list that never gets prioritized ahead of “big projects”. In that case – all else being equal – why wouldn’t you promote the overtime guy?
These kinds of decisions are why you are the person writing the reviews.
A point that Cameron makes alongside this one is the concept of burnout. This is definitely a very real problem. However, I feel that he’s again arguing to take the “copout” path. He seems to be claiming that it is impossible or would require too much work to monitor and make sure that his employees aren’t burning out. There is a big difference between running a guy at 80+ hours a week for months at a time, working 1 or 2 60-70+ hour weeks before huge release, and regulary working 50 hours a week because that’s what you are comfortable working.
As I admitted earlier, I definitely work overtime. I am soon taking my first vacation week in years (only because the company stopped paying out for unused time – I have to “use it or lose it” and I’m too practical for that 😉 ). However, I’ve been going at this pace for about five years straight now, across 2 companies. I’m not close to burnout. You can’t manage people homogeneously, you have to manage to the individual. I’m more of a sports car, not a minivan, there is no danger of running the engine at a little bit higher speeds.
I’m not bragging. My point is that I’m different than other people and a team needs all kinds of people on it. The Apostle Paul actually writes to this point quite eloquently in the Bible in 1 Corinthians 12:14-21:
Even so the body is not made up of one part but of many.
Now if the foot should say, "Because I am not a hand,
I do not belong to the body," it would not for that reason
stop being part of the body. And if the ear should say,
"Because I am not an eye, I do not belong to the body," it
would not for that reason stop being part of the body.
If the whole body were an eye, where would the sense of hearing be?
If the whole body were an ear, where would the sense of smell be?
But in fact God has placed the parts in the body, every one of
them, just as he wanted them to be. If they were all one part,
where would the body be? As it is, there are many parts, but one body.
The eye cannot say to the hand, "I don't need you!" And the head
cannot say to the feet, "I don't need you!"
There are things I do well and things that I don’t do well, and I realize that I don’t always see them clearly. The way that that is remedied is that my team is made up of all sorts of people. The person building the team knows what he has, and fills the gaps appropriately. The fact that I can easily work 50 hours a week or more without burning out is just a tool that my company has at its disposal, just as all of the other skills of employees are at their disposal.
One point that I just could not grasp in Cameron’s blog post was the fact that he is willing to let his clients down because of this overtime policy. Even if the work completed because of overtime would win their clients more business or help solve a serious problem that they are having, overtime is still off limits.
I see nothing wrong with working over to win new business, for you or for one of your clients. Your client has likely worked with others who cannot deliver these things and you make yourself indispensible to him as someone who can deliver them. But again, there is the potential for abuse, but that relies on your client service managers or account representitives to “do the hard stuff” of recognizing and stopping abuse before it gets anywhere.
As I was discussing this topic with a good friend of mine, he pointed out to me that one problem he had with overtime was that it “excused” or “covered up” poor planning. For instance, if a project was projected to have 15 features and be delivered in 2 months, but was estimated poorly, that can be a problem. Proper Agile philosophy is to have the business either extend the date based on the metrics from the iterations, or cut features. Another approach is for it to still spend the hours, but spend them in 60, 70, or 80 hour weeks to meet the deadline. That’s a “death march” and no one really wants that.
However, sometimes it is politically expedient to deliver the project by working the overtime. Not everyone works at a company that can afford to turn down external clients or at a consultancy that can easily refuse work. A good deal of software development is done as part of an “in-house” shop that develops software for “an enterprise”. There are 100 ways that you can curry favor by seemingly doing the impossible and those who don’t see the value in that don’t have a very mature view of the “real world”.
However, the issue then comes if you don’t learn a lesson about your estimating and back yourself into those kinds of corners on project after project. Again, I fall back on “Who do we get to do the hard stuff?” If your Project Managers can’t control these projects from the outset, you probably have the wrong people in there.
This has definitely been one of my longer rants and I know that a lot of people will disagree with me. Feel free to leave a comment below, or blog your own responses. If you do a reaction blog, please link it in the comments so that I can read the discourse and the other readers may benefit, as well.