> Please join me in my effort and do finish your projects.
Hear, hear. A friend and I hosted a "Finish it! Weekend" once (as opposed to a "Startup Weekend"). The idea was to get people together for one weekend and finish that last 10% or whatever of a project. Sadly we were the only two to show up. (And we both finished our projects, which suggests this might be a good kind of hackathon to host every six months or so).
Even though we'd never met and did everything via email, I still found it effective and built a site that made several hundred dollars and then sold down the track. Nothing lucrative, more than my hourly rate by hours spent.
Each night I did a tiny portion of the work:
- research keywords and write bullet points
- decide on domain, buy domain and set up hosting
- extend bullets to x paragraphs per page
- create site with nav and pages
- launch and paste in ad code
Each evening was about an hour.
MFA sites are a bit slimy and unfulfilling so I tend to favour other side projects these days.
Big monoliths are too useful to go away. Does emacs "do one thing and do it well?" No, it does a million things, some of them better than others. Nevertheless, lots of Unix guys use it.
The image just happens to have a text editor and a bunch of other useful utilities built-in.
Emacs looking like the antithesis of the Unix philosophy is only because the Unix nature is deeply embedded within it.
EDIT: Also: I might take part if the "Finish it" weekend takes place, provided my wife takes care of the kids long enough.
You've heard of Startup weekend, right? You spent an entire weekend working on something and then, come Monday you've got yet another project sitting on your plate that needs your attention. Now what?
I floated an idea by Steve Wainstead a while back for something we're calling "Finish Up Weekend." The idea is, take one of those projects that's part way finished and FINISH the damn thing! So, that's what we're doing.
Tomorrow morning around 9, Steve and I will be setting up shop at WIP and digging in to projects that we both want to make happen. No checking email. No checking Facebook. And especially, no working on projects for clients. This is all about YOU and that project YOU want to work on. Be prepared to show off what you finished!
We'd love to have you join us. Come on down and make something awesome.
Hope to see you there!
What gives this idea some mojo is it's an event. It's an incentive to set aside everything for one weekend to push the project over the finish line. And you're in the company of others with the same goal; this creates peer pressure to avoid distractions and stay focused until the end.
And the fact that projects are rarely "done", you just stop working on them at some point (hopefully a "good enough" point)
Mismatches include near total lack of reusability/composability, solo vs group effort, etc.
All analogies are flawed, some are useful.
Stories can evolve, plots get interwoven and some cut, its never finished until publishing maybe, and even then there can always be sequels.
Anyway, we could do this all day.
IoT will change all of that ;)
* (0.1) - Can sit on chair
* (0.1.1) - Chair holds person who sits on it
* (0.2) - Can detect person sits in chair
* (0.2.1-hotfix) - Reject fake 'sits'
* (0.3) - Determine weight of person sitting on chair!
> Not every concept needs an analogy to be understood if we
> can explain things using correct and simple language.
The analogy makes no sense. There's so many fundamental differences between physical objects and software that my eyes glazed over as soon as he started the carpenter rant.
Edit: That brings me back to the article. "Finishing software" just means we should act more like authors. Very hard to achieve when you think of the differences above.
Apparently not, but the analogy is completely valid for what is being compared. A chair is designed for a specific purpose, so imagine if it kept changing in ways which were out of your control and either unrelated to, or made it less fit for, that purpose.
The problem I have is with how the article is using the term 'finished' to mean 'functionally complete', which is causing unnecessary confusion. Porting to new platforms and fixing security issues should not alter how functionally complete an app is, only address problems which either interfere with that purpose, or with the purpose of other apps running on the same system.
Even then, the article still isn't about functional completeness, but feature creep, and perhaps in the process the dangers of not using the right words for what you mean.
Outstanding issues may exist for feature requests that I don't need, or for minor bugs that won't occur in anything but obscure edge cases that don't apply to the primary use case. I welcome high quality patches but otherwise have no interest in pursuing them.
You just can't look at a repo and discern its completeness in an easy way.
Also explain why you think it's complete.
Simply just not having in a commit in a year isn't a tell but it is concerning; I haven't come across tech stable enough that even very minor commits don't become necessary within even a few months.
If it's your personal projects though, I don't make that assumption.
I wish more software took that approach. Far too often software quality drops after a while as developers keep piling on the features.
This doesn't mean the entire project needs to be re-written. Often times, a simple note that says "compatible with Rails 4" would be satisfactory.
But if even the readme is not updated, that makes it difficult for me to put any faith in it. And unfortunately there are tons of projects like that on GitHub.
Let me give a counter-example. PriorityQueue is a data structure implementation published as a Ruby gem in 2005: https://rubygems.org/gems/PriorityQueue/versions/0.1.2. It has not been updated since, because it doesn't need to be. It just works. (It could use better docs, but even that would be a one-time change.)
Similarly, I have a gem that helps build searches with ORMs - https://github.com/nathanl/searchlight. It doesn't directly depend on any ORM, just the "chained method calls to build queries" interface that they implement. That means I don't need to update it when ActiveRecord or Sequel or Mongoid gets a new feature. Which means I commit far less often. I consider it feature complete and only make bug fixes, which should eventually stop.
At that point, it may look abandoned, but it won't be. Just stable. Which I consider a good thing.
But yeah, this happens all the time in this space.
Unfortunately, Rails APIs change a lot more than the time-trusted POSIX APIs.
"Rule #30: It is mainly the incompetent that don't like to show off their work."
Madden's remark is based on the specific environment he was involved in (NASA engineering); if you're surrounded by people who are good at their jobs and who know how to criticise constructively then there aren't many reasons to hide what you're doing other than it being a bit rubbish. I don't entirely agree with the idea that people who don't show things off are necessarily incompetent, especially if showing off your work means putting it under general public scrutiny (who can be very nasty), but there's a huge amount of value to be gained in getting feedback from your peers as early as possible.
 http://www.nasa.gov/pdf/293253main_62682main_jerry_madden_fo... (Non-PDF version: http://www.altisinc.com/resources/rules/ )
