Too true.
It sometimes feels like programming is about trying to glue a bunch of hacks together creating yet another hack. Then someone standardises said conglomeration of hacks. Repeat.
A thousand times no. It's what we do when the problem set changes that causes trouble. We only ever respond one way: by agglutinating more code with the old. Compound this a few times and you have irreversible complexity. It's what would happen in a neighborhood if you called garbage "construction material" and only ever piled it up all around you.
The solution is to delete nearly as much code as we write. Put differently, the solution is small programs, ruthlessly pursued. The reason we don't do this is that it's totally absent from (nearly all) software culture -- absent as in blank stares and why-you-talk-crazy-talk if you bring it up -- and by far the number one determinant of what people do is what other people do.
There are a few points of light. Chuck Moore and Arthur Whitney come to mind. From everything I've heard, their programs are small enough not to have these problems. And in case anyone is wondering "If this is so much better how come we don't all work that way?" - the answer to that conundrum hit me the other day: sample size. Statistically speaking, it's never been tried.
Thanks for the Arthur Whitney reference, I had not previously been aware of his work although I fiddled about with APL to teach maths years ago and have always liked the 'executable notation' idea.
BC Is that advice you would give to practitioners: to throw out more?
AW Yes, but in business it's hard to do that.
BC Especially when it's working!
AW But I love throwing it all out.
It strikes me (as a non-programmer) that Moore and Whitney are working in well defined problem spaces. 'The art of the soluable' by Peter Medawar springs to mind (about scientific method).
I'm glad you looked that up. More people need to know about Whitney. I wish he would open-source his work so we could learn from it.
But why do you say they are working in well-defined problem spaces? No more well-defined than most, I would have thought. Certainly Moore was a pioneer of iterative development and evolving a program (and notation) in the direction of the problem. That's why he invented Forth in the first place.
Edit: Oh, having looked up the Medawar reference I realize you probably mean "well-defined problem space" in the way a mathematician would: a problem space narrow enough to be effectively studied but rich enough to produce meaningful results. Certainly most software projects do not start out in such a space. On the other hand, we don't try to learn enough about our problems to find such spaces. We merely add code. One might almost say we excrete it.
Sorry, yes, I'm not a coder. Whitney is dealing with financial data sets of impressively huge sizes but he (to my limited knowledge) clearly understands the structure of the data and a range of queries at a deep level. Moore looks as if he his devising the hardware to run the code!
I don't get it? If he really hates the situation so much, why did he choose a language that makes it notoriously difficult to write quality software in and chose a concurrency style that is notoriously difficult to reason about?
Your claim that JavaScript is "notoriously difficult to write quality software in" is unsubstantiated. Which language in your opinion makes it easy to write quality software in?
People only like JavaScript because they know it. Yes, it's more productive than Java because it's (barely) functional, but I personally believe the renewed love for JavaScript is mostly Stockholm Syndrome.
I believe since Java 6 (possibly 5), the JDK has come bundled with a minimal installation of Rhino which runs JS on the JVM. How many people actively use that? It's not hard to get going, 5 or less lines of code to start running a JS file and it will run everywhere with JRE >6.
But there's no jQuery, etc. It's a somewhat nicer way to work with Java since you aren't forced into I-don't-care-about-it-exception-catching hell and Map<Map<Map<...>>> madness, but compared to Jython or Clojure it doesn't match up. You can get a headless jQuery working with Rhino, though it's not as simple as it should be.
Rhino is slow, but it's freaking awesome if you need to write an algorithm that can run in the browser and on the server. Much much much nicer than having to maintain two implementations in two different languages.
Part of JS's popularity is definitely politics... the fact it's in the browser gives it a huge shot in the arm.
It's a decent language, though. Here's a comparison of JS to Ruby for some of the stuff people generally love Ruby for. JS comes out looking pretty decent.
If it ain't got macros, then it ain't a Lisp. Javascript is definitely no Lisp, but I really like that it allows function composition, which is somehow reminiscent of a Lisp.
f(g(h(x))); instead of (f (g (h x)))
You're right. I meant to say passing first-class functions as arguments, rather than pointers to functions as you would in C or an object method as you would in Java.
Indeed. Lisp is a simple language that can be completely defined in half a page. A naive implementation takes less than a thousand lines of code. The language is homoiconic, i.e, there's no difference between programs and data -- everything is a list. This enables programmers to perform complex transformations on code using macros. Lisp compilers such as SBCL generate code that is almost as fast as C++. Oh, and the original Lisp as described by McCarthy is strictly rooted in mathematics. If you limit yourself to writing only a subset of Common Lisp/Scheme -- one that emphasizes immutability and recursive functions on lists of symbols -- it is possible to use formal methods to prove the correctness of your code.
None of that is true for JS. I don't think Crockford thought his remark through.
JS is known for being a language with a lot of "WTFs" in it. Yes, you can write bad code in any languages and you can even write great code in JS. But to quote Fogus: "My problem with Javascript has always been that expertise is defined more in terms of understanding its faults rather than its features"
But I do feel that node.js is Rayn's attempt to enlighten me and hopeful others. He doesn't try to hide everything like ports and the underlying c code. Its all there, and best of all in a language that is familiar(at least for web developers).
I don't assume that he likes what he created. My point is: if he thinks things are these way why didn't he try to create a framework that did things simpler? The research on concurrency has plenty of options that are easier to read and reason about than callback-based code.
Interestingly, part of the reason Node.js used JS was that JS didn't have a ready-made standard library so it made a clean break from a lot of the styles of the past. Node was an opportunity to force a community to rethink a lot of things.
In what way did it accomplish this? The style Node has chosen for modeling concurrency is decades old. Twisted has been using it since the late 90's. So JS doesn't have a standard library? Who cares? You still have to write one for your event-loop, which is what you had to do in Twisted. I don't see any rethinking going on, I see steps backwards.
Call it a noob mistake... but I recently wrote my own MVC framework on top of Express... and ended up never writing the app I originally intended to use it to write.
I think a few months ago, this wouldn't have made sense to me, but now I totally get what he's saying.
On my new app, I'm still using express to do most of the connect-ey stuff, but i've definitely decided that most MVC-ey frameworks are a premature optimization (for me). I'd rather just start with node + express, add in whatever DB I need (Redis / Mongo preferably) and build small and progressively.
My lesson learned... would love to hear other opinions.
There is very little value in trying to draw generalisations from past experiences when it comes to deciding whether to use a framework, and if so, which framework to use.
Unless you're reinventing the wheel, each project will front you with a unique set of challenges. More often than not, with a framework, these problems are awkwardly solved with code written by other people to solve other people's problems.
In my opinion all of this has less to do with what's trying to be achieved than it does with what you personally want to take away from the experience. If your motivation is to make money quickly to feed your family then you would be silly not to jump on something like Rails and ride on the shoulders of giants. On the other hand, if you want to become the most proficient programmer you can become then this path will probably lead you astray.
A quick look around the internet reveals both tiny projects that fail, as well as enormous projects that succeed, on full-stack frameworks such as Rails.
Needless to say if you're hacking on node you are of the latter category; The developer striving to broaden her horizons by exposing herself to the news and unknowns. This won't help you learn to work in a team on a large project. It wil not teach you to control complexity. In fact, it will probably lead you to believe you're learning all these things when you're in fact becoming comfortable with the complete opposite (working alone, hacking in anything, anywhere you feel like).
Generalisations really piss me off.
I whole-heartily encourage anyone who is open-sourcing node.js code to continue doing so. Even if it is Yet-Another MVC framework. Just take note of what ry is getting at here by keeping it mean and lean.
The people who created Plan 9 (and Unix) this days are working on something that has a better chance of blowing a hole through the huge mess that is modern software: Go ( http://golang.org )
I might be naive, but Go is the only thing that has given me some hope for the future of software development in recent times, it means there is a chance that maybe some day I will be able to write software in an environment and with tools that are not byzantine hideously insane piles of layers gratuitiously complex crud.
Hell, with Go you completely bypass even libc (but unlike Plan 9, you still can take advantage of the hardware and software support of existing operating systems/kernels, that sadly are an unavoidable mess, which is one of the things that made it impossible to adopt in practice).
My interpretation of what Ryan is saying: Programming languages, libraries, and linux distributions are more complex than they should be. When you use them in your products, you contribute to the problem. When you're thinking about them, you're wasting your time because your users don't care about your tools. One day we'll decide it's easier to throw them all out and start over.
Overall, I don't agree with this.
Complexity arises because what we want to do is complicated. I don't think there's a way around that. Sometimes too much cruft builds up in an area, but that leads to redesigns of specific components. For example, client-side configuration of LDAP and Kerberos has been unreasonably complex for a long time. That didn't lead to people ditching them, that lead to https://fedorahosted.org/sssd/. It's likely that one day we will decide it's best to replace LDAP, just like was done with NIS. However, it won't mean we have to throw out all of linux.
The "users don't care" argument doesn't appeal to me. I don't care what tools the architects used when they designed my apartment building, but if learning some complex math and geeking out over slide rules enabled them do it, I'm all for it. Being told there's something wrong with me because I've changed the settings in my text editor is insulting.
Every level of abstraction above binary code, from assembly, to C, to Ruby, to Rails DSL's--each works by creating magic incantations that let you run larger functionality with a new shorter series of magic words.
Are you really against magic, or is it that you are against black magic (which I would classify as leaky abstractions)?
Sometimes the new magic incantation is longer than the old incantations it was based on, though. And slower. And harder to understand. And buggier. And doesn't expose important functionality, so you invent roundabout ways to access it. And when you put several abstractions on top of each other, you will eventually get all these problems combined.
For example, try to draw a single black pixel on the screen... using JavaScript, or better yet, some language that compiles to JavaScript. How long would that take you? How many lines of code? How fast does it run? How much memory used by all subsystems combined? How many system calls involved? In assembly language that would be one instruction. And don't tell me that drawing single pixels is unimportant. I can show you any number of hackers who would create extremely cool webapps if drawing a pixel took one assembly instruction.
Do not confuse the language with the environment in which it runs. The difficulty with pixel-poking isn't with JavaScript, it's with the environment. Give it another environment that allows the language direct access to the window (rather than to a DOM node nestled deep withing the bowels a parse tree which then needs to be rendered by a completely separate engine) then the difficulty would vanish. JavaScript may most typically run in a browser context, but the browser context is not JavaScript.
I don't know what it's like for other Javascript-based environments, but in mine it looks like this:
Mars.load("olympusmons.js");
var app = new Mars.UIApplication().init(1280, 720);
app.setBackgroundColour(0xFFFFFFFF);
app.startRenderThread();
var scene = new Mars.UIScene().init(app);
app.addScene(scene);
var surface = new Mars.UISurface().init(app);
surface.setSize(300, 200);
surface.setColour(0xFFFFFFFF);
var texture = surface.getTexture();
texture.setBackgroundColour(0xFF0000FF);
texture.setPixel(150, 100, 0x000000FF);
It's hard to disagree with you when you use that definition of 'magic'. This is an example of my definition...
Yesterday I was looking at a Chartbeat gem that accesses the Chartbeat REST API [1]. The entire class is 40 lines of code, however it's coded so weirdly that you'd have to read the source in order to use it. Every API call was a method_missing call, so instead of doing (in irb)
But I only know that because I had to look at the source code. In addition, there's no way to specify custom exceptions to the user, you have to rely on the rest_client gem's exceptions.
The code does look magical, and kudos to the developer that wrote it for the ingenius use of method_missing, but IMHO it's a bit to magical for my tastes. I like to look at a library's documentation and instantly know what methods I'm allowed to call and what exceptions/results I'm going to get back.
Honestly, this is why I cringe whenever I hear code described as "clever." I bring up "clever" here because "magic" seems to be used in this discussion in a manner synonymous with "clever." [1] Developers tend to be intelligent people who like to stretch their intelligence, but in terms of code robustness, the boring, normal solution is almost always a better choice than the clever approach. Clever, to me, has almost become synonymous with unusable, fragile, and over-complicated.
[1] Edit: Added explanation since, on a second read, it seems like I'm digressing from the topic.
"Technology's greatest contribution is to permit people to be incompetent at a larger and larger range of things. Only by embracing such incompetence is the human race able to progress." http://www.theodoregray.com/BrainRot/
Holy shit, it isn't just me! I've been muttering for years to coworkers, colleagues and random acquaintances that elegance cannot be obtained by adding an additional layer of complexity, yet modern developers seem absolutely enamored of the kind of vile unnecessary complexity that comes with layered abstractions.
I couldn't agree more. In software engineering, I have seen people read books on design patterns and use it EVERYWHERE possible.
Even the most simplest and straightforward development work is matched to a pattern and implemented as a design pattern.
I think there should be a rule that says if your feature or a particular problem that you are trying to solve does not exceed XYZ lines of code, then it should never be implemented as a design pattern.
Right. Because current attitudes are that if you aren't developing everything purely object oriented with a design pattern or five using nosql for your data store you're a fucking imbecile. I shit you not I've seen a coworker spend half a day adding 800+ lines of get() and set() methods to a 150 line email script. The truly bizarre part is, it's not like he's stupid, or fresh out of school. The guy's a certifiable genius with six or seven years of industry experience under his belt.
This kind of cargo cult bullshit is, in my opinion, the single largest recurring (recursive?) problem in our industry. Unfortunately this isn't a new problem. Every generation of programmers finds some set of development concepts to enshrine as the gospel.
I am struggling to think of a single piece of software that I interact with in my day-to-day life that brings me pleasure. I suppose Emacs comes closest, but it's a hideous pile of hacks and YHWH help you if you want to get into the internals to start paying back the massive amount of technical debt.
tsort. There we go. I don't hate tsort. pbcopy and pbpaste.
I am struggling to think of a single piece of software that I interact with in my day-to-day life that brings me pleasure
Games, a game delivery system like steam or perhaps vlc for playing my favorite music, but even then, its the music that makes me happy, not the program playing it...
Ont he other hand, there is a lot of software that I actually hate.
I special case games because I play them on consoles and therefore have compartmentalized them as appliance functions, and not the massively complex pieces of software that they are.
The list of software that I actively despise, however, is finite, but unbounded.
The iPhone is a miracle the size of a deck of cards. A lot of the standard apps are a joy to use. (The annoyances arise more from the business side than the nature of the software or the device itself.)
I'm not an iPad user but it makes a lot of people pretty happy.
Chrome is usually a pleasure to use. Firefox used to be that way, and they are starting to regain my trust again. I feel good about using Firebug as well.
Skype has some irritations, but for the most part it's still marvelous to open up a video chat to fucking Zanzibar whenever I feel like it.
vim is not always easy, but wow is it rock solid.
Upgrading Debian works very well for me at least, thanks to the miracle of apt-get. Debian itself, well, it's not winning usability awards, but still....
I upgraded from Ubuntu 9.04 to 11.04 (I think) with a bunch of commands without a problem. Couple of reboot and that was it. God that felt good (all of that on Linode). When I compare that to sysadmin / installing Linux or some Unix ...
I assume you mean in terms of the interaction with the software itself (rather than say, pleasure from social media being the conversations rather than the software) and there's one type of software that's specifically about enjoying the interaction: games. I guess you're not a gamer?
Grep. Grep is about the single best fucking thing ever written by the hands of man. Shakespeare can suck it, I'm telling you, grep is IT.
Edited to add: Git. Git is also a thing of beauty. Who knew revision control could be made to not suck? Sure, SVN was a welcome relief from the unrelenting stone faced hell that was CVS, but that's damning by faint praise.
I love sed too, but you should mention QED (1965!) here, which is actual proto-mother of almost all text-related goodies. Let me quote a nice wikipedia paragraph, which covers it.
ed went on to influence ex, which in turn spawned vi. The non-interactive Unix command grep was inspired by a common special uses of qed and later ed, where the command g/re/p means globally search for the regular expression re and print the lines containing it. The Unix stream editor, sed implemented many of the scripting features of qed that were not supported by ed on Unix; sed, in turn, influenced the design of the programming language AWK, which in turn inspired aspects of Perl.
Git is the quintessential example of requiring the users to get inside the author's head if they want to avoid disaster, and thus falls into the "steaming pile of crap" category. The things "git merge" will do to your tree are not defined by what a user might reasonably want or expect but by what's easy and convenient for the git authors, and there is simply no way to understand "git reset" without thinking about the internals of how git tracks changes. Simple commands do bizarre things that are almost never needed or desired, while simple and common tasks require non-obvious (and poorly explained) options. Git is a powerful and useful tool, but it is also the poster child for what is wrong with modern software development.
Yep, I agree. I've used git for 5 months. I just know for sure what 3 commands do: git commit -a and git push and git add.
Ask me what git merge does, or how to branch, or even how to delete a file in a repository (w/o deleting it from your local), or how to revert back to another version, or how to even check out, and I'll say I dunno. I read the documentation, but am still confused. I sometimes feel like I'm dumb because I feel everyone loves git and everyone gets it. Glad to hear that I'm not alone.
A big problem for me is that every time I drop into the shell, I'm in the shell. And I hate the shell like I hate nothing short of, I don't know, Nazi zombie robots. I've been using Unix or a derivate for more than twenty years and I have never lost my loathing for the shell.
And don't even get me started about C the language. It makes me want to go find Ritchie and punch him in the junk.
Why is rsync not a binary linked to a useful librsync? Why STILL TO THIS DAY a grep/egrep difference? And why did Apple integrate Interface Builder -- their best piece of software, IMO -- into Xcode?
On one hand, I agree with him. The software ecosystems we work in have a whole lot of needless and incidental complexity. I could go on and on about the insanely and overly complicated things that developers -- especially ones like Ryan Dahl -- have to deal with all the time.
On the other hand, it's arrogant for one to think that he or she could do it that much better than the next guy. Writing efficient, maintainable, and "simple" software requires adding layers of indirection and complexity. You have to use your best judgment to ask whether the new layer you're adding will make things ultimately cleaner and simpler for future generations of programmers, or will hang like a millstone around their necks for years to come.
Let's try a little thought experiment: go back a few decades to the early 80s. Propose to build node.js as a tool to make it much easier for developers to write real-time network applications. You'll need to design a prototype-based dynamic language, itself an extremely difficult (and dare I say complicated) task. The implementation will need a garbage-collector, a delicate, complicated, and cumbersome piece of code to write. To make it acceptably fast, you'll need to write a JIT, which traces and profiles running code, then hot-swaps out JITted routines without missing a beat. You'll need to write a library which abstracts away event-based IO, like the "libev" node.js uses. That will require kernel support.
Frankly, even forgetting about relative CPU power at the time, I think you'd be laughed out of the room for proposing this. All of these things, for production systems, were extremely speculative, "complicated" things at the time they were introduced. People can't predict the future, and they obviously have difficulty predicting what tools will become useful and simple, and which will become crufty tarpits of painful dependencies and incidental complexity. No one in 1988 could say "a dynamic, prototype-based, garbage-collected language paired with a simple event model will allow developers to create simple real-time network applications easily in 2011". Many of them probably had high hopes that C++ templates would deliver on the same vision by then. But, instead, we have Boost.
Further, it's extremely arrogant of Dahl to create a dichotomy between those who "just don't yet understand how utterly fucked the whole thing is" and those, like him, with the self-proclaimed power of clear vision to see what will help us tame and conquer this complexity. Who knows, maybe in 15 years we'll be saddled with tons of crufty, callback-soup, unreliable node.js applications we'll all have to maintain. I don't think James Gosling envisioned the mess that "enterprise Java" became when he designed the initial simple language. Most developers do many of the things he cites, like adding "unnecessary" hierarchies to their project, because they believe it will help them in conquering complexity, and leave something simple and powerful for others to use down the line.
Not well, unfortunately. Neither does it handle errors well. It doesn't have proper closures, either. I love it, but readily admit it's a giant research demo.
Erlang came out in 1986, and was used in production systems shortly thereafter. The world really is just catching up to the state of the art of the early 80s.
Ryan is right. Most of the software we use is crap. That's because Worse is Better.
Ryan doesn't claim he can tame it. The post comes off as self-deprecating and not arrogant to me:
"Node is fucked too. I am also one of these people adding needless complexity. ... The entire system is broken - all the languages and all the operating systems. It will all need to be replaced."
In fairness the internals of Node get complicated due to cross platform support. The fact that every OS does it differently is both a blessing (because we can learn from mistakes of others) and a curse.
Arrogance? Come on, it's a rant. Cut him some slack.
Other than that, I agress with pretty much everything you said. It's easy to forget how reliant we are on things like industrial-strength GC, multithreading and JIT and how young those things really are.
It's not arrogant of him to think like this. It's more like Steve Jobs, circa 2006 thinking phones sucked and deciding to do something about it. Or maybe it's like Steve Ballmer thinking he could take over the phone market. I think it's too early to say for sure, but the early signs are promising.
Modern Lisp didn't came out until much later, but still, Common Lisp was out in 1984, and that's still very early, especially considering the fact that it was a response to already widespread use of Lisp languages with Lisp-like features.
The post is about how a programmer thinks that there is a lot of things that are more complicated than those should be; and even use web development as an example. PHP is a programming language with a lot of native functions to do things in the web that would be a lot harder otherwise...
So, what is the trolling here? The lack of serious tone in the comment?
Never fails to amaze me what users will do with a software tool.
I've seen experienced devs and support staff run a C program written to parse some weird data against another data set in the vain hope that it would parse the new data set into something usable.
I've seen MBAs who could barely tell you what a variable is write visual basic macros in Excel to do hardcore data management.
Game devs who almost seemed to frickin' think in OpenGL.
It is a big ball of mud (turtles all the way down, eh?), but on a good day, I listen to a hacker talk about finally getting that little piece of code beat into submission and it's very satisfying just to see that gleam in their eye.
The real problem is that tools and libraries are incredibly unforgiving. Not only do you have to understand 10-15 different technologies to make your project work, but you need to understand them all extremely well which is a huge barrier to entry.
I don't know a whole lot about rails, so this is conjecture, but I imagine this is why ruby on rails is so popular: you don't need to know very much to get it going.
I get why complexity is disliked(/feared?) by some people, but unless you've got a better workable solution that you're ready for me to try out, your rant is just noise to me.
I've often found myself begrudged by the complexity of a piece of software, but that doesn't make me think we should throw the entire program out. How about we make it easier to use instead?
He's saying we've become the proverbial frog in the boiling water. The inability to abstract well has made any medium-to-large software project a Rube Goldberg contraption. You may not mind it -- but you should. Because it's silly. Because it's stupid. And recognizing that fact is the first step towards our recovery.
As he should. These things are all stupid. They're monstrously stupid minutiae that you shouldn't have to know about unless the abstraction somehow leaks.
What he's saying is, "Where are better abstraction mechanisms?" And that's a tremendously important question (whether you get it or not).
Application messaging is a great idea. Desktop buses are useful.
DBus as an implementation of messaging largely sucks. It uses an ad hoc protocol, there's little security, the C library implementation of it is a big mess, the socket interferes with remote X, introspection doesn't really work, and it uses far too much XML.
This is just raw pessimism, you could rant like this about anything.
I hate all cars, especially my own. I hate that heavy, dangerous, gas-guzzling honda civic with an over-sensitive brake pedal and enormous, completely pointless blind spots over both shoulders. I hate filling it up with gas, which is expensive, smelly, and bad for the environment. I hate the dishes that I have to wash every day after I use them. I hate my Aeron chair that I sit in all day long. I hate peeling grapefruit. I hate the sound of my central air conditioning fan powering up. I hate how I'm either sore from working out or depressed from not working out.
There's nothing wrong with a rant now and again but let's recognize it for what it is.
Life is pain, Highness. Anyone who says differently is selling something.
Software really is sort of a special case though. Most of the problems you mentioned are at least partially caused by the constraints and resources of our physical environment. However, the complexity of software is almost entirely generated by human ineptitude. The one exception might be complexity caused by necessary optimization for hardware limitations, which would in fact explain some of problems cited in the blog post.
Unix (for example) was most certainly designed around the constraints of hardware at the time.
Furthermore it is a physical limitation for how much software you can write (and have it work) if you can get something that "mostly works" by building on top of yesterday's cruft then you do it, since the alternative is starting over from scratch and not being able to finish.
Most of the problems I mention aren't objective. Sometimes I like washing dishes, it's relaxing. I certainly like eating from dishes. Some people like cars and like driving. It certainly saves people time. Peeling grapefruit is very satisfying and makes the room smell nice. Central air is so much nicer than setting up a fan by my window and hoping that blowing the 75 degree air from outside will cool down the 85 degree ambient temperature inside.
Blaming "human ineptitude" is pessimistic. Sure, the fact that humans can't all manipulate computational machines directly and require layers of abstraction to effectively model problems can, technically, be called ineptitude, but really-- why be so down about it? That's the way things are and there's a lot of good that comes from software if you think about it for more than 30 seconds.
You could have picked about a hundred "regular" cars to illustrate your point better and not one of the fastest and most expensive in the world.
For example my brand new Hyundai Sonata has pretty shitty rear visibility due to it's 'sleek' styling and therefore smallish rear window. I could cite many more.
It's more than the mirrors, and unless you have transparent pillars on top of the car (giving up the structural integrity of the cabin) it's going to have blind spots.
Also, most side-view mirror blind spots are caused by improper mirror positioning. If you can see the side of your car, or see the same object in both the rear view and side view mirror, you've positioned them wrong.
You should actually have them a lot farther out such that visibility in your side mirror coincides with losing rear-view visibility. That position is a lot farther out than most people think and is tricky to do the first few times.
Chevy HHR. No matter how much I adjusted the mirrors on that beast there are spots along the sides, and directly behind, that you just aren't going to see.
To some degree, I can agree with Ryan here that a lot of software these days is unnecessarily complex. However, I also think that his view is biased because he works on a project that is responsible for a great deal of abstraction.
The average Javascript developer using node.js DOES NOT have to "deal with DBus and /usr/lib and Boost and ioctls and SMF and signals and volatile variables and prototypal inheritance and _C99_FEATURES_ and dpkg and autoconf", because Ryan and other node.js devs already have thought about it for them, and introduced a helpful and practical layer of abstraction on top of all this complexity.
As a result of having to think about it all day, every day however, it's understandable that Ryan would despise this kind of stuff. On the other hand, as a web developer that uses the result of his hard work, I am not affected by it at all, so the complexity of my work is substantially reduced.
The complexity of your work (as I assume a web developer) is substantially reduced to only HTML, CSS (and its various implementations on various browsers), Javascript, the modeling language you use, the framework you use, the database, SQL, ... Should I go on? It's all shit. Not just what he deals with.
I'd be interested in Dahl's (or your) opinion of Alan Kay's STEPS project in this context.
"For example, essentially all of the standard personal computing graphics can be created from scratch in the Nile language in a little more than 300 lines of code. Nile itself can be made in little over 100 lines of code in the OMeta metalanguage, and optimized to run acceptably in real-time (also in OMeta) in another 700 lines. OMeta can be made in itself and optimized in about 100 lines of code."
Most people won't change their mind about anything, unless everyone else already did. Therefore, (Kay concludes at 24:00), truly new ideas take at least 30 years to become popular.
STEPS is too young. At this pace, wait for at least 20 years.
In order to make some project popular, you need to show it's powerful in doing REAL work. Ruby on rails did it for ruby. Paul Graham's success and writing did help lisp.
This bit isn't the most impressive. Self-compiling languages are worthless until they implement something else. And it happen that IS (OMeta + Javascript + Nile), does implement more than itself. On top of it, they implemented:
- TCP-IP in 200 lines. Current C implementation use 10Kloc (50 times more).
- Most of Cairo's functionality in 500 lines. And it's fast enough. Cairo on the other hand weighs about 40Kloc. (Again, about 50 times more code.)
And that's for functionality they couldn't scrap altogether, or merge those with similar capabilities. For instance, you don't want to send emails, or publish a web page, or print a PDF, or, goodness forbid, a Word document. You just want to handle a fucking document. Send it, publish it, whatever, this is all glorified text (you do need the glorification, though).
Hear hear! As a software developer, my trade is a ghetto awash with all manner of amateur-hour charlatans and language silos that are tantamount to pistol-whipped lock-in (I'm looking at you node.js). If you take a step back, the entire ecosystem of 'software development' is a chattering tower of Babel, all sound and fury, signifying nothing.
Programming languages, their frameworks, their libraries, their petty concerns are a mere vanity folly, riddled with re-invention, abstraction arcana, and deus-ex-machina hoopla. We have lost our way, straying so far from the path of the UNIX philosophy such that I must now 'whole-stack' an application instead of using the pipe character. A pox on the whole damned lot of it!
Some days I just despair of all the time I've wasted bustling and jostling, crushed by the sweaty masses in the ghetto. But if I'm honest with myself, I must confess I love it too. I love my programming languages, my libraries, the eight different ways I know to full-text search, to regex, to parse, to lock, to async. I love the smell and heat of the coal-face, the futility of it all. Stockholm Syndrome indeed!
You had me until "straying so far from the path of the UNIX philosophy". UNIX is a huge part of the problem IMO. Worse is better. Systems like Linux are the enemy of progress because while they suck horribly, they work much better than some alternatives (not to mention any naMeS) and at least as good as others so why spend time actually doing things right?
There is so much more that could be done with operating systems in any direction you want to go. I'm thankful that doing things on my iPad doesn't involve messing with command lines. But for when I want hackability I'd rather have what a Lisp machine could have become than a silly way to do functional programming in shell.
Increasingly, the key is to main orthogonality towards your problem solving (like an eagle) within the decaying confines of a semi-bloated (often mostly educational in terms of what not to do) ecosystem.
Which means rewriting crufty pieces of your stack when certain thresholds occur. 'There will come a point where the accumulated complexity of our existing systems is greater than the complexity of creating a new one' -- is something that happens in motion, iteratively, and which you do when you have time at all levels of the evolution that we call development.
Anyway, that's my two cents. Nice others are on the same wavelength, I think.
Good analogy, it reminded me of teen angst. The Livejournal version of this rant would have been: "I hate how the world is so complicated, with relationships and stuff and politics and law and technology, why don't people in this time just behave simple. Animals have done so for millions of years, and the only thing that matters is that things are simple and understandable to me. I don't care about history and mathematics why, ohhh why doesn't the world simply do what I want !!!"
Software needs to be complicated because the tasks that it performs are complicated. The only way human programmers can deal with this is abstraction on abstraction on abstraction. This will only becomes worse as software handles more "real world" things such as formerly hardware tasks.
Unnecessary software complexity is added due to maintenance, where the maintainers added extra complexity because they weren't able to integrate the changes into the current design and/or didn't understand it well enough. Probably a better job could be done with better tools/documentation in this case. Not by ranting at developers though.
His rant about UNIX is crazy. Any full-featured operating system necessarily is complex under the hood. If something randomly doesn't work in his favorite OS he also has to spend hours googling, diving into obscure settings managers, etc.
302 comments
[ 2.9 ms ] story [ 277 ms ] threadThe solution is to delete nearly as much code as we write. Put differently, the solution is small programs, ruthlessly pursued. The reason we don't do this is that it's totally absent from (nearly all) software culture -- absent as in blank stares and why-you-talk-crazy-talk if you bring it up -- and by far the number one determinant of what people do is what other people do.
There are a few points of light. Chuck Moore and Arthur Whitney come to mind. From everything I've heard, their programs are small enough not to have these problems. And in case anyone is wondering "If this is so much better how come we don't all work that way?" - the answer to that conundrum hit me the other day: sample size. Statistically speaking, it's never been tried.
http://queue.acm.org/detail.cfm?id=1531242
It strikes me (as a non-programmer) that Moore and Whitney are working in well defined problem spaces. 'The art of the soluable' by Peter Medawar springs to mind (about scientific method).But why do you say they are working in well-defined problem spaces? No more well-defined than most, I would have thought. Certainly Moore was a pioneer of iterative development and evolving a program (and notation) in the direction of the problem. That's why he invented Forth in the first place.
Edit: Oh, having looked up the Medawar reference I realize you probably mean "well-defined problem space" in the way a mathematician would: a problem space narrow enough to be effectively studied but rich enough to produce meaningful results. Certainly most software projects do not start out in such a space. On the other hand, we don't try to learn enough about our problems to find such spaces. We merely add code. One might almost say we excrete it.
But there's no jQuery, etc. It's a somewhat nicer way to work with Java since you aren't forced into I-don't-care-about-it-exception-catching hell and Map<Map<Map<...>>> madness, but compared to Jython or Clojure it doesn't match up. You can get a headless jQuery working with Rhino, though it's not as simple as it should be.
It's a decent language, though. Here's a comparison of JS to Ruby for some of the stuff people generally love Ruby for. JS comes out looking pretty decent.
http://fingernailsinoatmeal.com/post/292301859/metaprogrammi...
None of that is true for JS. I don't think Crockford thought his remark through.
1. Modern (JS) runtimes have JITs that can generate code almost as fast as C++.
2. You can write purely functional code in JS.
3. JS has arguably less features than R5RS Scheme, which itself is hard to fit on half a page.
In this rant he didn't say Node.js was the solution, or better than any of these crappy abstractions.
Don't assume that. He might not say he doesn't like node.js, but it doesn't mean he is happy with it.
But I do feel that node.js is Rayn's attempt to enlighten me and hopeful others. He doesn't try to hide everything like ports and the underlying c code. Its all there, and best of all in a language that is familiar(at least for web developers).
If you want people to get the performance benefits from using non-blocking libraries, you care.
I think a few months ago, this wouldn't have made sense to me, but now I totally get what he's saying.
On my new app, I'm still using express to do most of the connect-ey stuff, but i've definitely decided that most MVC-ey frameworks are a premature optimization (for me). I'd rather just start with node + express, add in whatever DB I need (Redis / Mongo preferably) and build small and progressively.
My lesson learned... would love to hear other opinions.
There is very little value in trying to draw generalisations from past experiences when it comes to deciding whether to use a framework, and if so, which framework to use.
Unless you're reinventing the wheel, each project will front you with a unique set of challenges. More often than not, with a framework, these problems are awkwardly solved with code written by other people to solve other people's problems.
In my opinion all of this has less to do with what's trying to be achieved than it does with what you personally want to take away from the experience. If your motivation is to make money quickly to feed your family then you would be silly not to jump on something like Rails and ride on the shoulders of giants. On the other hand, if you want to become the most proficient programmer you can become then this path will probably lead you astray.
A quick look around the internet reveals both tiny projects that fail, as well as enormous projects that succeed, on full-stack frameworks such as Rails.
Needless to say if you're hacking on node you are of the latter category; The developer striving to broaden her horizons by exposing herself to the news and unknowns. This won't help you learn to work in a team on a large project. It wil not teach you to control complexity. In fact, it will probably lead you to believe you're learning all these things when you're in fact becoming comfortable with the complete opposite (working alone, hacking in anything, anywhere you feel like).
Generalisations really piss me off.
I whole-heartily encourage anyone who is open-sourcing node.js code to continue doing so. Even if it is Yet-Another MVC framework. Just take note of what ry is getting at here by keeping it mean and lean.
I might be naive, but Go is the only thing that has given me some hope for the future of software development in recent times, it means there is a chance that maybe some day I will be able to write software in an environment and with tools that are not byzantine hideously insane piles of layers gratuitiously complex crud.
Hell, with Go you completely bypass even libc (but unlike Plan 9, you still can take advantage of the hardware and software support of existing operating systems/kernels, that sadly are an unavoidable mess, which is one of the things that made it impossible to adopt in practice).
And that is precisely what gives me hope, Go is going against the trend of almost every other language.
Overall, I don't agree with this.
Complexity arises because what we want to do is complicated. I don't think there's a way around that. Sometimes too much cruft builds up in an area, but that leads to redesigns of specific components. For example, client-side configuration of LDAP and Kerberos has been unreasonably complex for a long time. That didn't lead to people ditching them, that lead to https://fedorahosted.org/sssd/. It's likely that one day we will decide it's best to replace LDAP, just like was done with NIS. However, it won't mean we have to throw out all of linux.
The "users don't care" argument doesn't appeal to me. I don't care what tools the architects used when they designed my apartment building, but if learning some complex math and geeking out over slide rules enabled them do it, I'm all for it. Being told there's something wrong with me because I've changed the settings in my text editor is insulting.
I don't like magic in programming, yet nowadays there seems a move (especially in Ruby with the [over]use of method_missing) that encourages it.
Every level of abstraction above binary code, from assembly, to C, to Ruby, to Rails DSL's--each works by creating magic incantations that let you run larger functionality with a new shorter series of magic words.
Are you really against magic, or is it that you are against black magic (which I would classify as leaky abstractions)?
http://www.joelonsoftware.com/articles/LeakyAbstractions.htm...
For example, try to draw a single black pixel on the screen... using JavaScript, or better yet, some language that compiles to JavaScript. How long would that take you? How many lines of code? How fast does it run? How much memory used by all subsystems combined? How many system calls involved? In assembly language that would be one instruction. And don't tell me that drawing single pixels is unimportant. I can show you any number of hackers who would create extremely cool webapps if drawing a pixel took one assembly instruction.
Yesterday I was looking at a Chartbeat gem that accesses the Chartbeat REST API [1]. The entire class is 40 lines of code, however it's coded so weirdly that you'd have to read the source in order to use it. Every API call was a method_missing call, so instead of doing (in irb)
you'd have to do But I only know that because I had to look at the source code. In addition, there's no way to specify custom exceptions to the user, you have to rely on the rest_client gem's exceptions.The code does look magical, and kudos to the developer that wrote it for the ingenius use of method_missing, but IMHO it's a bit to magical for my tastes. I like to look at a library's documentation and instantly know what methods I'm allowed to call and what exceptions/results I'm going to get back.
[1] https://github.com/ashaw/chartbeat/blob/master/lib/chartbeat...
[1] Edit: Added explanation since, on a second read, it seems like I'm digressing from the topic.
Even the most simplest and straightforward development work is matched to a pattern and implemented as a design pattern.
I think there should be a rule that says if your feature or a particular problem that you are trying to solve does not exceed XYZ lines of code, then it should never be implemented as a design pattern.
Yet to determine XYZ. I would guess XYZ = 200?
Right. Because current attitudes are that if you aren't developing everything purely object oriented with a design pattern or five using nosql for your data store you're a fucking imbecile. I shit you not I've seen a coworker spend half a day adding 800+ lines of get() and set() methods to a 150 line email script. The truly bizarre part is, it's not like he's stupid, or fresh out of school. The guy's a certifiable genius with six or seven years of industry experience under his belt.
This kind of cargo cult bullshit is, in my opinion, the single largest recurring (recursive?) problem in our industry. Unfortunately this isn't a new problem. Every generation of programmers finds some set of development concepts to enshrine as the gospel.
tsort. There we go. I don't hate tsort. pbcopy and pbpaste.
Games, a game delivery system like steam or perhaps vlc for playing my favorite music, but even then, its the music that makes me happy, not the program playing it...
Ont he other hand, there is a lot of software that I actually hate.
The list of software that I actively despise, however, is finite, but unbounded.
I'm not an iPad user but it makes a lot of people pretty happy.
Chrome is usually a pleasure to use. Firefox used to be that way, and they are starting to regain my trust again. I feel good about using Firebug as well.
Skype has some irritations, but for the most part it's still marvelous to open up a video chat to fucking Zanzibar whenever I feel like it.
vim is not always easy, but wow is it rock solid.
Upgrading Debian works very well for me at least, thanks to the miracle of apt-get. Debian itself, well, it's not winning usability awards, but still....
Edited to add: Git. Git is also a thing of beauty. Who knew revision control could be made to not suck? Sure, SVN was a welcome relief from the unrelenting stone faced hell that was CVS, but that's damning by faint praise.
http://en.wikipedia.org/wiki/Ed_(text_editor)
ed went on to influence ex, which in turn spawned vi. The non-interactive Unix command grep was inspired by a common special uses of qed and later ed, where the command g/re/p means globally search for the regular expression re and print the lines containing it. The Unix stream editor, sed implemented many of the scripting features of qed that were not supported by ed on Unix; sed, in turn, influenced the design of the programming language AWK, which in turn inspired aspects of Perl.
And I love AWK too.
I love git, and use it for all of my projects. But my love for git might also be because I have spent so much time on learning it.
Ask me what git merge does, or how to branch, or even how to delete a file in a repository (w/o deleting it from your local), or how to revert back to another version, or how to even check out, and I'll say I dunno. I read the documentation, but am still confused. I sometimes feel like I'm dumb because I feel everyone loves git and everyone gets it. Glad to hear that I'm not alone.
I like and use grep. But, as a programmer, I like ack[1] much better than grep.
[1] http://betterthangrep.com/
And don't even get me started about C the language. It makes me want to go find Ritchie and punch him in the junk.
Why is rsync not a binary linked to a useful librsync? Why STILL TO THIS DAY a grep/egrep difference? And why did Apple integrate Interface Builder -- their best piece of software, IMO -- into Xcode?
Let's not even get into Google.
On the other hand, it's arrogant for one to think that he or she could do it that much better than the next guy. Writing efficient, maintainable, and "simple" software requires adding layers of indirection and complexity. You have to use your best judgment to ask whether the new layer you're adding will make things ultimately cleaner and simpler for future generations of programmers, or will hang like a millstone around their necks for years to come.
Let's try a little thought experiment: go back a few decades to the early 80s. Propose to build node.js as a tool to make it much easier for developers to write real-time network applications. You'll need to design a prototype-based dynamic language, itself an extremely difficult (and dare I say complicated) task. The implementation will need a garbage-collector, a delicate, complicated, and cumbersome piece of code to write. To make it acceptably fast, you'll need to write a JIT, which traces and profiles running code, then hot-swaps out JITted routines without missing a beat. You'll need to write a library which abstracts away event-based IO, like the "libev" node.js uses. That will require kernel support.
Frankly, even forgetting about relative CPU power at the time, I think you'd be laughed out of the room for proposing this. All of these things, for production systems, were extremely speculative, "complicated" things at the time they were introduced. People can't predict the future, and they obviously have difficulty predicting what tools will become useful and simple, and which will become crufty tarpits of painful dependencies and incidental complexity. No one in 1988 could say "a dynamic, prototype-based, garbage-collected language paired with a simple event model will allow developers to create simple real-time network applications easily in 2011". Many of them probably had high hopes that C++ templates would deliver on the same vision by then. But, instead, we have Boost.
Further, it's extremely arrogant of Dahl to create a dichotomy between those who "just don't yet understand how utterly fucked the whole thing is" and those, like him, with the self-proclaimed power of clear vision to see what will help us tame and conquer this complexity. Who knows, maybe in 15 years we'll be saddled with tons of crufty, callback-soup, unreliable node.js applications we'll all have to maintain. I don't think James Gosling envisioned the mess that "enterprise Java" became when he designed the initial simple language. Most developers do many of the things he cites, like adding "unnecessary" hierarchies to their project, because they believe it will help them in conquering complexity, and leave something simple and powerful for others to use down the line.
Ryan is right. Most of the software we use is crap. That's because Worse is Better.
"Node is fucked too. I am also one of these people adding needless complexity. ... The entire system is broken - all the languages and all the operating systems. It will all need to be replaced."
I am not a node.js user.
Other than that, I agress with pretty much everything you said. It's easy to forget how reliant we are on things like industrial-strength GC, multithreading and JIT and how young those things really are.
Oh, hell, just watch the Mother of all demos (1968): http://www.youtube.com/watch?v=JfIgzSoTMOs
It's not arrogant of him to think like this. It's more like Steve Jobs, circa 2006 thinking phones sucked and deciding to do something about it. Or maybe it's like Steve Ballmer thinking he could take over the phone market. I think it's too early to say for sure, but the early signs are promising.
So, what is the trolling here? The lack of serious tone in the comment?
Never fails to amaze me what users will do with a software tool.
I've seen experienced devs and support staff run a C program written to parse some weird data against another data set in the vain hope that it would parse the new data set into something usable.
I've seen MBAs who could barely tell you what a variable is write visual basic macros in Excel to do hardcore data management.
Game devs who almost seemed to frickin' think in OpenGL.
It is a big ball of mud (turtles all the way down, eh?), but on a good day, I listen to a hacker talk about finally getting that little piece of code beat into submission and it's very satisfying just to see that gleam in their eye.
Just how much reliance we put on autoconf really makes me shudder.
I don't know a whole lot about rails, so this is conjecture, but I imagine this is why ruby on rails is so popular: you don't need to know very much to get it going.
I get why complexity is disliked(/feared?) by some people, but unless you've got a better workable solution that you're ready for me to try out, your rant is just noise to me.
I've often found myself begrudged by the complexity of a piece of software, but that doesn't make me think we should throw the entire program out. How about we make it easier to use instead?
Pointing your finger and making noise will draw attention to the issue, but isn't likely to fix it on it's own.
dbus
/usr/lib
Boost
ioctls
SMF
signals
volatile variables
prototypal inheritance
C99
dpkg
autoconf
LD_LIBRARY_PATH
/usr
zombie processes
bash tab completion
dynamic linking
static linking
glib
the details of programming languages
formatting source code
configuring window managers
configuring editors
unicode
directory hierarchies
What he's saying is, "Where are better abstraction mechanisms?" And that's a tremendously important question (whether you get it or not).
There are better abstraction mechanisms.
http://www.freedesktop.org/wiki/Software/dbus
Should no programmers have to know about inter-process communication? Is dbus a bad IPC mechanism? Is IPC itself a flawed concept?
Those are interesting questions, because we can ask why and look for alternatives. Ryan's post and your response, not as interesting.
DBus as an implementation of messaging largely sucks. It uses an ad hoc protocol, there's little security, the C library implementation of it is a big mess, the socket interferes with remote X, introspection doesn't really work, and it uses far too much XML.
I hate all cars, especially my own. I hate that heavy, dangerous, gas-guzzling honda civic with an over-sensitive brake pedal and enormous, completely pointless blind spots over both shoulders. I hate filling it up with gas, which is expensive, smelly, and bad for the environment. I hate the dishes that I have to wash every day after I use them. I hate my Aeron chair that I sit in all day long. I hate peeling grapefruit. I hate the sound of my central air conditioning fan powering up. I hate how I'm either sore from working out or depressed from not working out.
There's nothing wrong with a rant now and again but let's recognize it for what it is.
Life is pain, Highness. Anyone who says differently is selling something.
Furthermore it is a physical limitation for how much software you can write (and have it work) if you can get something that "mostly works" by building on top of yesterday's cruft then you do it, since the alternative is starting over from scratch and not being able to finish.
One of the more intriguing comments I've seen on HN. Care to elucidate?
Blaming "human ineptitude" is pessimistic. Sure, the fact that humans can't all manipulate computational machines directly and require layers of abstraction to effectively model problems can, technically, be called ineptitude, but really-- why be so down about it? That's the way things are and there's a lot of good that comes from software if you think about it for more than 30 seconds.
Human ineptitude is a part of our physical environment. We're just animals. Clever ones, but not perfect.
For example my brand new Hyundai Sonata has pretty shitty rear visibility due to it's 'sleek' styling and therefore smallish rear window. I could cite many more.
It's more than the mirrors, and unless you have transparent pillars on top of the car (giving up the structural integrity of the cabin) it's going to have blind spots.
You should actually have them a lot farther out such that visibility in your side mirror coincides with losing rear-view visibility. That position is a lot farther out than most people think and is tricky to do the first few times.
The average Javascript developer using node.js DOES NOT have to "deal with DBus and /usr/lib and Boost and ioctls and SMF and signals and volatile variables and prototypal inheritance and _C99_FEATURES_ and dpkg and autoconf", because Ryan and other node.js devs already have thought about it for them, and introduced a helpful and practical layer of abstraction on top of all this complexity.
As a result of having to think about it all day, every day however, it's understandable that Ryan would despise this kind of stuff. On the other hand, as a web developer that uses the result of his hard work, I am not affected by it at all, so the complexity of my work is substantially reduced.
"For example, essentially all of the standard personal computing graphics can be created from scratch in the Nile language in a little more than 300 lines of code. Nile itself can be made in little over 100 lines of code in the OMeta metalanguage, and optimized to run acceptably in real-time (also in OMeta) in another 700 lines. OMeta can be made in itself and optimized in about 100 lines of code."
http://www.vpri.org/pdf/tr2010004_steps10.pdf
and, btw: https://github.com/tristanls/ometa-js-node
Most people won't change their mind about anything, unless everyone else already did. Therefore, (Kay concludes at 24:00), truly new ideas take at least 30 years to become popular.
STEPS is too young. At this pace, wait for at least 20 years.
Is there some similar proof for ometa ?
- TCP-IP in 200 lines. Current C implementation use 10Kloc (50 times more).
- Most of Cairo's functionality in 500 lines. And it's fast enough. Cairo on the other hand weighs about 40Kloc. (Again, about 50 times more code.)
And that's for functionality they couldn't scrap altogether, or merge those with similar capabilities. For instance, you don't want to send emails, or publish a web page, or print a PDF, or, goodness forbid, a Word document. You just want to handle a fucking document. Send it, publish it, whatever, this is all glorified text (you do need the glorification, though).
The bottom line is, Alan Kay and his team rule.
Ultimately we are developing the software because of one simple thing.
The user.
Programming languages, their frameworks, their libraries, their petty concerns are a mere vanity folly, riddled with re-invention, abstraction arcana, and deus-ex-machina hoopla. We have lost our way, straying so far from the path of the UNIX philosophy such that I must now 'whole-stack' an application instead of using the pipe character. A pox on the whole damned lot of it!
Some days I just despair of all the time I've wasted bustling and jostling, crushed by the sweaty masses in the ghetto. But if I'm honest with myself, I must confess I love it too. I love my programming languages, my libraries, the eight different ways I know to full-text search, to regex, to parse, to lock, to async. I love the smell and heat of the coal-face, the futility of it all. Stockholm Syndrome indeed!
There is so much more that could be done with operating systems in any direction you want to go. I'm thankful that doing things on my iPad doesn't involve messing with command lines. But for when I want hackability I'd rather have what a Lisp machine could have become than a silly way to do functional programming in shell.
Which means rewriting crufty pieces of your stack when certain thresholds occur. 'There will come a point where the accumulated complexity of our existing systems is greater than the complexity of creating a new one' -- is something that happens in motion, iteratively, and which you do when you have time at all levels of the evolution that we call development.
Anyway, that's my two cents. Nice others are on the same wavelength, I think.
To be regarded the same way as a long relationship with a cranky friend, maintaining an aging specimen tree, or a historic house.
Do you cut the branch off, or just prune it back a little?
Software needs to be complicated because the tasks that it performs are complicated. The only way human programmers can deal with this is abstraction on abstraction on abstraction. This will only becomes worse as software handles more "real world" things such as formerly hardware tasks.
Unnecessary software complexity is added due to maintenance, where the maintainers added extra complexity because they weren't able to integrate the changes into the current design and/or didn't understand it well enough. Probably a better job could be done with better tools/documentation in this case. Not by ranting at developers though.
His rant about UNIX is crazy. Any full-featured operating system necessarily is complex under the hood. If something randomly doesn't work in his favorite OS he also has to spend hours googling, diving into obscure settings managers, etc.