Live data from Hacker News

Software disenchantment

tonsky.me

81–90 of 98 posts

Re: Software disenchantment

#82
Software is typically written to serve some business need, and when crappy software serves that need it's incredibly difficult to convince the organization to invest more in quality. However, being asked to crank out half-baked features, poorly tested code, and poorly designed systems takes a toll on programmers who want to be proud of their work.

So what is a programmer to do? I feel like buyers and sellers of software are each cool with the status quo, so who has incentive to improve?

Re: Software disenchantment

#83
post #65

Article tl;dr: "I believe that apples are more efficient than oranges after all." I just want to point out that the idea that "modern buildings use just enough material to fulfill their function and stay safe under the given conditions" is fundamentally at odds with the author's subsequent thesis. Modern buildings don't use "just enough material", because "just enough material" would be _just_ concrete everywhere; it…

You don't need a web browser to edit text. As evidenced by dozens of excellent text editors that are not built on web browsers.

It's just easier to take a web browser that already has something approximating a text editor, and pile things on top of that.

And why is that? Well, because you want to support all the different platforms, and we as an industry have absolutely screwed up the portability story, and so we build it as hacks instead. There's absolutely no reason why developing a GUI app for macOS should be radically different from developing a GUI app for Windows or Linux - they all ultimately do the same thing. There's no sensible reason for them to be different. But they are. And so now the easiest way to solve that problem is to pile the browser on top, and forget that the differences exist. Of course, it doesn't actually solve the problem in general, because the differences are still there, and the industry as a whole still pays the overhead tax, in both man-hours of work someone has to spend maintaining that flimsy stack of abstractions, and in runtime performance tax those abstractions impose.

But the only way to fix it is to burn the whole thing to the ground. And that's not happening, because the short-term cost is too large to even contemplate any long-term gains.

Re: Software disenchantment

#84

I put some of the blame on an unhealthy insistence of code reuseability and sticking to paradigms. The result is so much code that is just abstractions piled onto abstractions piled on to more abstractions until you get the famous FizzBuzz Enterprise Edition [0] that I'm sure we've all seen by now. Nobody wants to just write some god damn code anymore. They include entire frameworks instead of just writing a couple h…

> include entire frameworks instead of just writing a couple helper functions > unhealthy insistence of code reuseability

The problem you're alluding is that until recently, there was very poor support on the web for the equivalent of Unix strip[1] or Proguard[2] (often used by Android devs). We need reliable and accurate dependency analysis to be able to properly eliminate unused code.

Today, with ES6 modules and a recent version of webpack, this is partly possible. Unused modules are not included in the final output file. I noticed a drastic drop in the final minified JS file size, after moving to a configuration that enabled this sort of (module) stripping.

[1] https://en.wikipedia.org/wiki/Strip_(Unix)

[2] https://stuff.mit.edu/afs/sipb/project/android/sdk/android-s...

Re: Software disenchantment

#85

I put some of the blame on an unhealthy insistence of code reuseability and sticking to paradigms. The result is so much code that is just abstractions piled onto abstractions piled on to more abstractions until you get the famous FizzBuzz Enterprise Edition [0] that I'm sure we've all seen by now. Nobody wants to just write some god damn code anymore. They include entire frameworks instead of just writing a couple h…

> include entire frameworks instead of just writing a couple helper functions > unhealthy insistence of code reuseability The problem you're alluding is that until recently , there was very poor support on the web for the equivalent of Unix strip[1] or Proguard[2] (often used by Android devs). We need reliable and accurate dependency analysis to be able to properly eliminate unused code. Today, with ES6 modules and a…

Those shouldn't even be needed.

To give an example, let's say you need to calculate SHA-256 hashes in your program. People would rather include the OpenSSL library than just add a SHA-256 function to their code. Instead of a single function (that maybe has a couple helper functions), they add a massive library full of features they don't need, taking up memory, bloating the executable size, and increasing load time.

If you're using less than 10% of a module, you should be questioning if you even need that module at all.

Re: Software disenchantment

#86

Earlier quoted context omitted.

> include entire frameworks instead of just writing a couple helper functions > unhealthy insistence of code reuseability The problem you're alluding is that until recently , there was very poor support on the web for the equivalent of Unix strip[1] or Proguard[2] (often used by Android devs). We need reliable and accurate dependency analysis to be able to properly eliminate unused code. Today, with ES6 modules and a…

Those shouldn't even be needed. To give an example, let's say you need to calculate SHA-256 hashes in your program. People would rather include the OpenSSL library than just add a SHA-256 function to their code. Instead of a single function (that maybe has a couple helper functions), they add a massive library full of features they don't need, taking up memory, bloating the executable size, and increasing load time.…

If I understand correctly, I think you're suggesting they copy the functions they need from the library into their own source tree.

I think that makes sense for something simple like left-pad, but I don't think it's advisable in most cases. For instance, the SHA-256 function is non-trivial[1]. Even thought it's just around 100 lines, it's a fairly intricate function, and I would want to use a library for it. Preferably a heavily-used library like OpenSSL.

Using a library reduces the size of my own code base, and places the responsibility for fixing bugs and optimizing the SHA-256 with the open source community / the maintainers of the library. SHA-256 is particularly interesting, because modern Intel and AMD CPUs have dedicated instructions[2] for performing it. If I copied the source code for SHA, and later the library was updated to use the x86 instruction if available, then I would lose out on this performance gain.

