14 ms·
Kernighan and Pike were right: Do one thing, and do it well
- readthenotes1 3y agoIt saddens me that he didn't have a cartoon with one saying "High cohesion!" and another (smoking a pipe) saying "Low Coupling!"
- nologic01 3y agoIts an insightful read and the final graph analogy seems very apposite. But here is the rub: if microservices is a general graph pattern, it includes all the other patterns (likear, hub and spoke etc) as these are all just particular graphs. In other words, you could implememt unix pipe like or plugin like microservices by applying certain constraints.
- Nevermark 3y agoRight, but implementing a restricted domain (pipes) with tools designed for a more general domain (graphs), gives up the efficiencies and reduced complexity of the restricted domain. That is why we have restricted domains.
- nologic01 3y agoThe efficiency argument depends a bit on the scope one considers. If you only ever need pipes it makes sense to optimize and learn how to build pipes and your toolkit will reflect that. But if you need a variety of patterns you need to weigh in the inefficiency and cost of switching. The analogy would be a multi-purpose tool versus many special purpose ones (and the knowledge of operating each). This is all theoretical ofcourse, but my sense is that the debate about microservices is colored first of all by the extra complexity of networked computation (which raises the bar for a succesful architecture) and maybe indeed the absence of well defined constraints that would guide people on different possible best practices for segmenting monoliths.
- lelanthran 3y agoIs that relevant, though? An undirected cyclic graph is a superset of all other data structures[1], yet we still differentiate between them and choose the most suitable. [1] And can be used to build all other data structures. A tree is a directed acyclic graph, a list is a tree with no more than one child per node, etc
- nologic01 3y agoThe proof would be in eating the pudding, but the thrust of the argument would be to indeed recognize that "microservices" is too general a pattern and one might benefit and make them more usable by developing tailored patterns (imposing constraints adapted to the data exchanges that dominate the application). Its just a thought sparked by that interesting diagram at the end of the post and motivated by the fact that the REST architecture is also specified as a set of constraints...
- lelanthran 3y agoI take issue with the pasta diagram. I was there, in the 1990's, as a working professional not a hobbyist. The popular architecture was, for better or worse, structured as layers, not spaghetti. Some software from the 80s might meet that definition, but I think it's uncharitable (almost to the point of insulting) to assert that until the 2000s most programmers didn't know how to write anything but spaghetti code.
- marginalia_nu 3y agoThere was a moment when OOP was the new hot thing that code got real noodly, but this was arguably a temporary regresssion.
- jacquesm 3y agoSince Wirth nobody had any excuse. Structured programming was the key to breaking through the few-thousand-lines glass ceiling. Case in point: I tried writing a program to be able to edit sheetmusic and to play it back using the sound hardware in my computer. Endless re-tries of doing this, it would start off just fine and grow and grow and then I would get bogged down. With every iteration it was clear that it was getting better but I never could see it through to the finish. Then I read Wirths book https://en.wikipedia.org/wiki/Algorithms_%2B_Data_Structures_%3D_Programs https://en.wikipedia.org/wiki/Algorithms_%2B_Data_Structures... and even though the book was geared towards Pascal it was like someone had turned on the light. Everything fell into place and suddenly I could write code until I ran out of memory and keep it all organized. Massive change. This was in 1982 or so.
- Kamq 3y agoProper spaghetti code, in my mind, has always been pre-structured code. Which generally means assembly. C is rough to refactor sometimes, but it's nowhere near the kind of "push a couple return addresses and jump into the middle of a function" that used to exist.
- tailspin2019 3y agoGood article, but to me it seems to be co-opting the term enshitification in a strange way: > Large codebases will eventually reach an “enshittification point” — the point at which bugs are introduced faster than they can reasonably be fixed. I think of enshitification primarily as an organisational/business phenomenon rather than a technical one. It doesn’t necessarily emerge “bottom up” as the result of technical debt but from top down as a result of misalignment of values between the brutally commercial goals of the business and the values/goals if its customers. Tech debt and development velocity do play into this but I don’t think it’s the primary driver of it. The term is a useful one at that level of abstraction imho because we already have quite a lot of language to describe things like this at the lower, more technical level.
- asddubs 3y agoTo me enshittification is when the overall usefulness of a piece of software starts going down as more money is attempted to be squeezed out of its users. Agree that it's not a technical phenomenon
- RetroTechie 3y agoThis is why I tend to go for the "open" option (eg. open source software) wherever possible. Not necessarily because it's better. But because the incentive to enshittify it is lacking. Closed / proprietary ecosystems tend to be nice for a while. And then disappear without warning. Or turn into crap, like a big sinking ship taking all its users down with it. FOSS / open platforms tend to fork and/or evolve. And (if they survive) improve over time. That I can deal with.
- Narishma 3y agoIt happens in OSS too, though maybe the reasons there are different. See Gnome for example.
- RetroTechie 3y agoYep. And thus, Gnome 2 was forked into MATE. A good example of the forking / gradual evolution I can live with.
- noelwelsh 3y agoThe basic point is right, but I think a lot of the details are off. The core idea is composition. A system is compositional if you can build it from small reusable parts. It's one of the key ideas in functional programming, and it's somewhat core to object-oriented programming. (OO is too big to be able to claim their is a consistent philosophy behind it.) But ... firstly, let's stop with the Unix worship. They didn't deliver, even in the domain of the terminal. My copy of `ls` has at least 40 flags (where I stopped counting). Secondly, people have tried composition on the desktop. That's what CORBA, COM, and OLE were all about. They all kinda sucked for various reasons. Finally, the place at which the author arises has been around for as long as Unix: it's Emacs.
- pjmlp 3y agoNot only is COM still around, it is the main delivery mechanism for Windows APIs since Vista. Agree with UNIX worship point, I also had it, I was young and naive, lacking experience in the history of computer systems.
- noelwelsh 3y agoWow, I didn't realise. I haven't paid attention to Windows APIs for a long time. I really thought it would have died a long time ago.
- pjmlp 3y agoThat is what people outside Windows keep thinking. After WinDev managed to botch Longhorn efforts, its .NET ideas were redone in COM for Vista, and it has been like that ever since. WinRT/UAP/UWP, is basically COM with a new base interface IInspectable, .NET metadata instead of TLB files, and app boxing. And it is the foundation of WinAppSDK, whose goal is to port UWP subsystem into plain Win32, although their current execution leaves a lot to be desired.
- dist-epoch 3y agoThe core of COM is about allowing binary code to be used from any language through a standardized interface. As pjmlp mentioned, this part was very successful and all new Windows APIs are based on it. The COM which failed and which you are thinking about was related to OLE and the idea of embedding Excel sheets inside Photoshop drawings, ...
- sdenton4 3y agoI've been having a delightful time these last couple years working with Jax (the machine learning thing), which takes the DOTADIW stance. The philosophy is to get rid of frameworks, and replace them with libraries developed with DOTADIW in mind. This leads to better separation of concerns (amongst the various libraries), fewer leaky abstractions, sane-r, better thought-out APIs, and so on. All kinds of good.
- draw_down 3y ago[dead]
- hresvelgr 3y agoThese tools are not composable once you venture outside of a shell, and if I have to write anything beyond 5 lines, I'm not using one. There needs to be a way to make these applications usable as software libraries, and no, invoking them as a separate process from the main application does not count. This is the reason the functionality of these tools have been reinvented many times over and why they get extra cruft added is because they're actually not composable everywhere that matters. edit: typo
- vlovich123 3y agoDid you read the article? The entire last half is how to apply it to UIs and what that looks like (Obsidian, Canva, etc).
- hresvelgr 3y agoI did. I'm talking about CLI apps, though that wasn't clear I will admit.
- eternityforest 3y agoWe need more standard special purpose interfaces. Not unstructured RPC protocols, but very specific "Every plugin of this type has this function that does exactly this" kinds of things. Linux people seem to tolerate bash partly because they DO have a special purpose modular system. They algorithmically manipulate text in batch rather than realtime mode to produce an output on a regular basis(I'm not sure for what, besides compiling and building, but they all say they have use cases). Apparently it works great if you process lots of text files. Perhaps a GitHub awesome list. I've been meaning to start one for very common standards in general(18650 batteries, tripod thread, etc). We have LADSPA and LV2 for audio, shell commands for text, etc, What else do we have, and what should we have?
- enriquto 3y ago> invoking them as a separate process from the main application does not count Why not? What is your worry? That starting a process is too slow? That data transfer is too slow? Something else? I agree that process startup may be meaningful overhead in the rare cases when the actual computation is very fast. But sharing uncompressed data between programs is essentially zero-cost. Separate processes look particularly elegant and modular to me. They are much easier to debug and profile than bolted-in dependencies, since the running time and input/output of each process are trivial to isolate. Of course, having both a library and a cli interface for the same computational brick is always better, but the unix-style tool is an essential thing to have.
- freddie_mercury 3y agoI think it is hard to reconcile this with the reality that every big billionaire dollar app does the complete opposite. Excel, Word, Jira, Salesforce, Facebook, Oracle ERP, etc.
- jacquesm 3y agoI don't think there is a real contradiction. Once success gives you access to billions you no longer need to work the same way as you had to when you were much, much smaller. That's why as a small team it is wrong to adopt 'The Spotify model'. And yet, many companies will do just that. At every level of the corporate ladder there are different appropriate sets of tools and ways of working that will allow you to achieve particular results. Once you reach the Microsoft of the 1990's era level size (or Oracle, or SAP) you can ignore some of the truisms from the leaner days and do different things that would have killed a younger version of your company. Just like an adult can run and jump further and faster than a toddler.
- dgb23 3y ago> Once you reach the Microsoft of the 1990's era level size (or Oracle, or SAP) you can ignore some of the truisms from the leaner days and do different things that would have killed a younger version of your company. I think there are two sides of this. There’s of course a much stronger need to integrate with established systems, no matter the unnecessary complexity, for those companies. They need to provide stronger compatibility guarantees as well as mitigate risk. The other side is that once you have that many resources, it becomes less necessary to strive for simplicity and uniformity. The value for those companies shifted a long time ago from engineering to business processes.
- alkonaut 3y agoAs a developer I can sort of see the appeal. I often have tasks where I can compose programs. But as a user I just want the software that solves my problem from start to finish even if it does a worse job and costs more. Even if there are N pieces of software that solves my problem in N steps, that composition isn’t something I generally can or want to do. I just want someone to make a big ball of mud app that does exactly what I need. It’ll try to do whatever everyone else needs too, which is why it is a buggy ball of mud. But it’s still a lot more attractive than having N separate steps and doing any sort of composition myself. Because that invariably requires knowing about files, data formats compatibility between components . The Unix principle works well in Unix because the people using it are computer people, perhaps even software developers. In the age of everyone using computers (so 1990 and onwards) this breaks down horribly. The big ball of buggy mud do-it-all Software wins hands down every time.
- oneshtein 3y ago> I just want someone to make a big ball of mud app Just hire someone to make a big ball of mud app. > it does a worse job and costs more Yep. Just pay for it.
- Kamq 3y ago> But as a user I just want the software that solves my problem from start to finish even if it does a worse job and costs more. Well, if you're willing to pay, there's a lot more options. You correctly identify the unix principal only working because the people doing it are computer people. It's designed for a situation where you are the one that has to solve the problem, not one where you can just pay your way out of it. And while that might break down post 1990 once you start getting non-computer people using computers, I think your analogy breaks down post 2009 or so in the age of ads and everyone expecting everything to be free.
- ngcc_hk 3y agoMay be that is the key to the problem. We should have a programmer os vs a user os, sort of like macOS vs the underlying command interface. Not like dos to windows. The unix or linux is designed by programmers for programmers. User should pay their way out by paying the programmer. Obviously there is some in-between cases… occasional use is ok.
- eesmith 3y agoWhat's so different about Obsidian that sets it apart from previous plugin-based architectures? In particular, what is true about Obsidian which wasn't true about Eclipse some 20 years ago?
- eesmith 3y agoTo count the number of functions in a rust file you could run: cat main.rs | grep "^\s*fn\s" | wc -l This both promotes the "one thing well" model, while revealing its inherent limitations. How many functions are in this rust file? /* confuse things fn fo fp fn fm fl */ fn main() { println!("Hello, world!"); } The above grep reports two, when there is only one. It can be made to work if everyone agrees to follow conventions, like always formatting the Rust code, and indenting comments which look like Rust code. But that means pushing complexity onto people, rather than into the tools. Which you could do at the beginning, when complexity is low, but it gets increasingly more difficult over time.
- l0b0 3y agoThis sort of heuristic bugs me too. We should be able to write language server-adjacent tools which could do this sort of thing as easily as grep. You could do a lot of useful stuff with that, for example to implement custom linting rules: - Count non-comment tokens within each scope, to look for complex scopes: `foo --tokens --exclude-comments --group-by=scope` - Count expressions (as opposed to just SLOC) per function: `foo --expressions --group-by=function` piped to `uniq` - Get the functions and their argument count: `foo --arguments --count --group-by=function` - Find very short or long names: `foo --names --sort-by=length` piped to `head`/`tail`
- skydhash 3y agoMost languages are open source, it should not be difficult to extract their parser and do this stuff. As far as I know, only Babel ( JavaScript ) and Java have a plugin ecosystem, but only related to compiling.
- deleted 3y ago[deleted]
- eesmith 3y agoWhile I have not tried them out, I know there are tools along these lines. See Tree-sitter at https://tree-sitter.github.io/tree-sitter/ https://tree-sitter.github.io/tree-sitter/ , and as an example project which uses it to parse different languages in a line-oriented manipulable way, see https://pypi.org/project/code-ast/ https://pypi.org/project/code-ast/ . At the very least, the hard part - parsing the different languages - is done.
- deng 3y agoI wish people would stop applying the "only do one thing and do it well" to all software. Kernighan/Pike were explicitly talking about software tools in the Unix environment, not about all software in general. It is an idealist, you might even say elitist view of how software should work, which they then realized in Plan9. And as impressive as Plan9 is, there's a reason it never got widespread adoption, and that is not just because of evil Microsoft/IBM/whatever. It simply did not solve the problems people had, because it did not run the software the people (which are mostly non-programmers) actually needed to do their daily work. Yes, you can use these systems to write shell primitives, yet another build system, a window manager, a Wiki system, a basic text editor - mostly tools for programmers. It's like people with 3D printers mostly printing stuff to improve their 3D printer.
- asddubs 3y agoHey! I'll have you know, I don't print improvements for my 3D printer, I mostly don't use my 3d printer at all
- giantrobot 3y agoI love the cognitive dissonance of people saying "do one thing and do it well" when talking about Unix/Unix-like systems shipping with tools like sed, awk, and Perl. The idea that gets elided or list entirely is building composable tools. Composability lends itself to focusing a tool on a task but doesn't necessarily require it. If you build tools focused on composability i.e. output that is regular and easily parsed and properly using input and output channels, you'll get a system that is very extensible and responsive to end user needs. If you instead focus just on the "single purpose" tools you'll often end up getting ones that are too limited. They'll end up tightly coupled with other programs/service since their functionality alone doesn't do anything all that useful.
- jbverschoor 3y agoSpaghetti because there are so many "engineers"
- i_don_t_know 3y agoTo me, Wirth’s Oberon system has the same philosophy of having small composable tools and being extensible. There’s no distinction between system language and scripting language. Text is also a common way of passing data, but you can use whatever data structure you want. I think of it less as an OS than as an application shell that you shape to your needs.
- dgb23 3y agoThere are very different notions of OS and what its responsibilities and capabilities should be. In the world of Lisp and Smalltalk, you have a holistic view of what computation means. In Unix, complexity is pushed outward. Web browsers, language runtimes, virtual machines and containers are all examples of people expressing their needs by simulating operating systems.
- amelius 3y agoGood thing Elon Musk didn't take this advice.
- francasso 3y agoYou don't need a damn network between two pieces of code just to "do one thing and do it well", for God's sake, I'm so sick of this rampant cluelessness in the industry. Do you saturate the resources of one machine and need to split things off? Do you have multiple teams each taking care of their own stuff? Do multiple services, it's fine in those cases. For almost any other reason you are just adding complexity, boilerplate and additional failure conditions. If you think that microservices solve the "spaghetti code problem", well, good luck to you, you'll need it.
- lijok 3y ago> If you think that microservices solve the "spaghetti code problem", well, good luck to you, you'll need it. That is a very good point. In fact, good monolithic code layout is a precursor for microservices, as only once you have identified your boundaries and isolated your concerns can you begin splitting them out into their own services. I will say this however - microservices might not solve the "spaghetti code problem", but it definitely helps isolate it. When we get consultants in to speedboat a new system, we give them their own separate service. Saves a lot of time and de-risks our beautiful monolith.
- qaq 3y agoHave your teams use façade pattern and you no longer need microservices to "isolate it"
- lijok 3y agoFacade doesn't help with poor tests, scripts, new dependencies, cicd workflows, repo settings, etc
- monsieurbanana 3y agoIf it's that bad, you might be better off paying extra to avoid shitty outsourcing companies. But you're probably not the person I should telling this, developers aren't usually in charge of that.
- nabogh 3y agoCan't say I love Obsidian being held up as the best we can do for program design. It's closed source. It could be an elaborate system of duct tape and string holding the thing together. I mean it likely is quite good based on their velocity and quality. But if we're to learn anything I'd really like to see its source code.
- cpach 3y agoIt’s okey to prefer open source over proprietary applications. But obviously we can still learn lessons about interface design from proprietary systems. We don’t need the source code in order to observe those aspects of the application. (And if we need understand how to application operates under the hood, it’s entirely possible to use tools like IDA and Ghidra.)
- psychoslave 3y agoMake an extensible platform through a plug-in facility is hardly new or specifically closed source solutions, doesn't it?
- cpach 3y agoI haven’t made such a claim.
- psychoslave 3y agoThen there is something I miss in the article maybe. What is the lesson there? What is indeed so special about Obsidian, a platform I'm completely unfamiliar with, that is different from any other platform with a plug-in architecture?
- mawadev 3y agoWith plugins and extensions we've gotten to the point where "Create New Document" in Photoshop is an extension. Now that electron apps spawn their own browser process, then act like the central GUI hub and "do that right" - it seems to be quite the opposite from "do one thing and do it well" from my point of view.
- lifeisstillgood 3y agoThe point about "do one thing" is that it takes a lot of rewrites to work out what one thing to do, and where the boundaries are. Unix tools have developed in tandem in the unix ecosystem over decades of rewrites. They rubbed the rough edges off of each other. The major failing of most "systems design", architecture and companies is a reluctance to replace what is there with something better. No one likes a rewrite. And this affects microservices too. Once a microservice exists it's boundaries are defined. sure you can rewrite it to be more peformant but you cannot chnage its interfaces or it's scope - something is depending on that. The ability to reform those interfaces is what makes it possible to grind down and find the one thing to do well. And that takes lucking into the right fundamentals and being willing and able to make large scale changes. "Move fast and break things" might actually be excellent advice
- hamdouni 3y agoTwo things come in mind after reading this: There is no contradiction between monolith and DOTADIW. The code unit is the function, so each function does one thing and does it well. I don't get why microservices is the opposite of large code base : having the code splitted in different files or in different repo, changes nothing about the sum of all lines of code, no ?
- jheriko 3y agoexample of program "so simple it might be free of bugs" is buggy. classic bad tool work. EDIT: imagine a line starting 'pub fn'. correct solution? use parsers for parsing, not hacks.
- Decabytes 3y agoI’ve been learning PowerShell recently and as I was writing down the good things about learning about a shell scripting language I came to this conclusion. I normally use Python for things like this, but I have gotten burned more times than I care to admit with simple scripts having dependency issues. I realized that shell languages are not only smaller languages, but are more limited in scope. This means there are less dependency issues to handle. On top of that PowerShell scripts are easy to stitch together with pipes, so doing things like parallelizing and sending a job to the background as a task, then checking on it later is a lot easier. Furthermore the stitching together of shell feels very functional, and because the cmdlets only do one thing getting it to be parallelized is infinitely easier. To this day PowerShell is the only code I’ve ever parallelized on purpose. I then realized this was all possible due to the self contained nature of the cmdlets, which goes back to the Unix philosophy invented in 1969, about doing one thing and one thing well
- fefe23 3y agoCame looking for insights, found none. Instead I got platitudes like "sometimes microservices work well, sometimes not" and some copied together cartoon graphs, with a topping of meme pics. The conclusion is: "There are no easy answers". I wish I was kidding.
- diarrhea 3y agoCorrect. Even in this thread, it’s just a bag of opinions. Most are elaborate and well articulated, all correct, all wrong nonetheless. No wonder this topic is always such a pile of patchwork. It’s as diverse as developers are.
- dclowd9901 3y agoNotably the graphs didn’t make any sense to me. Don’t bugs go up as LOC go up? That’s my intuition at least.
- vlz 3y agoYup, but who knows, that graph also doesn't even bother with a description on thy y-axis, maybe it is supposed to go from 0 "maximum bugs" (zero code non-buggy) all the way up to "no bugs" (all lines of code bug free). Or maybe the author just wanted something colorful for us to look at.
- IshKebab 3y agoI think the core thesis is that "do one thing and do it well" is about small components that are connected together. The classic example is shell pipelines, but they are actually quite shit because they only deal with unstructured data (there's finally some work to fix that in Powershell and Nushell but it took many many years). A better modern example of doing one thing and doing it well is apps that support plugins. ---- I think the whole "do one thing and do it well" is terrible advice. A "thing" is not well defined. It's equivalent to "don't have too many features" which of course leads to "how many is too many" and you're on your own. It's one of those bits of advice like "premature optimisation" that is more often used to excuse thoughtless design than to motivate good design.
- cowsandmilk 3y agoBut then Kernigan contributed to awk which does regexes, count lines, and enough other things that there are 500 page books on how to use the tool. Maybe stringing together grep and wc wasn’t always enough.
- AnimalMuppet 3y agoOf course it wasn't always enough. It was enough to be useful in many situations, and not enough to be useful in all situations. So there's awk. And it's useful in some situations, but not in all. So there's C. (And some will say it's not useful in all situations...)
- 37174330 3y agotheorem: Total system complexity in software is constant; architecture determines where the complexity is exposed. doctrine: Effective architecture shifts complexity to the core competency of the development and operational resources. observation: software engineering suffers from the disconnect between the competencies in development and operation resources.
- AugustoCAS 3y agoI think this is an oversimplification. Having something that does one thing and does it well works for simple things that can be composed. Sometimes this is not the case, as the composition would be too cumbersome or too slow. The example of Obsidian (in my eyes) confirms this. Markdown is a very simple and elegant way to produce simple documentation, but as soon as one needs more it just crumbles. I agree that the big tools (Word, excel, photoshop, etc) are bloated. These applications have crossed the bridge into 'they do everything about X' long time ago and they work well in their very wide problem space. Just taking excel (or Calc) as an example, I cannot see how using simpler tools I could create pivot tables and aggregate values across multiple sheets.
- Barrin92 3y agoTaking Obsidian and VsCode as examples of the unix/microservices philosophy is very bizarre. VsCode is in many ways a philosophical successor to Emacs and sits on the opposite end. Yes, it has plugins but it is designed from the top down to work in a particular way, and everything integrates with it. VsCode Extensions don't function on their own, they're not composable tools, they don't expose any agnostic interfaces (except for the LSP). They're designed to work well within the existing ecosystem of VsCode. It's essentially a lesson in systems thinking. Paraphrasing Russ Ackoff, the complexity of a system is the consequence of the interaction of its parts, not the parts themselves. Microservices and unix tools always ignored this, which is why they fell out of favor. I can split one complex thing into a dozen simple things, but that doesn't make my life easier, because then all the complexity is in glueing them back together. And even worse improving one part doesn't mean you improve the system you care about. Ackoff always used to give the example of a car. You take the best part of all cars in the world an put them together, you don't have a great car but a pile of junk, the parts don't fit. This is also the issue of unix tooling and microservice architectures, people optimize for the wrong thing.
- grumblingdev 3y agoThe Atom editor was JavaScript + Electron same as VSCode. You could configure everything a lot more than VSCode IIRC. I was very excited initially. But I think perf issues did it in from this design choice. I'm keen to explore Emacs more. Plugin systems are one of the hardest things in software (but also look the easiest from the outside).
- Pxtl 3y agoI feel like this is misusing the term "enshittification" that Doctorow coined, which mostly described the phase where a popular product has to start generating value for its investors and starts exploiting its users.
- Pxtl 3y agoThis is why I'm disappointed that more OSes didn't steal the contact list from Windows Phone. The WP contact list acted as a shell for all person-to-person communication programs, showing a unified history feed of all communications you can read from a given person. Like RSS but for humans. It seems like the obvious way to do "lots of small programs" on the phone -- one single place for managing your communication with a person, whether it's Twitter, email, StarCraft, phonecall, chess, WhatsApp, teledildonics, etc.
- didibus 3y agoThe article is pretty average, and goes to great lengths to say very little, with some questionable analogies and examples. But near the end, there is a gem, which is the introduction of the Hub and Spoke design. Now Plugin architectures aren't new by any means. But they've not been discussed as much nowadays, and I think the idea of "Hub and Spoke" describes it very well.
- layer8 3y agoThe difficulty with the plugin model is that it tends to be brittle with regards to change. You need to have very well-abstracted, succinct and stable interfaces that don’t prohibit changes in the main application too much. It’s also difficult to prevent plugins from relying on various implementation details that aren’t part of the interface contract. If plugins have to be regularly updated for new application versions, that only leads to constant churn and abandoned plugins. It means the architecture effectively isn’t truly modular.
- briHass 3y agoThere's irony in using K'nex as an analogy. I hated those toys as a kid; sure, they're flexible in all directions, but all that flexibility means there's no structural integrity. To build something that doesn't twist and collapse, you have to overbuild all the connections and consider all the possible vectors of movement (gravity or applied) that need to be guarded against.
- tete 3y agoMost micro service architectures I come across sadly are very spaghetti.
- BirAdam 3y agoHear hear! And they usually develop their own unique bugs than then increase the spaghetti-ness.
- dclowd9901 3y agoOh the ideal. At my last company, we had developed years ago an API layer that allowed outside developers to build plugins to our web app. We also created a market place in which these developers could host these plugins. It was an absolute constant headache trying to tease out the bugs that these plugins would introduce. They often slowed the app down to a halt, and because they’re so opaque, users would blame us for the slow experience. I suspect it was because of the fact that their performance impact was so difficult to hold accountable, plug-in developers were never incentivized to make their plugins performant and just hacked them together. And this is universal. Every app I’ve used with a sufficient amount of capability for extensibility will invariably suffer this problem. Slack and Figma also suffer from this issue after you’ve installed a bunch of plugins. They get really slow and bug out. It is inevitable: the more code you add to something, the worse it gets.
- xhevahir 3y agoMaybe it's time to retire the term? Sounds like it's extremely prone to misuse.
- rakoo 3y agoThis hub-and-spoke architecture is the core of acme, the editor of plan 9 aka "unix if it had evolved using its own mantras and didn't choose pragmatism all the time". That editor has extremely basic functions built-in, and more complex operations are done by external processes plugged to acme and accessing all buffers directly, with a good, mandatory usage of the mouse. Unfortunately it doesn't have all batteries included by default, so it's not very famous today.
- EVa5I7bHFq9mnYK 3y agoWhy not use Python, or any other normal language, instead of all this bash nonsense?
- BirAdam 3y agoBash is already there. Also, if you really wanted something more powerful than Bash for a shell scripting context, Ruby or Perl would be a better fit.
- EVa5I7bHFq9mnYK 3y agois there something like copilot for CLI? Remembering endless switches is tiresome.
- zweifuss 3y agohttps://githubnext.com/projects/copilot-cli https://githubnext.com/projects/copilot-cli
- EVa5I7bHFq9mnYK 3y agonice
- Lio 3y ago> cat just outputs file contents Well it does but... its actual purpose is to concatenate multiple files. All Unix commands can read files so you don't need any special tools for that. E.g. grep "^\s*fn\s" < main.rs | wc -l or in grep's specific case just grep "^\s*fn\s" main.rs | wc -l
- BirAdam 3y agoHonestly, every paradigm and tool the industry has come up with has been great at identifying and attempting to solve either or one or many issues with software development and maintenance. The UNIX guys did this for C, where when UNIX systems are viewed as a C dev environment, the tools and paradigm are fine. The issue, IMHO, is that people tend to get… religious in their dedication to a paradigm and/toolset. I think the functional and OOP communities have done well too. The issue today is, I think, speed. People move very quickly now and there’s not adequate time for teams to document, bug fix, and grok a code base. If they took enough time for this, they’d be late to market and miss a giant amount of revenue. There’s also just the problem of accretion. All human organizational and informational systems suffer this, and software is no exception. At some point, the size of the code base and the number of developers eclipses any attempt and understanding and control. The extremes of the UNIX paradigm are neither sufficient nor necessary to arrest this, personal discipline is more the requirement.
- MisterTea 3y ago> "The issue today is, I think, speed. People move very quickly ..." Companies make people move quickly. > "If they took enough time for this, they’d be late to market and miss a giant amount of revenue." They arent worried about markets or revenue, the shareholders are. > "At some point, the size of the code base and the number of developers eclipses any attempt and understanding and control. " This is the result of corporate software development. Its software is shit because no one is allowed to sit down and think about problems. Just close the jira ticket and move on to the next one. To seek refuge, find a software community that cares and participate there.
- mplewis 3y agoThis article oversimplifies the pitfalls of various architectures to the degree that many of its conclusions are simply incorrect.
- SoftTalker 3y agoIf small, focused programs are good, so is concise, focused writing. This piece seems to have a central point that small composable code units are better than large monolithic ones. But it should not take a "12 minute read" to make that point.
- TZubiri 3y ago" The model [Unix Philosophy] never successfully made the jump to desktop operating systems. So popular modern programs like Photoshop and Word are about as “encrusted with dubious features” " You export your phtoshop design as a .png file and you import it into word. There you go. Windowed desktop programs like Photoshop and Word do offer interoperability, in the form of files. (Which by the way is another way programs communicate in UNIX, pipes are just a way for that communication to happen on memory).
- vimsee 3y ago> You export your phtoshop design as a .png file and you import it into word. There you go. > Windowed desktop programs like Photoshop and Word do offer interoperability, in the form of files. I think you are comparing apples and oranges here. Maybe if Photoshop and MS Word used the same dedicated underlying binary/application to read and process the png, then maybe it would follow the UNIX philosophy a bit closer?
- TZubiri 3y ago"Maybe if Photoshop and MS Word used the same dedicated underlying binary/application to read and process the png" The unix philosophy is to do one thing and do it well, it doesn't need to conform with expectations about each binary achieving low-level tasks. What even would be "reading and processing pngs"? Sounds like a dumb technical way to divide responsibilities. I rather have responsibilities of apps be user-defined like "editing images" and "writing documents". The unix philosophy precedes the development of the UNIX ecosystem, it's anachronistic to understand an OS based on how applications ended up interpreting it. It's like conflating a constitution of a country for its laws.
- vimsee 3y agoI still stand by my previous answer.
- vlz 3y agoThe way in which microservices, unix programs and extensible editors in this article are compared as if they are all attempts or at least examples of how to somehow "solve software architecture" is really rubbing me the wrong way. The author is speaking as if "How to organize software" is the nail and these things are all attempting to be hammers when they are really not. Would I want to build a world wide streaming service, I would probably need some custom microservices and I will not need some kind of plugin architecture for them. Would I want to build a slick editor that non-programmers can use for knowledge organization I will not wire something together with awk and gnuplot. If I want to quickly search some log files and sort and count the errors in them I will not look for an obsidian extension nor build a microservice. The question of how to architect such software is still an open one. I was happy about the clear thesis statement in the byline of the article: > Extensible programs like Obsidian have achieved a Holy Grail of software architecture, after decades of failed attempts However, by focusing on categories like "Applets", "Unix programs" or "microservices" the article in effect did barely touch the topic of software architecture and offered no evidence to support that byline.
- grumblingdev 3y ago> "How to organize software" I have recently had the thought that this is mostly what software architecture is...at some level. It's about where we draw the boundaries around code to make it easy for humans to understand. Imagine taking an existing repo, and extracting every block of code into a function, and then moving them into their own separate file in one big folder. You could extend it to all the libraries of your code, and of those services we communicate with over the network too. This would look a bit like a debugger symbol table. It's closer to how the computer understands the program. The app still runs. It's just hard for people to understand what is going on. Software architecture is simply the grouping of these functions to some extent. It's not a foolproof analogy, because there are some decisions to be made about implementation details of things, but at some level of abstraction you would find the same operations need to be run. Just an interesting thought. > The question of how to architect such software is still an open one. I find a problem we face with architecture discussions is that its always about tradeoffs that are not immediately apparent. And it takes a lot of mental effort to remember why something is a bad idea. The way we discuss it is limited by plain text. It's hard to demonstrate a system evolving over time in a concise manner. Architecture should be evaluated by throwing a spec at it, and then changing every part of the spec (including adding perf requirements) and seeing how long it takes to make the changes, and how many bugs it has.
- zomglings 3y agoWhat the article says about the hub and spoke model, singing praises of Obsidian, couldn't these points just as easily apply to Eclipse (the open source editor)? Eclipse isn't universally beloved. I haven't been following Eclipse development very closely of late, but there were versions released in the early 2010s that were universally derided. This is one example of cherry-picking I noticed in the article. Also linear relationships in Unix - ever heard of heard of tee? Also "enshittification" is turning into a meme at this point, I believe mistakenly applied here.
- pferde 3y ago"Enshittification" was a meme - in the original, non-lolcat sense of the word - from the very beginning. Perhaps what you meant to say is that it is being overused even where it does not make sense. :)
- jmull 3y agoHere’s the actual good advice: Build your system as a set of composable parts. The article doesn’t really quite get there, but is close. Almost everything else in there is wrong and should be ignored. Let’s see… *nix command line never did follow DOT, that’s the definition of shitty, not enshitification, the graphs are pulled out of thin air and represent the author’s feeling, not data, microservices don’t solve problems in large projects that various other approaches don’t solve (microservices tends to combine an certain approach to architecture, deployment, organizing dev teams and assigning responsibility to them within a larger organization, organizing code, change management, etc… the relevant things here aren’t specific to microservices). BTW, the microservices graph shown near the end is a lot like spaghetti architecture, where everything depends on everything else. (Not that you have to do it like that, but you’ll need some higher-level organization to manage it.)
- aswanson 3y agoAmen. The only thing I'd add is "independently debuggable composite parts."
- grumblingdev 3y agoI would prefer "end-to-end debuggable...". The biggest casualty of the web-scale era.
- HumblyTossed 3y ago> Big monolithic apps have large codebases that slow down development velocity. They’re slower to compile, harder to test, and full of dark corners where bugs can lurk and multiply. A bad change to one part of a codebase can cause headaches for an entire building’s worth of developers, tanking productivity for hours or days. This has NOTHING to do with monoliths. If you cannot architect a monolith, you’re going to have a hell of a time with micro services. This just comes down to being an awful software engineer.
- gardenhedge 3y agoA monolith has more engineers working on it though and chances are some of them won't be great.
- tracerbulletx 3y agoIt has nothing to do with individuals not being great, organizations of perfectly talented well intentioned people still end up with a mess eventually.
- zelphirkalt 3y agoIn the end the code needs to be written. What is better, parts of a monolith being shitty, or a subset of the microservices being shitty?
- slashdev 3y agoThose same engineers will still be there in the microservices world. You can argue that the damage they can do is reduced, but I don’t think that’s always true.
- gardenhedge 3y agoThat's my point though. Damage a monolith - big trouble. Damage a microservice - much more approachable to rewrite or replace.
- throwaway894345 3y ago