9 ms·
Minimal Viable Programs (2014)
- kejaed 7y ago“I really like systems that do one essential thing and do it well. Good examples are Dropbox and Twitter. Dropbox just works. Twitter has a no fuss 140 character tweet box. Simple, easy to understand and minimalist.” They used to... Maybe even when this was published in 2014.
- TeMPOraL 7y agoYup. This remark made me search for the publication date. Yes, Dropbox did one thing and did it well... 5 years ago. Today, not so much.
- coleifer 7y agoAnd yet when I expressed a negative opinion on dropbox "Paper" I was downvoted into oblivion. Same happened when I was critical of antirez "disque" project, which is abandonware now. Part of HN seems breathless about new and shiny, and others seem to like this kind of "Unix philosophy" minimalism. I guess it's just a matter of taste at the end of the day?
- antirez 7y agoDisque is not abandoned fortunately! I'm in the process of porting it as a Redis module. It was not viable to continue it as a fork.
- branweb 7y agoThis is a useful concept. I also thought these lines were insightful: New features mean new sales opportunities, good for the company but not good for the user. The problem with adding features to MVP is that when we ship more complex products like complete operating systems that are packed with programs, the complexity of the individual programs contributes to the complexity of the whole. Not sure how to solve that particular problem though. This made me think of a blogpost linked on Hacker News when Joe passed away: https://github.com/lukego/blog/issues/32 https://github.com/lukego/blog/issues/32. This part seems relevant here: Joe wrote amazingly simple programs and he did so in a peculiar way. First he wrote down the program any old way just to get it out of his head. Then once it worked he would then immediately create a new directory program2 and write it again. He would repeat this process five or six times (program5, program6, ...) and each time he would understand the problem a little better and sense which parts of the program were essential enough to re-type. He thought this was the most natural thing in the world: of course you throw away the first few implementations, you didn't understand the problem when you wrote those!
- klyrs 7y agoNeat. That's essentially how I program, too. Early history in some of my git repos has the pattern git add program ... ... #first implementation works; time to rewrite git add newprogram ... ... #second implementation works; bury the first git rm program; git mv newprogram program ... This keeps my directory relatively clean, as I only have my previous attempt and the current refactor around at any given time. It also keeps the git history clean for the living files, and keeps the diffs nice and tidy.
- newnewpdro 7y agoExcept that way there's basically zero semantic continuity between the commits of the old program and rewrite. It's preferable to work in branches and rewrite and refactor incrementally whenever possible, merging the new code in as things progress at convenient milestones. Then the history documents which functionalities in the old implementation became what files and lines in the new implementation. That information can be very helpful when the rewrite breaks previously working functionality and customers are upset, especially if the rewrite authors aren't even around anymore.
- klyrs 7y ago> Except that way there's basically zero semantic continuity between the commits of the old program and rewrite. That's the goal of this practice. Throw it all out and rewrite from scratch. > That information can be very helpful when the rewrite breaks previously working functionality and customers are upset, especially if the rewrite authors aren't even around anymore. I'm talking about writing non-releases. The entire structure of the code, algorithms, data structures, API / CLI must not be preserved. Anything that stays constant between non-releases is either (a) a good idea or (b) a stone unturned. Rename variables, split and join modules, violently reorder function arguments... nothing is off-limits. After I've been through a few rounds of this, the first release should be entirely free of inessential warts (and maintenance is typically quite easy at this stage). After the first release, I'm a stickler about backwards-compatibility and my development pattern is closer to what you're suggesting. Among folks who know me, I've got a reputation for writing clean, optimized code. It isn't because I'm good at writing clean code; it's because I'm good at throwing away ugly code and I'm very reluctant to share code that doesn't meet the bar.
- JimmyRuska 7y agoThings are becoming more like the unix philosophy, modular and shared. Even though feature creep is increasing on modular systems, as long as the core components are simple to understand and introduced first, extra features do not necessarily decrease utility. For example tmux, if you look at a cheat sheet you might be overwhelmed, but when I teach people to use it they find it extremely simple. I just tell them ctrl-c to create a new window, and ctrl-w to switch windows. They only need 2 commands to get value, even though there are hundreds of features, and later they can incrementally learn about them. This is the same way I learned programming, the people learn emacs and vim. You start with the MVP feature set that will make it functional and you learn about features from there. Even AWS, Google Cloud, Azure, even though they're mega services of now insane size and feature breadth, they're creating single services that are easy to understand and compose together. You don't need to understand a lot to copy files in and out of AWS s3 for example, and you can compose many services together even after a basic understanding. You can slowly learn about more features as you work. In the future, things like apache arrow will also help as you can retain services as modular but potentially share memory when composing services. This idea of service composition is also common in Haskell and other functional languages, where if it's possible to do lazy evaluation you can avoid redundant work. Now that the unix philosophy is being more widely adopted, although renamed to microservice fundamentals, these ideas of lazy evaluation and protected data sharing probably be the next level of services research.
- gerbilly 7y ago> Things are becoming more like the unix philosophy, modular and shared. I sure hope you are right. Just look at kubernetes which wraps UNIX in a big complicated opaque 'opinionated' wet blanket.
- weberc2 7y agoKubernetes is the operating system in this analogy, and it’s quite a modular operating system at that. Specifically, it schedules the programs that themselves should adhere to the Unix philosophy. I don’t think the Unix philosophy ever extended to the OS (although microkernels seem to be driving in that direction).
- kiba 7y agoHuh. I had my own definition of Minimal Viable Programs: code that demonstrate how to do X, and only X. I found that tutorials often had unnecessary amount of complexity to show people how to do something, like encumbering an example with classes, title setting, etc, none of which is essential to the operation of the program and which makes it difficult to understand and learn. So, if I found a working example, I would strip the example down to its most essential until I cannot take away anymore without it ceasing to function. Maybe I should call it minimum viable examples instead.
- oftenwrong 7y agoA bit like https://stackoverflow.com/help/minimal-reproducible-example https://stackoverflow.com/help/minimal-reproducible-example
- mankyd 7y agoThis always becomes a tricky debate. Take the `ls` program. MVP would just by `ls`. Or maybe `ls -la` to get all the details. You could theoretically pipe that into other programs to get more information. But I'll be damned if I don't use `ls -lah` because I am a human, not a robot. `ls -1` is also super handy. I am sure there are lots of others that folks use. So where do you draw the line? It makes way more sense to include a few extra options in your tool rather than requiring your users to jump through extra hoops to get something _they_ find useful. edit: On the other hand, you don't need to include the kitchen sink, either. I have seen programs with literally hundreds of long-form command line arguments. It's a nightmare to wade through.
- avmich 7y ago> But I'll be damned if I don't use `ls -lah` because I am a human, not a robot. I'd prefer that '-lah' be an external composable modifier. 'ls -la' looks like it is, I think, because it tries to create simpler common case, for the expense of that case be more specialized. Since, as somebody decided, 'ls' by default contain only some information available, one presumably needs 'ls -zz' (a made up option) which would produce all information available, and a composed to it filter which would select what is needed at the time. If composability would be really cheap, we wouldn't need that special '-zz' option. We can even consider an option as a composition of additional operation over generic 'ls' behavior - in this case we wouldn't need the shell 'pipe' operator, and syntax of shell statements would become closer to Haskell's. For example, 'cat' could do something generic by itself, while 'cat note.txt' would be considered a composition of 'cat' and 'note.txt' which creates a specialized behavior (which sort of reminds Forth).
- sgt 7y agoI'm aware of "h" but never really had an issue determining that e.g. 1144623161 means 1.1G. I guess I recognize the actual length of the group of digits and then my brain splits it up backwards into 161 623 144 followed by a a 1.
- lou1306 7y agoThe flags you talk about are mostly about the presentation of the output. The, shall we say, "business logic" of `ls` is still pretty bare-bones. That could be one way to draw a line. Also, I think these presentation/formatting flags are a consequence of the Unix shell "everything-is-text" paradigm. In Powershell, where you pass around structured data rather than text, typically you handle presentation just by piping into the appropriate cmdlet.
- janpot 7y ago> A minimal viable program is the smallest program that solves a particular problem. It is small and beautiful. It has no additional features. Yet, when a node developer creates left-pad...
- weberc2 7y agoI don’t think this extends to libraries, which are units of composition and each unit comes with a more-or-less fixed amount of overhead for managing the trust relationship with the maintainer (as well as other things, like managing the version to pin against, etc).
- dragonwriter 7y agoThere's two problems with leftpad: (1) Dependencies always add certain minimal level of complexity, so a too-trivial dependency can add more-than-warranted complexity as a dependency even when the implementation itself would not do so as an integrally-maintained component of the larger system. (2) the nature of the npm distribution ecosystem (and this is by no means unique to npm) means that the complexity and risk added by dependencies managed through that ecosystem is more than it otherwise could be with immutable, append-only repositories of dependencies.
- thinkingkong 7y agoWhat's an example of an immutable, append-only repository of dependencies? That _sounds_ intriguing but I don't follow.
- all2 7y agoMaybe like C's `include`s? Where (I think) the code is in-lined without modification? The include is immutable (unless there are macros). Append only sounds like the included code should be evaluated after other code in a given file (so main defs would take precedent over included defs? Or main defs would be over-written by included defs... I guess it depends on compiler/evaluator implementation. The more I type here, the more I realize how much I don't know about this stuff...
- vanderZwan 7y agoTangent: I miss Joe Armstrong. I never even programmed in Erlang but I just enjoyed watching his contalks and the interviews he held with other people so much.
- brunojppb 7y agoGood software is written like this. Joe could not be more sharp on that. I did the exact same thing at my current company. I created a ticket system integrated in Slack where employees can quickly open a new issue and put a tag on it. A ticket is created in HelpScout where out IT support team follow up. Works 100% of the time and had zero downtime so far (around 2 years on production). No need for new features. It just works.
- gglitch 7y agoI’ve been interested in shell scripting lately and I have to admit that I posted this not because of Joe’s high-level observations on minimalism of architecture, but because of his discussion of a tiny, shell-based system his team used for ticket management, which reminded me of this shell-based notepad posted a few days ago: https://news.ycombinator.com/item?id=21416338 https://news.ycombinator.com/item?id=21416338
- wodenokoto 7y agoTFA made me think of this recent similar post: A static site generator using make, shell script and pandas, in about 150 lines including templates. http://stephenbalaban.com/static-site-generation-in-50-lines-of-code/ http://stephenbalaban.com/static-site-generation-in-50-lines...
- vector_spaces 7y agoI think you meant Pandoc rather than Pandas?
- wodenokoto 7y agoYes I did. I wanna blame autocorrect but I’m afraid it was probably some sort of Freudian slip
- opportune 7y agoGreat post. I think this also ties into configurations. It is so annoying when getting started with a new tool requires reading through a ton of documentation and then making a big configuration file just to get it to work. Adding features can be great but adding cognitive overhead isn’t
- kyberias 7y ago> If you want a job done find the busiest person you know and give them an extra job. This is because the reason they are busy is that lot's of people want them to do things because they are good at doing things and that's why they are busy. Oh man... that is so accurate it hurts.
- NicoJuicy 7y agoOh man, you know what happens right. Management wants 1 issue at a time/person. So they just mention the next task in person, that you are not allowed to create on the board. Lol :-(
- mc3 7y ago1 issue "in progress" might make sense, but 1 issue in total seems weird.
- WrtCdEvrydy 7y agoYou know you became that guy when you get your own swimlane... bonus points if there's a list of items that last at least 3 months there.
- r3dk1ng 7y agohttps://news.ycombinator.com/item?id=5920732 https://news.ycombinator.com/item?id=5920732 most minimal viable program
- skybrian 7y agoThis happened to work because all the users were programmers who were already familiar with the command line, text editing, and the CVS tool, and they had already been granted access to their source control system. It wouldn't work for the general public. Maybe the lesson is to figure out your minimum viable audience and build on the tools they already know?
- nimvlaj30 7y agoThis is the real lesson. Programmers prefer simple, atomic programs that are short and digestible. Most other users need safety restraints such as a GUI. Doesn't stop you from using minimum viable product as a philosophy.
- 3xblah 7y agoOne opinion, possibly shared by others, is that small programs are actually more versatile than larger ones. The obvious example is working with text in UNIX versus in a large, graphical program with, e.g., cascading menus full of features chosen by a company, not by users. The text processing functionalty in the large program is usually pre-determined, not usually able to be modified by users. We can say what the program can and cannot do. Whereas it is difficult to say with any certainty what are the limits of a UNIX user who is creative in her use of a variety of small, single purpose programs. She may write her own, in addition to using the ones provided.
- AdieuToLogic 7y agoFrom the first sentence of the article: > A minimal viable program is the smallest program that solves a particular problem. It is small and beautiful. It has no additional features. From the FreeBSD source tree (/usr/src/usr.bin/tr): $ svn log tr.c | tail -6 | grep -v '^---' r1590 | rgrimes | 1994-05-27 08:33:43 -0400 (Fri, 27 May 1994) | 2 lines BSD 4.4 Lite Usr.bin Sources So, yes, what a lovely mindset indeed.