First They Ignore You
A well-meaning dev sets up the wiki on a spare server. It contains some important information about the network that nobody else understands, a very terse guide to application architecture, a page about local bars and restaurants that is, somehow, already out of date.
Then They Like You
Very gradually, through dint of a handful of well-meaning devs continually suggesting people add things to it, it grows. Useful information about how to set up environments is added, as well as how to debug more complex problems.
At some point it reaches a tipping point of usefulness and becomes the defacto place for documentation. Reams of notes from meeting, observations from research spikes, and ideas from brainstorming sessions are added, large parts duplicated and contradictory. It is chaotic but a goldmine. The page on local restaurants and bars is never updated. Only one of the bars is still in business.
Then They Ignore You Again
Eventually the wiki comes to the attention of upper management. Maybe Support. Maybe Sales. Maybe Ops. Somebody sees it, sees that it is good, sees that it is a democratic nirvana to which everybody can contribute and nobody has overall control, and decides it should be theirs.
They institute a Wiki Transformation Project, which despite being a glorified database migration somehow takes six months to complete. When finally complete it is introduced with a company-wide powerpoint presentation (attendance mandatory).
The new wiki is on some more intimidating platform: Confluence maybe, or Sharepoint if you are really unlucky. Half the users do not have permission to edit pages they wrote themselves. All of the formatting is screwed up and several important diagrams and flow charts have been lost completely. The page about local bars and restaurants has been quietly deleted along with, it becomes apparent only later, a number of other pages people relied upon. Only a handful of well-meaning devs ever add anything new to it again.
Loveliness Unfathomable
On coding, at which I am a professional, and on other things such as cooking and gardening, at which I am a distinct amateur.
Wednesday 22 March 2017
Thursday 9 March 2017
Scrum is dumb
Agile, as I never tire of telling people, is a broad set of pretty uncontroversial principles while Scrum is something invented by management consultants to make money. Nowhere in the agile manifesto does it mention stand-ups, story points, or sprints. You can be agile without doing any of those things.
In seventeen years I've never been a part of a team building a thing for a customer who was remotely interested in getting updates every fortnight. About 90% of the time I've been in teams where we all worked on different parts of the same massive mature application (or family of applications). Most <air quotes>projects</air quotes> were coded by only a single developer, very few indeed by more than three. Most could only be released with a great deal of difficulty (sometimes having to navigate the audit processes of customers, and the limited resources therein) and were rarely done so more than once a quarter at the absolute most.
The one time I can recall building a new piece of software as a collaborative team, the customer was represented in the sprint reviews by our own support analyst and, when it came time to hand over some money, declined having never once seen what we produced. Far more often than not there simply was no customer beyond a products guy with an idea they had long since lost interest in.
Scrum, then, has always felt like a solution in search of a problem.
Of the three aspects mentioned above, daily stand-ups I am generally in favour of. They are short so even if unproductive not very harmful, and they do provide a degree of team coherence, when everybody is -as usual- working on different things.
Anecdote: Once upon a time, long before I'd ever heard of a sprint, teams would send out weekly progress emails detailing what each member had achieved last week and was planning for the new week. One poor sod in a different team became a running joke for having the same 'finish N-Patch' status for well over six months. In the end he left the company without ever finishing it. At the time I thought he was just an idiot but now I tend to view the whole episode as a failure of pastoral care. He wasn't getting on with the people he was living with and obviously wasn't coping with his work. I suspect he was probably a bit depressed. He needed support and he didn't get enough of it. If the team had done daily stand-ups then the work issues would have been obvious and, hopefully, they would have stepped in (where his manager did not) long before everything got so bad. At the very least it would have made the problem much harder to ignore.
Until recently I was kind-of okay with story-points and burn-downs and velocity and all the rest. Accept that estimations are wrong, I thought, instead measure your actual progress toward a finished product and do not get snared by the beguiling false certainty of man-hours. But too many interminable estimation meetings have beaten it out of me, too many questions of the form: "but how much is a story point really?"
In any case I don't think I've ever had a burn-down that actually burnt down, never had a velocity that didn't hover about zero for sprint after sprint after sprint. We couldn't book the points till the story has passed QA and QA were always trying to catch up with something more urgent. By the time our work became urgent nobody cared anymore. It was only urgent because it was being released anyway.
Stories that fit in a sprint are rare beasts too. As a user I want to do X we would write, and then realise this was a months work at least and our velocity was going to be zero-zero-zero-one hundred! Gamely we would try and split it up but rarely ended up with anything better than As a user I want an X button, and As a user I want X to happen when I press the X button. And sure enough our velocity would transform into half-zero-zero-one hundred!
In the end we started writing stories from the point of view of the components. As a thingabob widget I want the doohicky service to support Z in order that I know what to prepare in order to begin X. And the whole thing became meaningless.
I guess it comes down to why do sprints at all? To deliver frequently make sense, but who are you delivering to? If it's QA then who cares? Certainly they don't. If it's a metaphor, delivering kind-of-atomic chunks of work to a golden master version, then adopting git-flow will give you all this without four hours of mandatory meetings every fortnight. If it's to check you're going in the right direction with a product owner, why only every two weeks. I've never worked anywhere where I wouldn't frequently wander over to the product owner, be she architect or saleswoman, and ask her to clarify what she wanted.
I've sometimes said that I've drunk the TDD Kool-Aid. It works. I've seen it work. I'm convinced. My attitude to Scrum has always been more circumspect. I bought the principles, was optimistic, but had never seen it really work. Now I'm embroiled in a second attempt to "Go Agile," at a second company attempting it, and I see all the same failings all over again, I'm forced to confront the possibility that the whole thing is snake-oil.
In seventeen years I've never been a part of a team building a thing for a customer who was remotely interested in getting updates every fortnight. About 90% of the time I've been in teams where we all worked on different parts of the same massive mature application (or family of applications). Most <air quotes>projects</air quotes> were coded by only a single developer, very few indeed by more than three. Most could only be released with a great deal of difficulty (sometimes having to navigate the audit processes of customers, and the limited resources therein) and were rarely done so more than once a quarter at the absolute most.
The one time I can recall building a new piece of software as a collaborative team, the customer was represented in the sprint reviews by our own support analyst and, when it came time to hand over some money, declined having never once seen what we produced. Far more often than not there simply was no customer beyond a products guy with an idea they had long since lost interest in.
Scrum, then, has always felt like a solution in search of a problem.
Of the three aspects mentioned above, daily stand-ups I am generally in favour of. They are short so even if unproductive not very harmful, and they do provide a degree of team coherence, when everybody is -as usual- working on different things.
Anecdote: Once upon a time, long before I'd ever heard of a sprint, teams would send out weekly progress emails detailing what each member had achieved last week and was planning for the new week. One poor sod in a different team became a running joke for having the same 'finish N-Patch' status for well over six months. In the end he left the company without ever finishing it. At the time I thought he was just an idiot but now I tend to view the whole episode as a failure of pastoral care. He wasn't getting on with the people he was living with and obviously wasn't coping with his work. I suspect he was probably a bit depressed. He needed support and he didn't get enough of it. If the team had done daily stand-ups then the work issues would have been obvious and, hopefully, they would have stepped in (where his manager did not) long before everything got so bad. At the very least it would have made the problem much harder to ignore.
Until recently I was kind-of okay with story-points and burn-downs and velocity and all the rest. Accept that estimations are wrong, I thought, instead measure your actual progress toward a finished product and do not get snared by the beguiling false certainty of man-hours. But too many interminable estimation meetings have beaten it out of me, too many questions of the form: "but how much is a story point really?"
In any case I don't think I've ever had a burn-down that actually burnt down, never had a velocity that didn't hover about zero for sprint after sprint after sprint. We couldn't book the points till the story has passed QA and QA were always trying to catch up with something more urgent. By the time our work became urgent nobody cared anymore. It was only urgent because it was being released anyway.
Stories that fit in a sprint are rare beasts too. As a user I want to do X we would write, and then realise this was a months work at least and our velocity was going to be zero-zero-zero-one hundred! Gamely we would try and split it up but rarely ended up with anything better than As a user I want an X button, and As a user I want X to happen when I press the X button. And sure enough our velocity would transform into half-zero-zero-one hundred!
In the end we started writing stories from the point of view of the components. As a thingabob widget I want the doohicky service to support Z in order that I know what to prepare in order to begin X. And the whole thing became meaningless.
I guess it comes down to why do sprints at all? To deliver frequently make sense, but who are you delivering to? If it's QA then who cares? Certainly they don't. If it's a metaphor, delivering kind-of-atomic chunks of work to a golden master version, then adopting git-flow will give you all this without four hours of mandatory meetings every fortnight. If it's to check you're going in the right direction with a product owner, why only every two weeks. I've never worked anywhere where I wouldn't frequently wander over to the product owner, be she architect or saleswoman, and ask her to clarify what she wanted.
I've sometimes said that I've drunk the TDD Kool-Aid. It works. I've seen it work. I'm convinced. My attitude to Scrum has always been more circumspect. I bought the principles, was optimistic, but had never seen it really work. Now I'm embroiled in a second attempt to "Go Agile," at a second company attempting it, and I see all the same failings all over again, I'm forced to confront the possibility that the whole thing is snake-oil.
Tuesday 1 July 2014
Fun with standards
This, as I understand it, is completely legitimate c99:
>$ cat main.c
#include <stdio.h>
inline void foo()
{
printf("inline\n");
}
int main()
{
foo();
return 0;
}
>$ cat outline.c
#include <stdio.h>
void foo()
{
printf("out-of-line\n");
}
>$ clang -O0 -c main.c -o main.o && clang -O0 -c outline.c -o outline.o && clang -o inline-test-O0 main.o outline.o
>$ clang -O2 -c main.c -o main.o && clang -O2 -c outline.c -o outline.o && clang -o inline-test-O2 main.o outline.o
>$ ./inline-test-O0
out-of-line
>$ ./inline-test-O2
inline
>$ cat main.c
#include <stdio.h>
inline void foo()
{
printf("inline\n");
}
int main()
{
foo();
return 0;
}
>$ cat outline.c
#include <stdio.h>
void foo()
{
printf("out-of-line\n");
}
>$ clang -O0 -c main.c -o main.o && clang -O0 -c outline.c -o outline.o && clang -o inline-test-O0 main.o outline.o
>$ clang -O2 -c main.c -o main.o && clang -O2 -c outline.c -o outline.o && clang -o inline-test-O2 main.o outline.o
>$ ./inline-test-O0
out-of-line
>$ ./inline-test-O2
inline
Wednesday 18 June 2014
Nice Languages Finish Last
I am writing things in Lua. Lua is a nice language, everybody keeps telling me so.
A very compelling use case for Lua is to use it as a scriptable configuration file. You can imagine how wonderful that would be:
Client wants to get configuration elements from the environment. They can already do that.
Client wants to get configuration from a different file with a weird proprietary format. They can already do that.
Client wants to use the most recent different file from a whole directory of them. They can already... Wait. They can't do that! They want to perhaps sleep for a bit and then check again. They can't do that either. You see Lua is a nice language and doesn't have a massive bloated API that can do everything. Python, Perl, or PHP could have done those things, because they are not nice.
They are useful.
A very compelling use case for Lua is to use it as a scriptable configuration file. You can imagine how wonderful that would be:
Client wants to get configuration elements from the environment. They can already do that.
Client wants to get configuration from a different file with a weird proprietary format. They can already do that.
Client wants to use the most recent different file from a whole directory of them. They can already... Wait. They can't do that! They want to perhaps sleep for a bit and then check again. They can't do that either. You see Lua is a nice language and doesn't have a massive bloated API that can do everything. Python, Perl, or PHP could have done those things, because they are not nice.
They are useful.
Friday 12 April 2013
Lessons From Working With Timezones.
I have been reviewing, and then when the reviewing turned up a load of pre-existing bugs actually fixing the damn things myself, a lot of code to do with handling timestamps. Here are some of the lessons learned.
Use boost date_time.
It's one of the boost bits that comes in a library rather than just a header file but don't let that put you off, it makes easy some things that were hard, and makes possible some things that were impossible. It is a good thing.
The rest of these rules will focus on the more prevalent posix types and functions.
Never put anything other than posix time in a time_t.
By posix time I mean time since midnight 1st Jan 1970 UTC, aka epoch time, or unix time, or timestamp. You will have a hard time persuading anything to treat your time_t value as anything else so just don't do it.
Never put anything other than the local time in a struct tm.
Effectively this means never calling gmtime. There is only one reason to ever call gmtime, and that is if you need to get a UTC time string, in which case don't keep the value around for any longer than it takes to create the string. Doing so is asking for trouble.
Anybody writing code that relies on being run in a particular timezone shall be taken outside and shot.
This should be obvious and strikes me as lenient, personally I would beat them with sticks until dead. Shooting's too good for them.
Anybody writing tests that rely on being run in a particular timezone shall be taken outside and beaten with sticks until they are sorry.
It may look like an easy and harmless shortcut but No, just No!
Never go near the TZ environment variable.
Oh TZ environment variable, how I hate thee? Let me count the ways:
- You are not thread safe
- You can be changed invisibly by other parts of the codebase.
- You are hard to clean up correctly.
- You do not even bloody work properly.
Yes, it turns out that Windows is, as you'd expect, expertly engineered to work in every location you can imagine except if you change the TZ environment variable, after which it will get the timezones right (but of course), but likely get the dates of change from standard to daylight saving and back again wrong. it will use the American dates, even when it is not in America.
Alter your timezone and check it again.
I have come to the belief that writing time-handling code in a timezone that coincides with UTC for half the year is an actual disadvantage allowing bugs to go unspotted. Now, whenever I go near it, I tell my dev box it is in Road Town.
The weather's better too.
Use boost date_time.
It's one of the boost bits that comes in a library rather than just a header file but don't let that put you off, it makes easy some things that were hard, and makes possible some things that were impossible. It is a good thing.
The rest of these rules will focus on the more prevalent posix types and functions.
Never put anything other than posix time in a time_t.
By posix time I mean time since midnight 1st Jan 1970 UTC, aka epoch time, or unix time, or timestamp. You will have a hard time persuading anything to treat your time_t value as anything else so just don't do it.
Never put anything other than the local time in a struct tm.
Effectively this means never calling gmtime. There is only one reason to ever call gmtime, and that is if you need to get a UTC time string, in which case don't keep the value around for any longer than it takes to create the string. Doing so is asking for trouble.
Anybody writing code that relies on being run in a particular timezone shall be taken outside and shot.
This should be obvious and strikes me as lenient, personally I would beat them with sticks until dead. Shooting's too good for them.
Anybody writing tests that rely on being run in a particular timezone shall be taken outside and beaten with sticks until they are sorry.
It may look like an easy and harmless shortcut but No, just No!
Never go near the TZ environment variable.
Oh TZ environment variable, how I hate thee? Let me count the ways:
- You are not thread safe
- You can be changed invisibly by other parts of the codebase.
- You are hard to clean up correctly.
- You do not even bloody work properly.
Yes, it turns out that Windows is, as you'd expect, expertly engineered to work in every location you can imagine except if you change the TZ environment variable, after which it will get the timezones right (but of course), but likely get the dates of change from standard to daylight saving and back again wrong. it will use the American dates, even when it is not in America.
Alter your timezone and check it again.
I have come to the belief that writing time-handling code in a timezone that coincides with UTC for half the year is an actual disadvantage allowing bugs to go unspotted. Now, whenever I go near it, I tell my dev box it is in Road Town.
The weather's better too.
Tuesday 9 April 2013
Different Ways Of Thinking
An engineer's mind is focussed on objective reality, it needs to be, it is the medium in which he or she works. When an engineer tells you they will do something it means they intend to do it, and believe they will be able to do it.
A manager's mind is focussed on subjective reality, it needs to be, it is the medium in which she or he works. When a manager tells you they intend to do something it means they agree it would be good if it were done.
When a salesman tells you they intend to do something, they are just making noises they think will make you happy.
A manager's mind is focussed on subjective reality, it needs to be, it is the medium in which she or he works. When a manager tells you they intend to do something it means they agree it would be good if it were done.
When a salesman tells you they intend to do something, they are just making noises they think will make you happy.
Monday 18 March 2013
How Code Reviews Lead To Crappy Code
I have finally figured out what it is about code reviews I do not like.
There is a lot to like about code reviews, they extend knowledge, they allow developers with little experience in certain areas to work in those areas with the confidence that any dumb mistakes they make will be caught, and most importantly, they genuinely catch bugs - often very nasty subtle bugs at that.
At other shops I have done reviews of the 'cast your eyes over this before I press commit would ya' form, and these were low impact and high value. Here we are having a real quality drive in an (I think successful) attempt to pull a legacy product back from the brink of becoming a bug-ridden mess, and are doing long, involved, line-by-line dissections of every commit.
Here is what happens, like any department anywhere, some people are better at the job than others. Always fond of a massive generalisation I shall divide this entire gamut of human ability into two sorts of people which I shall refer to as senior devs and peons. Quickly, I find, the department falls into the state where peons do most of the work and the senior devs review it. Senior devs would love to do the work themselves, and would do it faster and better, and would use things like Patterns, and Modern Language Features, and all the wealth of experience and knowledge that has made them senior; but they are too busy with their reviews.
Ahha, you might say, but peons code slower, and so produce less work to review, so it should even out, right?
Would this were so, but peon work is often poor, or more often sort of okay but with subtle errors and missing some corner cases. It gets sent back, with constructive criticism carefully worded not to offend, and then returns, with a few different errors, and cycles backwards and forwards, and becomes a mix of intents, of the parts where the reviewer has put her foot down and explicitly dictated a design (sometimes I think I should just copy and paste a diff into the review comments) and, and here's the rub, parts where she has not had the heart, or the patience, to criticise any further, and has allowed the peon to muddle through in their own way.
I didn't bother picking up on the stinky bits in the first review you see, because at that point it didn't work at all and a bit of a pong was the least of its problems, and I kind of assumed they'd go when the thing was rewritten to, you know, work. But they did not, and now, on the third cycle of the whole depressing business, it seems cruel to pick up on them, and with heavy heart I am forced to let them through because, stinky though they may be, I'm just happy that they work.
And so you end up with code which, while it contains no known issues, is just not very good; it is fragile, and has bad encapsulation, and the tests are close to useless, and frankly, it sucks. Meanwhile it has actually taken longer than it would have taken the senior developer to do the damn thing themselves, and they would have done it better, and they are wondering if the department wouldn't be more productive without the peon in the first place.
There is a lot to like about code reviews, they extend knowledge, they allow developers with little experience in certain areas to work in those areas with the confidence that any dumb mistakes they make will be caught, and most importantly, they genuinely catch bugs - often very nasty subtle bugs at that.
At other shops I have done reviews of the 'cast your eyes over this before I press commit would ya' form, and these were low impact and high value. Here we are having a real quality drive in an (I think successful) attempt to pull a legacy product back from the brink of becoming a bug-ridden mess, and are doing long, involved, line-by-line dissections of every commit.
Here is what happens, like any department anywhere, some people are better at the job than others. Always fond of a massive generalisation I shall divide this entire gamut of human ability into two sorts of people which I shall refer to as senior devs and peons. Quickly, I find, the department falls into the state where peons do most of the work and the senior devs review it. Senior devs would love to do the work themselves, and would do it faster and better, and would use things like Patterns, and Modern Language Features, and all the wealth of experience and knowledge that has made them senior; but they are too busy with their reviews.
Ahha, you might say, but peons code slower, and so produce less work to review, so it should even out, right?
Would this were so, but peon work is often poor, or more often sort of okay but with subtle errors and missing some corner cases. It gets sent back, with constructive criticism carefully worded not to offend, and then returns, with a few different errors, and cycles backwards and forwards, and becomes a mix of intents, of the parts where the reviewer has put her foot down and explicitly dictated a design (sometimes I think I should just copy and paste a diff into the review comments) and, and here's the rub, parts where she has not had the heart, or the patience, to criticise any further, and has allowed the peon to muddle through in their own way.
I didn't bother picking up on the stinky bits in the first review you see, because at that point it didn't work at all and a bit of a pong was the least of its problems, and I kind of assumed they'd go when the thing was rewritten to, you know, work. But they did not, and now, on the third cycle of the whole depressing business, it seems cruel to pick up on them, and with heavy heart I am forced to let them through because, stinky though they may be, I'm just happy that they work.
And so you end up with code which, while it contains no known issues, is just not very good; it is fragile, and has bad encapsulation, and the tests are close to useless, and frankly, it sucks. Meanwhile it has actually taken longer than it would have taken the senior developer to do the damn thing themselves, and they would have done it better, and they are wondering if the department wouldn't be more productive without the peon in the first place.
Subscribe to:
Posts (Atom)