The all important point is a constructive team that knows their job. But especially in space project related development, you may be surprised to find managers who don't know much about software.
Or, they don't show it off for fear of the ungrateful comments that projects tend to get because they don't implement some feature, or there's some obscure bug that the author doesn't consider important, or haven't updated it in a while, and so on.
"if you are not embarrassed by the first version of your product, you've launched too late"
I'm sure there are many others, but these ones keep me shipping.
Well, other than never shipping at all, which is, of course, the point ;)
If you're shipping respirators, cryovalves, automated replenishment systems...
The trick is in threading the needle on this one. In my experience "shipping" doesn't need to be a binary operation. Seek out your early adopters as soon as possible, get your product in front of them, and take their (hopefully) constructively blunt feedback to heart. Ask them what's needed to make it truly usable for the rest of your users.
A first release must not be buggy. But it can have a limited set of functionality.
Imho, the real art of software development is to restrict the initial set of functionality and get that done, as quickly as possible (but not quicker), bug free (sic) and useful.
Yes, I shipped. Yes, it was shit. Yes, it got MUCH better after it got real-world use.
I think there's a lot of truth in this. I've been working on a video game on and off for the last year and a half. For most of the development time, I would agonize over every little detail and take weeks to implement even minor features, because I'm an Artist (TM) and genius takes time damn it. Finally, two weeks ago I said "fuck it, I'm just going to focus on getting things working as fast as possible and I'll make them good later." And I've never created content or implemented features as fast as I have in these past two weeks; I actually have a working demo, instead of just notes and an empty engine. None of it is what I consider "good" right now, but I know that it'll be good eventually.
This is exactly my problem with web-services (and software that auto-updates itself).
In practice, abstractions this powerful and flexible are almost impossible to create. For example:
- the Linux kernel is based around POSIX, which is a pretty good set of abstractions. But its API surface area is huge, and whenever users want to do something not in POSIX, the Linux developers have to invent a new syscall or stick more crap in /proc.
- Lua is an exceptionally well-designed scripting language and implementation, that satisfies tons of use cases while staying small. But it keeps adding features to address pain points of existing users. For example, Lua 5.3 added integer support. Users wanted it.
- zlib is perhaps the closest I can think of to a library truly being "done." And it gets away with this because it is perhaps one of the easiest abstractions to define and contain: a simple string->string streaming transformation that uses a roughly constant overhead of memory. That's pretty much as good as it gets!
There's also stuff like preset dictionaries and so on so string->string is just one part of the abstraction and isn't a full signature. Compression level's another.
zlib's also not competitive in many scenarios, so it's only "done" for limited scope.
1) Keep it fun. Sometimes you start working on something and a week later you realize it's not as great as you expected it to be. Maybe you are working on some game and you can see it won't be as fun to play as you thought, etc. It's fine, it's ok to stop working on it. Forcing yourself to work on it won't produce any good.
2) Start with well defined, small goals. Define v1.0 which would contain only the most critical features, ship it (even if it means simply tagging on git). There's something hugely motivating about completing things, no matter how simple they are.
EDIT. One more thing I'd add, when working on a side project, don't start thinking about how everyone will be using, how many thousands of github stars it will have, whatever. It doesn't even have to be actually useful, as long as you have good time and learn something on the way. I've worked on a few projects that I'd say are totally useless (such as https://github.com/GedRap/xs-vm ) but at the same time I see them as successful because a) had great time b) learned something new, even if it's some small details about a library or a language.
1) Usually getting something finished is a boring slog. You get the (you think...) brilliant idea phase when you're all fired up, then you get "this is really boring" phase when you're working your way through a thicket of problems, squashing bugs, finding new bugs, thinking you should refactor (you shouldn't, usually) and completion seems like an ever-receding goal.
2) Break big goals into smaller goals. Repeat recursively until done. Then do it some more, because you missed a few things. Sweat the small stuff, because when you glue it all back together and you've worked through phase 1 properly, the big stuff just works. (Or near offer, anyway.)
Keep the cognitive load low: small microprojects and problems, one at a time.
It's not unusual to have problems with phase 1. But it's also the difference between being a professional and being a hobbyist.
If you just keep starting new projects when you hit phase 1, you don't ship.
>>> You get the (you think...) brilliant idea phase when you're all fired up, then you get "this is really boring" phase.
In my experience, there are 2 kinds of 'really boring' phase. One kind, as you mention it, is the less exciting part of the work, be it writing docs, or some edge case bugs, etc. The other kind is when you discover that you largely underestimated the complexity, or saw some major flaws in the initial idea. Like I've mentioned in my previous comment, maybe you start working on a game and find out some major flaws in the gameplay and can't see it being a fun game to play anymore. While it's not always obvious which case you are facing, in the later case, in my opinion, it's fine to halt the project. If you don't believe in it, nothing good will come out of it.
>>> It's not unusual to have problems with phase 1. But it's also the difference between being a professional and being a hobbyist.
I guess it depends on what's the purpose of the side projects. If it's something you try to make a business of (passive income kind of thing), then yeah you totally should get a bit of extra will power to get it shipped. But if it's something that is done just for fun, then I wouldn't sweat it that much.
Problem - I can't draw. I have no idea what I'm doing. I am completely terrified of making some kind of horrible messy fuck-up non-art and...
To keep it short - it's all fine. I'm not Durer, and I sketched something that didn't look much like rope. But it was way better than I expected.
The takeaway: there's a kind of pain barrier with a lot of projects. You think "This is not working, it's not going to work, I'm totally wasting my time on it", and all kinds of other critical thoughts.
Then you keep at it, and often - usually - it all works out.
The one exception I've found is that if projects for other people feel stuck, there's often a good external reason, and it's possible that you're genuinely wasting your time on them.
But if it's a solo project and it's not working, you don't have to force that iteration to work. But if you keep pushing and iterating and changing, something good falls out. IME the intense frustration is often the sign you're on the way to a breakthrough.
... long before those thirty years, someone who thinks he is a great manager may take over the steering wheel (he or she). And things are ready to start from the beginning.
Im my group, we have another flavour of not finishing things: managing by whatever is in front of the managers mind and declare it highest priority. This is the best way to work hard all the time and get nothing done at all.
Well, we all read peopleware a long time ago, all except of the managers.
Anybody here, who has a good idea how to handle these traps?
Bane of my existence for the longest time. Eventually I learned to just ignore those managers. They're too chaotic to remember whatever I was supposed to work on for them anyway.
It is. I've had a few managers where everything we all tried to change change were fruitless. The only solution was to either antagonize until things got out of hand, or to ignore.
> I like to confront, discuss and get things improved
That's a good initial starting point. But I've also learned that there comes a time when expending any more of my own energy fighting such people is no longer worth it.
> incompetent managers
In my cases, it wasn't incompetence but rather character. You can have rational discourse with incompetent people. You can show them why they're wrong. You can't have a reasonable discussion with someone who's own mind jumps from high-priority to high-priority, wanting everything yesteryear but isn't willing to put in the actual resources to get things done.
I've dealt with too many managers like that to expend much energy on it anymore. Mind you, ignoring them should be a last resort, but given enough experience with such managers, you learn to quickly know when you're dealing with one.
I'd much rather spend my time making customers happy.
You have many good points. And they match my experience. I'll try with less persistence.
Programming is more like policy writing. Definitely not like carpentry.
Except for some basic UNIX tools, like grep or make
Is make a basic tool? I'm often surprised when I find out new features of make that I was unaware of. I feel like it's bigger than it appears to be.
So much of programming and administration is about managing dependencies, and make is the default tool.
Such a pity it has a shitty syntax.
Maybe it's just me but I never feel a software is finished. You can at least refactor it or add new funcionality, improve speed/readability/reliability until the end of time. It's like writing a book. You can always rephrase, add new characters improve the story, but you have to stop writing it sometime.
I think the projects at http://suckless.org have taken maintainability to a really inspirational level.
What does it even mean to "finish" a program like 'ls' given the increasing complexity of filesystems with time?
But at the same time, consider things like UTF-8, localization, etc. They appear at the least expected moment and someone has to do something unless the tool becomes useless.
I understand you get the idea, though.
It may not apply to you however, I have been lucky enough to be surrounded by some very well disciplined developers who make a point of finishing a lot of what they start to varying degrees of success.
I found its Windows support rather broken -- failing test cases. Strange lockups.
I do not see Martin working much on those these days. Does anyone know how untangle those state machines besides him.
For much software, being finished is actually a kiss of death, because it is expected to keep improving and putting out new revisions. So "finished" is regarded as a synonym for "abandoned".
"Finish your stuff" for that kind of software is a poor directive. Rather, it should be, "before each release, get your stuff into a state of completion whereby everything that is documented is implemented and vice versa, and the quality is good (bug-wise, etc)".
Lines I found insightful:
"... make it functionally complete in the first place.
... If it can't be made functionally complete it's too big. You've tried to bite off a piece that's bigger than you can swallow. Just get back to the drawing board and split off a piece that can be made functionally complete."
I really like the idea of splitting a project into phases. You might have Three phases, each one building on the last, but the very first complete phase should be a complete and usable thing in itself.
First the skateboard, then the scooter, then the bike, the motorcycle, and finally the car.
I've always found this metaphor incredibly amusing, because, to me, it actually highlights the _problems_, rather than advantages, of the iterative approach. At every step of the process, you're not only increasing complexity, you're also pivoting your product to the point where:
1. your previous clients are unlikely to still be well served by the new product, and are likely to churn as a result
2. the engineering challenges are different enough that most of the components aren't really reusable, and trying to shoehorn one stage into becoming the next will give you a sub-par product.
Sorry, just had to =)
Just not seeing it.
When Java was first becoming popular, I recall emphasizing how important it was to use the standard, well-documented, well-tested java.lang.String, rather than a custom String class as had been done in C++. Application domain experts started asking about strings that didn't fit in RAM (documents).
A great, tested component in one domain may require a significant redesign in a domain with other requirements.
Analogy wears thing because a tyre is a standard off the shelf thing. In software everything that is interesting (and requires employees) is custom to some degree. So it is like a tyre for a rover on the moon.
However no need to get that to also work for a scooter on pluto! Unless the sales guy has already promised it!
So, they do the work for free, and updates as long as people keep using it?
Much of the stuff in the OpenBSD base.
thttpd also comes to mind.
Never finish your projects (unless you're just doing homework). Software is a system. Systems of any non-trivial complexity are living things that must adapt and evolve. Constantly.
(Also, there is absolutely nothing wrong with abandoning a project. Gain as much as you can from your experience and quickly move on to something better / more meaningful.)
This might be true for large and broadly scoped projects, but for small Unix-style modules/tools it isn't always the case.
To use real-world examples, see point-in-polygon and robust-point-in-polygon. The tools are both "finished" and any further API scope/modifications would be harmful to the software that has come to depend on them.
They could forever be improved in documentation, discovery (i.e. a website), etc but at a certain point it is better to place your effort into new tools.
1. The statement of your (minority) opinion as an undeniable fact.
2. Your needlessly hostile tone to anyone who dares question or disagree with #1.
(not least if you consider the actual contents of the linked article, which makes it clear that by "finish" he means to make it functionally complete, not to stop fixing bugs or e.g. ensuring it still compiles)
Define 'improving', because there have been quite a few major projects that have been getting 'worse' (slower, buggier, less secure, more bloated, breaking changes, feature creep, inconsistent documentation) as time goes on. So what exactly are we prioritizing?
Wintel conquered the world by maintaining backwards compatibility. These days the majority of 'improving' seems to be for getting around breaking changes introduced by others and making unnecessary UI changes. Reliability and consistency is not a priority anymore. Instead no software can ever truly be finished because the assumptions under which it operates change unpredictably and inconsistently.
I mean really, once you finish something like a file renaming utility, what else is there to do? If it stops working due to changes made by someone else, then it needs to be updated, but that isn't improvement. If on the other hand it's working as intended, then the only way to further improve it is by changing priorities. Engineering is all about tradeoffs, but priorities are now being driven almost entirely by cultural forces, and I've seen this render working software inoperable for no other reason than it didn't fit the fashion of the time.
Reality doesn't change to the point that a chair, or even a microprocessor, stops working. Software on the other hand does, and if the platform you're targeting isn't stable, then you can never finish a project, let alone improve it. And this 'no updates' = 'dying project' philosophy is a big part of the problem, because it forces developers to unnecessarily update a project just so people believe it's relevant, while the only metric we should be using is that the software is fit for the purpose we use it for.
Sometimes, genius strikes and you get something so precisely thought out and so well executed that it lasts for generations.
Still, I'd have to answer your question in the affirmative. The original TeX is quite dead indeed. It (and the ecosystem around it) have evolved significantly over the years and continue to evolve as we speak, so it is far from finished.
"We want to design a simple rocking chair for a sweet elderly couple." becomes "We need to make enhancements to this chair to equip it with an ejection seat suitable for a fighter pilot in a jet. No, you can't start over either, there isn't enough in the budget for that."
With git, github and software managers pulling directly from it (although a decentralization way could be even better), I wish we get more often software by hash so we stop worrying less about copping with new changes and more about doing what matter to us.
But, then, who wants those kinds of users, right?
Thanks for the article.
What never works is when I start building an eternal software edifice. My name is Ozymandias, king of kings...
Finishing your projects is good advice overall though.
After 30 years of programming, you'd better be a pretty decent programmer. And maybe that's why their projects take less time to complete.
A basic memoization algorithm type questions or 'tell me about a time when you...' and I choke every god damn time while a fresh graduate with a CS degree breezes through it.
I don't spend time on any of that when I'm working on a problem, it's important for me to build something that just works first in order to meet project deadline and then optimize afterwards but I guess this is not good for an employee point of view since they want someone who is more focused on producing code over product functionalities and features. At that point it would be useless if you've built something they can't look at the code (why the hell should I reveal proprietary information?).
So basically I find myself with the ability to finish but unable to be hired as an engineer as I lack CS and experience writing code in an office environment. Contrary, finding freelance projects and landing work has always been far more easier, and I can maximize my value for my client and also myself, since it is tightly coupled to the ability to complete projects on time and solve problems. Pushing back deadlines because of disagreements over code formatting or technology choice is not how I want to spend my time.
That might be because they know that afterwards never comes.