I thought the Unix philosophy embraced the idea of "small tools that do one thing really well."
> 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).
I searched my old emails and indeed we called it "Finish Up Weekend." It was held May 10, 2013 at Work In Progress (in Las Vegas). I'll credit John Hawkins (9seeds.com) with the name.
I did something remotely similar with a guy online - we set a schedule to each launch a monetised microsite within five days and 'keep each other honest' (e.g., not get lazy and do nothing each night). The plan was that each morning we'd check in and show progress - only allocated an hour each night. The pressure would motivate us to see it through.
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.
Two-keyword domain, Adsense-monetised, 5-6 pages of content I wrote myself. Location-specific.
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.
> I thought the Unix philosophy embraced the idea of "small tools that do one thing really well."
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.
To expand on this, each elisp package tends to do one thing and do it well. The majority of my Emacs workflow is basically just a bunch of small, single-purpose elisp programs that get used alongside one another.
Emacs looking like the antithesis of the Unix philosophy is only because the Unix nature is deeply embedded within it.
The original description we emailed around is probably best:
[snip]
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!
[/snip]
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.
Am I the only one that really hates the carpenter analogy? As someone who does woodworking on the side of my programming, there's a million reasons why it's a terrible way to think about software development. The chair doesn't have supported platforms, new security issues, or the need to be updated so that people keep buying the same chair. Someone else isn't going to have to come along later to maintain the chair and have to be knowledgeable about the specific tools that the chair was built with.
I think creative writing can also be a good analogy, for the reasons you state and also it seems closer to me since we are authors of the code we write.
Stories can evolve, plots get interwoven and some cut, its never finished until publishing maybe, and even then there can always be sequels.
* (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!
...
Taking this to the next level: I come across people all the time that put tremendous effort into building similes for... everything. Not every concept needs an analogy to be understood if we can explain things using correct and simple language.
I think something like an airplane is a much better analogy, as it is a complex system in a constant state of flux. It requires constant maintenance and has to comply with ever-changing FAA rules and regulations. It has to adapt to changing routes and distances -- it might be retrofitted to hold more fuel, or redesigned to burn less. During its lifetime, it will undergo several cabin reconfigurations, and will likely be completely rebranded more than once as it changes ownership. It will live through various versions of seat-back cell phones, overhead entertainment systems, seat-back entertainment systems, WiFi, foot rests, tray tables, and power outlets. And after decades of constant changes, it will be forcibly retired. Like software, it won't be retired because it no longer works -- it will just be EOLed because it's old, and something newer and shinier has come along.
Also, there's no versioning. It's not possible for anyone to create a copy of a chair at any point in its history, virtually for free.
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.
Carpenter analogy is as bad as the "book author" analogy. You write a book and let it go. Nothing to support, all updates are to be paid by customers in a new release.
"Book author" is at least closer to the truth. There are editions and old copies floating out there, it's hard to estimate completion dates, and authors have many of the same copyright problems. The difference is that software must live in a dynamic and shifting 'house' where everything gets rearranged by vendors, probed for weaknesses by attackers, and new features are constantly demanded by the users. Solutions to all of this are tacked on as an endless stream of appendices. Throw in patents for extra insanity. Both analogies strain to fit this reality.
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.
Some books do have versions (textbooks et al), some books are out-of-date as soon as they are published (statistics, science). Many would benefit from a reduction in lines and becoming more concise. Some are a jumbled mess that's basically useless, but nobody wants to update them.
The analogy is perfectly valid for the point he's making. You seem to be confused about what the author is saying. "Finish your stuff" does not mean "Never Improve". Security issues or additional features have nothing to do with finishing a project.
> Am I the only one that really hates the carpenter analogy?
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.
Don't forget that a programmer's work is not really like making three of the same chair either. Maybe if every single thing the carpenter made was a highly customized bespoke piece.
I find it irritating when people look at some of my projects on Github and consider then "abandoned" because they haven't had any commits in a year or two. They're not abandoned: they're finished. They do what they're designed to do, and I use them regularly.
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.
See I never assume a project is abandoned unless there are open issues regarding bugs (or possible bugs) that the owner never commented on. That combined with commits a long time ago is usually a pretty good tell in my opinion.
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.
I have several projects that haven't been updated in more than a year which are still maintained in the sense that if there are bugs, I fix them. They are rarely touched for a simple reason: They do what they're meant to, and they still work.
I wish more software took that approach. Far too often software quality drops after a while as developers keep piling on the features.
Let me give a more concrete example: if something was developed in Rails 3 but was not updated for Rails 4, then I assume it won't work (I'm on Rails 4.1).
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.
That's a fine example. It has dependencies, the dependencies change quickly, so the project needs updating.
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.
Maybe your README intro should communicate this? Most of us are not accustomed to something on Github being "finished", so a project where there aren't current commits is unsettling.
There's a great list of project management advice by Jerry Madden of NASA that gets posted here occasionally[1]. One of the points is;
"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.
There are other important reasons not to show things before they are done:
one is the impatient group member who rather refocuses a development than to wait until it converges to something usable. It takes a lot of experience to make a realistic guess, how long software projects take. It also takes a lot of experience to put progress reports in a way that it always looks like great things are happening in order to avoid the refocus discussion.
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.
I'd say it is a better idea to show something finished (or if it's too big, a part of it that it finished). Because if it's not finished, those who look at it will have hard time to understand where you are, where you can go and thus they'll have hard time making a good review of it, or worse, they'll associate the unfinished stuff to your incompetence, lack of vision, lack of will, whatever.
There are also simple human flaws that prevent people from showing off their work, such as lack of confidence and fear of failure (failure in succeeding). They tend to falsely be perceived as extreme modesty, too.
> "Rule #30: It is mainly the incompetent that don't like to show off their work."
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're embarrassed by the first version of your product (i.e. suppose it's buggy, or is lacking in it's UI) then it's probably not ready to ship? There is nothing worse than shipping a half-baked product.
Somehow I doubt you or anyone else here is shipping respirators and cryovalves as side projects, and even if so, the context here is clearly web and infrastructure software.
There's a set of tradeoffs here. 1) You really, really need feedback from your users as early as possible, to help keep you on-track. 2) Shipping something truly half-baked can kill your chances with most of those users.
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.
"If you're embarrassed by the first version of your product (i.e. suppose it's buggy, ..."
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.
No, I (sic)ed 'bug free', because this is a goal that may never be achieved. I want to say "try as hard as possible" but did not want to look like I think it actually IS possible.
I thought there was some confusion about who the credit for the quote went to. People weren't referring to Reid by name. The link was simply the first Google result that I clicked. Random.
It depends on how high your standards are. If you're a perfectionist then you're going to be forever embarrassed. Meanwhile the general public finds your product to be perfectly usable and useful, because they aren't running into any of the bugs that exist.
There are a lot of things, like say your competitors eating your lunch. If someone comes along and sort of satisfies the need it's easier for them to get people to upgrade than it is for you to come along later with a more polished product and ask them to migrate.
Depends on how much lock in your product has. Often an early releaser ends up creating a market and then a competitor comes in and releases a much more polished product and everyone jumps ship.
>"if you are not embarrassed by the first version of your product, you've launched too late"
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.
> You bought a damned chair and you want it to remain a chair, not to find out that it's some kind of protean piece of furniture that's a chair today and partly a table tomorrow and, who knows, maybe you'll be able to humidify your cigars in it next week.
This is exactly my problem with web-services (and software that auto-updates itself).
Every software is like this to some extent. The more external stuff they link, the more affected. Even if something doesn't auto update, eventually you'll have to update to the latest version because certain functionality will no longer work the way it should. Sure, you can fork it, but many software projects take more than one person to maintain.
The only way to "finish" software in the way the author describes is to find or invent an abstraction that is exceptionally powerful and well-designed. It has to give users what they want for a multitude of different use cases without requiring the library to grow to accommodate those use cases.
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.
In my own experience, I found the following 2 things being the most important:
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.
I learned a lot from a beginner's art class a long time ago. The teacher threw some rope on the table and said "Here - draw this."
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.
"Lately, after 30 years in the programming business, I've finally managed to cut down my projects to a reasonable size."
... 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?
> managing by whatever is in front of the managers mind and declare it highest priority
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.
Ignoring seems to me like the secret weapon of the powerless. I like to confront, discuss and get things improved. But it is so hard to get incompetent managers up to speed, if they lack years of experience.
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.
Just an aside on the carpenter metaphor, there's sort of a running joke that a carpenter's house is never finished. It's not just the software profession that has this problem.
But as the carpenter goes on doing his stuff, the things he did stay put. They do not suddenly become incompatible with each other, or need to be maintained daily. Carpentry is orders of magnitude less brittle. It doesn't even compare.
Programming is more like policy writing. Definitely not like carpentry.
I can't think of a piece of software I wrote and feel finished, not because I abandoned them, but because I stop improving them when they are good enough for the task.
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.
In the end though, readability/maintainability end up being at odds with features/speed. I like to think about the hypothetical programmer that has to take over my project ten years from now. Is the value of a new feature worth their pain and suffering? Is my project going to be too painful to keep alive?
I think the projects at http://suckless.org have taken maintainability to a really inspirational level.
The semantics of POSIX dirents haven't really changed, and any file system complexity is abstracted by the kernel's VFS subsystem to provide generic data in all cases. So, yes, it is possible for something like 'ls' to be finished, or at least for really long times.
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 caught myself thinking the same thing, however if you compare software to a physical product the importance of the analogy remains intact.
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.
The only software that gets truly finished is embedded firmware for small devices, which is done when it is debugged and covers all the conceivable use cases, and development stops. (The firmware may still generate new descendant code, but users have to get new hardware to get that code.)
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)".
A couple times today, I found myself in the middle of something and came back to HN to procrastinate. I saw the Finish Your Stuff headline and left to finish what I was doing. I need to have a little banner on top of my computer that says "finish your stuff"
You may find noprocrast feature on HN settings page useful. It is a polite reminder that tells you to go back to work. You can adjust how many minutes you can stay at HN (maxvisit), and when you can come back (minaway).
The iMatix guys have been amongst my heroes since they released Libero (state machine code generator) and built Xitami on it (both mentioned by Hintjens as "finished" projects in a comment to the linked article) back in the 90's...
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.
> 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.
It's not about incremental development, it's about passing the baton. The spirit is motion/movement/transport, and the corresponding vehicle should be a natural expression of that with your available tools. Who said that the goal should be product-oriented? If I want to reach Alaska I will gladly take whatever transportation suits me best at the time. If I were insistent that my tank was clearly the most capable vehicle, although I would eventually get there, it would not be as enjoyable, imho.
Probably it should be build the tyre first. This is a functionally complete thing that can, along with many other functionally complete things be composed into the car.
Car built with scooter tires... Scooter built with car tires...
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!
Coding is a conceptual art-form, it's not about building a car with scooter tires, it's about upgrading vehicles to get the end result in a workable fashion. Try using spark plugs and pistons to get somewhere!
No, you miss so much when you try to make a component you think will be useful. The first piece must be something that makes someone's life a little bit easier - that's the only way to be sure you're making something actually useful.
Aside of it being convenient for users, keeping the components small is good for the developer as it tends to tame the complexity to the acceptable level.
Right, and even the use cases for software can change in such a way that it can influence the entire architecture.
"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."
In which case perhaps the reasonable solution is for you to get a different type of chair, rather than trying to modify your old chairs to fit the changing requirements.
Yes, but now we've clearly abandoned the familiarity of the analogy, making it less clear how much value the analogy has in illuminating what we're trying to say.
Yeah, it's hard to have a productive life with always moving targets.
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.
I'm 5 years into the programming business and my own projects are just starting to get into a usable state in a reasonable amount of time. Finishing things feels a bit further away still.
I currently approach it from the "cyclical" time-management model. I'll know that things are never finished, but what I can do is finish a sketch of a broad system, or a detailing of a smaller portion, and return to it later. Repeating that a few times gets very powerful results.
What never works is when I start building an eternal software edifice. My name is Ozymandias, king of kings...
This is the sort of wisdom that's really hard to pass on. I've learnt this from experience, and many other have. But when we try to pass this on to new programmers, the message never quite reaches them until they've learnt in by experience.
Run of the mill software exhibit life cycle patterns more like a small animal. It starts out all nimble and has to grow and change over time to become an adult of its kind; then it eventually dies.
Finishing your projects is good advice overall though.
I like this idea, but I'm not sure it's realistic. Constraints change all the time, just like your users' needs. In principle this works, but I'm not convinced that everything should aim to be finished.
I'm at the last 10% of a screencast script; there's two more phases after this but for some reason my productivity on the project has slowed to a crawl. I'm not sure how to overcome this feeling.
If you think "giving up" on a project is easy. Try "giving up" on your "dreams", those project you work on every day, even though you know you wont make it.
But its so hard! :) my strategy is to have many 3-9 side projects on at any one time, each is really just practice and I judge the concepts based on how often revisit them.
If you look at his progression, a lot of it is also about shaving down the size and complexity. E.g. the AMQP -> 0mq -> nanomsg chain which is a journey of cutting complexity.
I don't know, lot of interviews I've been to in the past doesn't seem to value the fact that I spent almost 4 years of my life working on a single project (which will never be finished but pretty damn good by now) or that I've been selling and supporting customers with it.
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.
"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"
That might be because they know that afterwards never comes.
This is absurd. A finished project is a dead project. If it isn't improving, it's dying.
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.)
> A finished project is a dead project. If it isn't improving, it's dying.
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[1] and robust-point-in-polygon[2]. 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.
I disagree, based on personal experience. I have a few projects no longer in active development, but I use them frequently. They do what they are supposed to, they don't break down and require no maintenance other than changing the expiry date on the credit card associated with the hosted account every few years.
By that token a substantial proportion of the tools I rely on on a daily basis are dead.
(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)
> A finished project is a dead project. If it isn't improving, it's dying.
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.
You had to fish hard for this example, didn't you?
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.
> 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).