Ultimately, the solution should be in constructing reliable and correct dependency management systems, and using the operating system's dynamic/shared library infrastructure to not bloat code size.

Modern operating systems are incredibly efficient when it comes to DLLs/shared libraries. They load up the DLL only once, and every subsequent program that needs it reads off the same shared memory pages for the DLL. Whenever, some data (in the shared library), it forks that memory page alone for the process. It's incredibly efficient, and except for the first time the library is loaded, it is fast at loading.

I think due to a fear of the so-called "DLL Hell", at some point people decided to statically link everything, and create giant executables. The smart solution would have been to find a solution to the dependency hell problem (where a good start would be simply versioning .so/.dll files).

The limitation to this approach of course is that using (.so/.dll) shared libraries is only possible with native programs. Although, I think with web pages/apps, if you link to the same resource (script/CSS/etc) in multiple pages, the browser should only download/load it once; with a request sent to server to see if the resource has been modified (getting back a "304 Not Modified" response most of the time).

[1] https://www.movable-type.co.uk/scripts/sha256.html

[2] https://en.wikipedia.org/wiki/Intel_SHA_extensions

Re: Software disenchantment

#87
post #66
post #51

Love this article. I gave an internal talk recently that was about the sad state of programming right now. How we used to set a variable in assembly language: mov [foo], ax How we do it in React / Redux // constants.js export const SET_FOO = 'SET_FOO' // actions.js import { SET_FOO } from './constants' export const setFoo = foo => ({ type: SET_FOO, payload: foo }) // reducer.js import { SET_FOO } from './constants' c…

This is extremely hyperbolic, and I'm sure you know this. Here's how you set a variable in React: const foo = 1; What you're doing in your complicated sample is not _just_ setting a variable, you're also exposing it to a KVO subscription system that you could never represent succinctly in ASM. What's sad is how programmers communicate programming concepts right now, with quick digs and hot takes and zero actual criti…

Yes, it's an apple to oranges comparison, but the point is more why are we using an orange when an apple will suffice?

The real question is, is all that really needed?

We keep building abstraction layers on top of abstraction layers when often times, there is already tried and proven solution that works and is much simpler.

I've been doing some experimenting creating a single page application (SPA) without a web framework and turns out you can get 90% of what React offers with a tiny amount of code.

https://github.com/brennancheung/volgenic/blob/master/13-IDE...

My current iteration is just to do a:

    State.update(() => { state.foo = 123; state.other = 456;  })
I just use plain javascript objects to store data and wrap it in a function that will trigger re-rendering the VDOM / repaint.

And even if we do need that additional layer of abstraction we can always make it appear simpler and provide a cleaner interface to the programmer. A Proxy object setter could be used to eliminate the boilerplate of State.update.

Good abstractions simplify the problem by creating a mental paradigm that is closer to the problem domain. Poor abstractions do the opposite, they take away what is needed to solve the problem and create additional steps that are not really germane to the problem.

Many abstractions are well intentioned, but after we toss layer on top of layer, we often get so far removed from the problem domain, we have to ask ourselves if it is not simpler to just build up another set of abstractions that allow us to get closer to the problem domain (i.e., "First Principles").

Re: Software disenchantment

#88
post #25

I agree that something is out of whack. In-house plane-jane CRUD development used to be pretty simple and quick in the 90's. One could focus on the domain analysis side instead of micromanage tech. The IDE products had glitches, but got better every release, including deployment. The Web bleeped it all to heck and back, and nobody seems interested in promoting the standards to fix it. We toss in JavaScript gizmos to…

> We toss in JavaScript gizmos to attempt to improve the UI to desktop standards, but these gizmos are clunky and browser-version-sensitive. Agreed! doesn't anyone know how to write vanilla JavaScript anymore? relevant: http://vanilla-js.com/

Pretty hard to learn vanilla JavaScript when you're stuck in the mud 8 abstractions above it, trying to keep up.

Re: Software disenchantment

#89
I can think of many reasons to deliberately create software that is inefficient. Number one on the list is to make it more reliable. The number one reason software is rarely reliable is because code is more often than not complex to the point where the developer unsure whether it will work or not. In turn, this occurs most often when trying to maintain state via flags. If, instead of trying to maintain state, the software is designed so that the current state of objects is always a function of the original state of the object at the time the App started, you have an App that is potentially slow but like to be extremely reliable and extremely easy to read.

I always program this way these days and my Apps are always reliable. For example ToteRaider (see Toteraider.com), a complex gambling App, released 2.5 years ago is still on version 1. Zero defects in production and also zero defects in testing.

Re: Software disenchantment

#90
I couldn't agree more. I was a maintenance programmer/developer for 30 years and saw too much of this. It disgusted me to the point where I just rewrote entire systems during slow periods (unauthorized and on the sly). The Amiga OS had full multi-tasking with robust, inter-process messaging, and a full-featured windowed GUI that fit onto one 720K floppy so there is no valid reason that we need multi-gigs for the current version of Windows. I'm posting a link to your excellent article on Daniweb to encourage discussion.

Reverend Jim (on Daniweb)

Post reply on HN