
We’ve built a towering pile of shite - edent
http://shkspr.mobi/blog/2020/06/weve-built-a-towering-pile-of-shite/
======
afandian
I recognise this, and its cousins, from the JS world. It seems to say "how can
we possibly innovate without churn!".

But I have been absolutely bowled over, and inspired, by the Rust tooling. Not
only helpful error messages, but hints about misunderstandings you might have
had, along with concrete suggestions on how to fix it.

I feel like it corresponds to the highly rigorous thought that has gone into
the language, which also results in a great language irrespective of the
tooling.

Thank you Rust team.

~~~
masklinn
> I feel like it corresponds to the highly rigorous thought that has gone into
> the language

I'd say it's less about _rigorous_ thought, and more about being willing to
spend time on purely _user-centric_ things.

You can have both of course, but surely things like proof assistants have a
lot of _rigorous_ thought put into them, yet the error reporting is usually
horrendous.

Improvements to Rust's error reporting is the result of a specific and
dedicated effort in that direction: [https://blog.rust-
lang.org/2016/08/10/Shape-of-errors-to-com...](https://blog.rust-
lang.org/2016/08/10/Shape-of-errors-to-come.html) (and
[https://internals.rust-lang.org/t/new-error-
format/3438](https://internals.rust-lang.org/t/new-error-format/3438) and
[https://web.archive.org/web/20160807033841/http://www.jonath...](https://web.archive.org/web/20160807033841/http://www.jonathanturner.org/2016/08/helping-
out-with-rust-errors.html)).

And note that the new errors didn't really provide more information (at least
initially), instead they formatted the information better, removed
redundancies and noise, and called out the relevant bits more clearly. This
runs very much opposite of "rigorously" dumping all the stuff you have and
letting the user sort it out.

~~~
afandian
You clearly have more experience with Rust than I do, and maybe you set the
bar for 'rigour' higher!

In languages like Python, where you might run into an issue caused by not have
implemented an arbitrary method on a callback, or Obj-C where you might have
forgotten to implement a delegate, you're on your own as far as the compiler
is concerned.

Yesterday my Rust code didn't compile because I was missing a bound on a type
parameter on my function that I passed though into the key type of a hashmap.
Rust said "hey maybe you want to add this constraint to your declarations".

Some of this you can put down to dynamc vs static. But beyond that, it's clear
that the designers and contributors haven't just said "we want to make a
language with great safety" but then went on to ask "what specific ergonomic
challenges will this bring to users, and how do we help them" .

I don't think you could get those ergonomics from many other languages, even
if you wanted, without extra static analysis.

(edit: lazy typing on a phone; in the last para I was referring to the
mainstream languages like Python rather than the whole universe of languages.)

~~~
masklinn
> I don't think you could get those ergonomics from many other languages, even
> if you wanted, without extra static analysis.

You absolutely could. Hell, languages which are much simpler to analyse have
worse error reporting, and the language which started the movement of having
less shite error message is a fairly simple one: [https://elm-
lang.org/news/compiler-errors-for-humans](https://elm-lang.org/news/compiler-
errors-for-humans)

~~~
afandian
That was a typo on my part -- I meant languages like Python, not the whole
universe of languages. Of course anything is possible, I'm sure there are very
good languages out there, and that Elm is one of them.

------
ashtonkem
The popularity of Gradle utterly baffles me. It is one of the most infuriating
tool I have to deal with, and the one I most regularly flail around with
trying to find out the magic song and dance that’ll make it happy. The
existence of two separate programming languages has made the doc situation a
nightmare, and I genuinely do not understand why I have to use a real
programming language to configure my build.

~~~
jacobn
Why do I have to learn a second programming language just to configure my
build? /s

Builds need Turing completeness surprisingly often. Build languages then
expand to accommodate, with spaghetti disasters as the result.

“But it has to be accessible to new users and can’t be tied to just one
language” said SBT as it jumped the shark with its .sbt files.

Sigh.

Developers get crap tools because developers won’t pay for tooling - if it’s
not open source and free we don’t touch it outside of an enterprise
environment. And Lo and behold, most tooling is either cobbled together by
Enthusiasts, or as user friendly as enterprise ware usually is.

(There are, of course, shining exceptions to this, which is great)

~~~
ashtonkem
What’s frustrating is seeing new communities and languages make unforced
errors that a review of prior mistakes should easy uncover. The lack of a
unified, coherent build tool in Java was a _huge_ mistake. New languages would
be well advised to focus on good tooling right out of the gate, rather than
putting it off until later.

~~~
EdwardDiego
Maven has never really been displaced - Gradle only has traction in Android
dev, for some reason it became the blessed-by-Google solution.

Even when I'm writing Scala I prefer Maven to SBT, I just prefer declarative
build tools to DSLs up in my grill.

~~~
ashtonkem
In my limited experience, Gradle is increasingly popular for Spring Boot
applications.

------
McDev
"[Android] development tools are focussed on large teams of highly trained
software engineers, who all intimately understand every esoteric aspect of App
development."

This really rings true to me. I almost cringe when I have to explain how to do
some of the most basic things to non android developers.

Aside from the dozens of libraries you need to include, and need to know where
to find and what version is compatible with what, the tooling itself is an
insurmountable mess for new developers. It's also not getting any simpler.

~~~
skohan
I have to admit I often roll my eyes at the state of mobile development,
especially on Android. I worked on a few Android apps in 2009-2012 when a
"best practice" hadn't really been established yet, and as I tangentially
follow the field now it's hard to understand how insanely complicated it's all
become. I mean literally for 90% of apps we're talking about doing some REST
requests and populating some text and images on screen. Why dozens of
libraries are needed to achieve this I cannot understand.

Like I was interviewing a guy for an Android role, and he was walking me
through a pet project of his which consisted of literally one list view which
updated it's contents to filter results out of an SQLite database as you type
into a text field, and the project had literally dozens of files. It just made
me sad.

I mean maybe there is something I don't understand, but the state of the field
seems to be heavily driven by following what the "cool kids" are doing, and
the tooling seems to have more to do with signaling that you're in the in-
crowd than it has to do with actually delivering value.

~~~
ohgodplsno
>Like I was interviewing a guy for an Android role, and he was walking me
through a pet project of his which consisted of literally one list view which
updated it's contents to filter results out of an SQLite database as you type
into a text field, and the project had literally dozens of files. It just made
me sad.

That's most likely overengineering. The only things you need for this are:

\- An Activity

\- Eventually, a Fragment, but you can do your work in the activity directly

\- A database, optionally in another file to abstract out direct queries, but
it can simply be direct SupportSQLite queries. Just, not on the main thread.

\- A viewmodel if you don't want to hate yourself and write logic in your
Activity, making it basically untestable.

\- A layout file for your activity/fragment.

\- A layout file for your recyclerview list element

That's 5 files. 6 if you include build.gradle, 7 with AndroidManifest.xml

This can all be written in under 500 total lines.

Library wise, all you need for that is androidx and recyclerview.

~~~
arexxbifs
I honestly can't tell if this is a joke? 0.5 KLOC. Seven files. That's not
over-engineered?

~~~
ohgodplsno
A lot of that is due some Android APIs being insane. Amongst all of those, the
RecyclerView adapter will be over a hundred, because it is a stupidly verbose
API. Layouts are XML, so, yeah, stupidly large too. Those two contribute to a
lot of those lines. Not so much overengineered as lol-google-apis engineered.
ViewModels are also due to the batshit insane android lifecycle, where you can
easily be bitten in the ass. All of those are not for fun. They're because the
Android APIs are terribly crap, or because you're not allowed to do certain
things on the main thread (like, say, database queries)

After that, you can very well put your activity/fragment/database logic in the
same file, if you know you're never going to maintain it.

~~~
noema
"Best practice Android development" is soon to phase out XML (for the most
part) with Jetpack Compose. Working with two way data binding in XML seemed
like a good idea, until you had to debug it.

~~~
ohgodplsno
"Soon".

Compose is still in dev builds. Expect to see alpha in a few months, betas in
two years and RCs/Release in three. Not exactly "soon".

------
me551ah
Compared to Windows, iPhone, and Android. Android has the worst tooling
environment of them all. You would expect a big software company like Google
to know better, but you'd be mistaken.

All others provide you a native simulator that you can use to ease development
( Windows even provided one for Windows Phone). Android provides an emulator
that gobbles up RAM and is painfully slow to use. Most people just prefer to
use their local device instead.

Other platforms provide you their own IDE tailor-made for development. Google
just took IntelliJ and made some changes it.

Edit: Another point is compile times. Compile times for Android are just
atrocious. While Windows and iOS compile quickly in a few seconds and allow
you to fast deploy, Android is painfully slow taking over a couple of minutes
for compilation.

~~~
jeroenhd
> Android provides an emulator that gobbles up RAM and is painfully slow to
> use.

That's not my experience. The official Android emulator works just like any
emulator and will take the RAM it needs to run like a real device. If you
don't have the RAM to emulate a smart phone (which these days contains
anywhere between 6 and 10GB of RAM it seems) while also running the debug
tools, you can always lower the RAM you give the virtual device. Android will
run on 1GB of RAM though it won't be pretty if you want to emulate interacting
between different apps and such.

Oh, and there's a potential gotcha in that Android does a lot of stuff on the
mobile GPU, so GPU acceleration will make a huge difference. You don't need a
2080Ti to run the emulator, but integrated Intel graphics are often not up for
the task. On my laptop the Intel drivers were also flagged for
incompatibilities because of unresolved issues with the driver themselves,
making Android run on software rendering and oh boy what a drama that was.

The big problem isn't so much the emulator, it's the IntelliJ-based IDE
combined with the java compilers that gobble up RAM worse than Chrome. Each
compilation process can quickly grow to 2GB and release it soon after,
torturing your OS's memory manager.

My experience running and debugging the emulator with 16GB of RAM have been
quite good. 8GB is doable if you don't have too many tabs open and tune your
emulator.

The biggest problem I have with Android development is that compiling even a
small app takes over a minute in my 7700k.

As a fan of IntelliJ, I applaud their choice of IDE. They used to base their
IDE on Eclipse and that was clearly not worth it. As for dedicated IDEs,
unlike Microsoft and Apple, Google didn't have an existing IDE lying around
for their purposes. When someone did make an IDE from scratch, Xamarin, I
found it worse in every single aspect aside from language support. And let's
be honest, while Visual Studio is probably one of the best end-user facing
pieces of software Microsoft still maintains in-house, it wasn't __that
__great. Typing latency is high, configuration is painful and error messages
are vague. Many, if not most, dotnet devs run the Jetbrains tools to enhance
their VS experience.

~~~
me551ah
I agree that it works just like any other emulator, but the competition offers
simulators which take up far less resources. Google did start work on a
simulator which went by the name of 'Arc Welder' and while it seemed promising
it was discontinued soon after.

And I wholeheartedly agree with your point about compile times and have added
it to my comment.

~~~
jeroenhd
Windows Phone used the same model as Android, only Windows Phone devices never
got to the point where they came out with over 4GB of RAM.

iOS doesn't actually emulate most of the system though, which is why it can
run on so little RAM. Apple repurposes the shared components running on macOS
to do the heavy lifting of iOS emulation. Their approach, in my opinion, is
closer to a Docker container with a display than to a traditional emulator.

This is also why it's technically impossible to port the iOS emulator to
Windows or Linux even if they were willing to give up their vendor lock-in.

I haven't worked with the iOS simulator for long, but I found some features
the Android emulator offered missing in iOS. There was no installing apps
(like WhatsApp, to test sharing) and the tooling for faking following a
recorded or generated GPS path were either impossible for me to find or just
not there. I also found that the "OS" inside the simulator felt bare-bones and
incomplete whereas the Android emulator comes with the complete toolkit,
including Google Play. iOS simulation is faster than Android emulation, but in
my opinion that comes at a cost.

It's possible to do the same thing on Linux through Anbox, though that might
not have all the same API's. The Android kernel is quite different from the
Linux kernel it was once just a fork of and on Windows you'll never see the
same level of integration with Android that iOS has.

------
biddlesby
I see this argument a lot: in the "good old days" there was Unix and apt and
it was brilliant, now we have hundreds of toolsets and libraries that are
flaky and need updating every year.

I think what these arguments miss is the upside of today. The "good old days"
of brilliant developer experience was only brilliant for a small number of
people. You had to learn right way of thinking, invest the right amount of
time to learn good principles, how Linux was architectured, how not to re-
invent the wheel, and so on.

This was a huge barrier to many people getting started with coding and the
economics demanded getting more new developers ramped up faster. This pressure
caused people to try to quickly develop little "get started quick" ecosystems.

Now we are in a situation where from a pure software engineering perspective
we do have a complicated stack of teetering and shifting frameworks, I agree.
But on the other hand this has come with enabling an awful lot more people to
_quickly_ get started toying with apps and coding.

What I'm trying to say is, these days its quicker to go from Level Zero to
Level One, even if that means you've shot yourself in the foot going from
Level One to Level Two.

~~~
tekstar
The good old days were terrible!

Uncompress tgz

./configure.sh

Missing dependencies

Find those tgzs

./configure.sh

Missing dependencies

Find those tgzs

One won't run on your system

Try to hack the dependency out

Give up, you didn't really need that anyways

~~~
speedgoose
The old joy of watching logs of a stupid GNU script checking basic features of
the GNU C compiler. Just in case someone installed a compiler that had a
different implementation.

~~~
dTal
And it checks them _before_ checking for missing dependencies, so every time
you fix a dependency, you have to do the whole rigamarole over again.

~~~
m4r35n357
Yeah hitting the up arrow a couple of times then return is a real pain.

~~~
dTal
I was referring to the tedious wait for the configure script. It might not
seem so bad now, but what's a mild annoyance on modern computer with an SSD is
quite the interruption on a few hundred MHz and spinning rust.

Another thing I wish it would do is give you all of the missing dependencies
up front. Aain, not so bad now, but it was a major hassle for me when a
missing dependency meant a long walk to the local library, 4gb flash drive in
hand.

------
Tade0
_Why don’t our tools do the hard work for us?_

This is the main appeal of Rust to me.

I get error messages that contain the word "perhaps" with a gentle suggestion
on what I might have wanted here instead. Quite often it's correct.

------
nromiun
I agree with most of the post but this line confused me.

> The compiler would say “Missing semicolon on line 427.” To which I’d reply
> “If you know what is missing, and you know where it is missing, why not add
> it back yourself? You useless piece of crap!”

How can you add a feature like this without any extra complexity?

It sounds great in theory but in practice most code depend on another piece of
code. Most of the time blindly changing one line can introduce more bugs.

~~~
berkes
I really like how Rust does this.

"Expected a colon here, found a <" (ascii-art pointer to the place) "did you
forget to close a bracket here?" (ascii-art pointer to 12 lines above that,
where, indeed you forgot to close a bracket.

It does this for semi-colons (they are not always required), closing brackets
(maybe you are nesting something horrendously deep?) etceteras.

The idea, basically is "I see this is wrong. But I'm not the one to decide how
to fix it for you, but here's a suggestion".

I love Rust for this.

~~~
fludlight
Perl also did this in the late 90s. "Possible runaway quote on line 123"

~~~
shoo
I remember being baffled for an hour or two after accidentally putting a
trailing opening { in a c++ file and then getting thousands of compilation
errors all through the standard library headers my application included.

------
dilap
One of the Go un-features that is so very nice -- the very first Go code I
ever wrote, 7 years ago, still compiles perfectly.

It's great to not have stuff just rot behind your back.

(True for the language, not quite true for the ecosystem, since the switch to
modules fucked a lot fo shit up, with some tooling _still_ not back to pre-
modules levels of quality.)

~~~
mmargerum
I dread opening up older swift projects because I know they aren't going to
compile. Go is a breath of fresh air.

------
tempodox
This post does put the finger on one widespread problem: Bad error messages.

When you're designing an error message, don't just tell the user that
something went wrong. The mere fact that they're getting an error message
already conveys that. Instead, concentrate on telling them what is being
expected or what they can do to fix it.

~~~
catlifeonmars
Totally agree! I have to say, as an author of preprocessor/compiler
toolchains, I’ve struggled a lot with designing error reporting in a way that
maintains abstractions in the toolchains, but still produces useful error
messages. Oftentimes, I’ve fallen back to hard coding error messages that
assume a particular code path. I’d be really interested in seeing examples of
error reporting patterns that work well across multiple levels of abstraction.

------
sradman
In the bad old days when software shipped in boxes, one of the most important
roles on a software team was that of "Build Master". The holy grail was
reproducible builds that generated identical binary build artifacts. This was
achieved with two principles:

1\. Identical toolchain. 2\. Identical dependencies.

These two principles still apply, at least for the toolchains that produce
binary/bytecode/bitcode artifacts, and we have much better tools to achieve
these goals.

Since VMWare became popular, virtual machines have made the goal of
maintaining identical toolchains trivial: we simply maintain snapshots of the
machine image used for the builds.

The Web, or more specifically the HTTP transport, has made dependency
management infinitely better. The Web has changed the world but it seems that
the software development community has not imbibed the RESTful principles
described by Roy Fielding. URLs, especially for software dependencies, should
be forever. Support for URL forwarding should be a requirement for package
repositories.

I am also flummoxed that the Cache-Control and Concurrency-Control built into
HTTP is not leveraged. We have conditional requests that use ETag or Last-
Modified headers and the Content-MD5 header has been part of HTTP for a long
time. As far as I am aware, Software Configuration Management tools tend to do
the same thing out-of-band. ETags are opaque, but if I was designing a new
package repository, my ETag would be the SemVer, optionally annotated with the
target architecture for binaries.

------
jorams
Android (Studio) seems extra bad in this regard. I once decided to start a new
app project, and it instantly didn't build because the generated build
configuration was referring to incompatible versions of different components.

I thought the entire point of automatically generating boilerplate was that
you could ignore it until you needed something other than the defaults. When
all of that magically introduced complexity is _wrong_ , why make me start
with it in the first place?

~~~
DangitBobby
This was also my experience when I wanted to try my hand at app development.
The tutorial wouldn't build. Decided that I didn't want to be beholden to an
ecosystem like that.

------
parhamn
Unpopular HN opinion: we need more commercial SWE tools. This is the expected
outcome of under-organized underfunded ad-hoc development of professional
tools.

~~~
carapace
Hmm, if you put it like, "We should pay for quality tools." I think it comes
off less unpopular maybe?

~~~
mumblemumble
I find that it's nearly impossible to argue for this when it matters. It's
kind of magical how the reasoning works. We can't increase development
capacity by paying for more person-hours, because developer time is far too
expensive. We can't increase development capacity by paying for more
productive tools, because developer time is basically free.

~~~
carapace
I've noticed that too! It's like basic business principles are warped in the
presence of too many computers.

------
voodootrucker
If you don't like churn, avoid anything written by Google. They write it for
themselves, not you. And they are famous for their mono-repo. It works for
them, but it means they break semver and frequently make breaking changes in
minor version increases.

And when they do follow semver, the pattern becomes obvious. We're on Guava 29
after all
[https://mvnrepository.com/artifact/com.google.guava/guava](https://mvnrepository.com/artifact/com.google.guava/guava)

19 breaking changes in ... 10 years?

~~~
mumblemumble
I banned Guava from the things I maintain a couple years ago, and haven't
looked back. It's absolutely chock full of useful things. But I don't need any
of them enough to justify tangling with all the breaking changes.
Individually, it's all a bunch of things that I can live without, or implement
myself with minimal effort, or get from somewhere else.

------
lukevp
I have been a .net developer for a long time. More recently, I’ve been using
TypeScript in VS Code, with automatic Prettier and eslint on save. It’s
ridiculous how much more productive this is. I don’t have to worry about
semicolons, code formatting, imports are automatically added when tab
completing functions or variables in other files... it really makes me wonder
why every language doesn’t format automatically by default. It probably saves
me 30 minutes a day of manually formatting code, and it results in better
looking code too.

~~~
apta
Rider and IntelliJ also have the features you mentioned, and then some.

------
raverbashing
> The fix was simple. I manually replaced the word “compile” with the word
> “implementation”.

I really wonder why are we letting this happen. Really

A similar thing to when I see a command or an API call that does what you want
then says "deprecated" (with no clue of why or how to do that now). Sure,
because nobody does this anymore right? (and I'm not talking about complicated
stuff) Or the new function works in some mysterious way when the old one was
straightforward

I mean, really

But it seems people are "moving fast, breaking things and who cares if it's
broken? it works for me"

~~~
jeroenhd
The compile keyword produced warnings for over three years now. The author was
likely developing with an old or bad guide in hand, because the warnings were
there.

In my experience, many of the Android methods marked as deprecated also
contained docstrings to the new API and how to use it. In some cases it can
even automatically insert the boilerplate code to do what the old, deprecated
function did with the extra error handling for changes to the platform.

compile and implementation aren't the same thing. Depending on your use case,
compile needs to be either changed to api or implementation. They aren't the
same thing, so just a quick replace by the IDE would likely break more than it
fixes. The problem is that most guides treat them as the same thing and make
people think the compiler is being stupid for changing the word they need.

I can't speak for other projects, but for Android, where most of my
deprecation struggles came from, the change was the result of changing
requirements. Early Android was a wild west where every app could copy the
contents of your SD card and upload it to their servers without even so much
as a warning, where IMEI numbers were widely used as identifiers in databases
for analytics and where permissions were more of theory than a practical
requirement. Killing random apps was a permission any application could
obtain, app databases appeared on your SD card which sometimes included
credentials and secretly turning on cameras was easy to do by rendering the
preview to a 1x1 pixel area. Screen hijacks were also commonly possible,
causing major concern for apps for banking and such. Google had to
retroactively restrict applications with new permission systems and
applications often crashed without workarounds because the developers often
never bothered with exception handling for stuff like file I/O. This isn't
moving fast and breaking things, this is trying to fix fatal flaws in the
design of a running train.

When I encounter deprecation, it's because the underlying design of the API I
use has significantly changed, often for good reason. It's annoying when
features turn from a simple function call to a complicated code structure, but
there's often a good reason behind it. I just wish people would put those
reasons in their docstrings and release notes instead of marking stuff as
deprecated and leaving it at that.

~~~
xondono
That’s not the point of the article, the point is that if a developer gets to
the point of having to break things, it should think on how to mitigate the
work is forcing upon those who use its tools.

It’s about being conscious about others time and the impact your work has on
theirs.

They might be a good reason for changing “compile” to “implementation”, but it
costs nearly nothing for the dev to add a specific rule that if “compile” is
in the code, the compiler should show a link or point to the docs or explain
how to solve it.

On the other side it’s painfully costly for anyone using that tooling to
understand what’s happening, why the change, how to solve it. The end result
is that a lot of inexperienced users will find a fix that works for them (like
bulk replace of one for the other), and the end result tends to be a worse
ecosystem for all.

~~~
jsnell
I don't think that's true. This is what the author wants. Or rather, demands:

> Why doesn’t Android Studio / Gradle / Whatever just go “Mate – you’ve used
> compile here – that won’t work. Want me to automatically update the syntax?
> It’ll probably be fine.”

But the machine can't make the decision, since it doesn't know the intent. The
informed human in charge of the project does. What if there's automation, and
tool ends up making the wrong decision? I bet that the author would be
complaining about that instead.

Reading the Twitter threads that the author links to are quite illuminating,
and it's surprising to me he feels it's showing him in a good light. It's an
amazing display of both entitlement and intentional ignorance.

------
sumanthvepa
I can't empathize with this enough. The build stack of Java software is
absolute nightmare. I really haven't met anyone who really know this in any
detail. There is something seriously wrong with the Java community. I also
develop extensively in Python and I rarely encounter the same degree of
difficulty in developing complex software.

~~~
lucianbr
I think it's a matter of perspective. I develop a lot in Java, and I
understand most of the build stack. Most of the time, when I see an error I
instantly realise what the problem is. Sometimes, rarely, it's cryptic, and I
need to do a lot of digging to figure it out.

I also touch python once in a blue moon. It's always frustrating. To get
anything done, I need to install python, then install pip, then make a virtual
env, then use pip to install the libraries the project needs in the virtual
env, then start the project. At this point, I realize the project does not
work on the latest version of python, but on some specific version, and I need
to throw away everything and start again. And each time I tell myself: "why
wouldn't they write this obviously critical piece of information on the main
page?"

I don't think one of the tech stacks is much better than the other. I think we
just perceive the one we are knowldgeable in as better, for obvious reasons.

~~~
hprotagonist
> To get anything done, I need to install python, then install pip, then make
> a virtual env, then use pip to install the libraries the project needs in
> the virtual env, then start the project.

These days i spell that

    
    
      poetry new myproject && cd myproject
      poetry add dep1,dep2,...
      poetry install
      git init .
      gi python && git add .gitignore && git commit -am “first commit”

~~~
mxschumacher
And pyenv for the right Python version

With poetry init, the tool walks you through project setup

~~~
hprotagonist
yep, pyenv is step 0 for sanity.

------
buzzkillington
>“Missing semicolon on line 427.” To which I’d reply “If you know what is
missing, and you know where it is missing, why not add it back yourself? You
useless piece of crap!”

Because what you mean and what the closest syntactically correct program to
what you typed are two very different things.

~~~
bluedino
Xcode is pretty good at figuring out what you should have done whether you did
it the right way or not. Surprised me a bit at first.

~~~
buzzkillington
So is GCC. The point is you still need to look at where the error is because
the closest syntactically correct program to what you wrote is probably not
the program you wanted to write.

------
naranja
Archive Link for your convenience, because website seems to be down for me:
[https://web.archive.org/web/20200606144232/https://shkspr.mo...](https://web.archive.org/web/20200606144232/https://shkspr.mobi/blog/2020/06/weve-
built-a-towering-pile-of-shite/)

------
omginternets
There seems to be a constant in all of these “towering piles of shite”
articles: they’re all talking about frontend development. My own experience
concurs. I wonder why that is.

~~~
ComputerGuru
It seems unfair to group desktop apps, web sites/apps, and mobile apps under
one category of “frontend development.”

A good (read: native) and well-architectured desktop app probably has more in
common with backend development, UI design aside!

~~~
hombre_fatal
Well, it's all client dev. And client dev is hard and fundamentally distant
from server application dev because your client applications run on N machines
of M different configurations and are user facing instead of just running on
one server being machine facing.

It's not unfair to group client dev together. Client dev is always hard.
People on HN who only have touched JS dev tend to think that JS clients are
uniquely hard and, presumably, that clients are a cakewalk to build on other
platforms/sdks.

Never was true. Just look at the Android dev comments ITT. It's all hard and
complex.

~~~
ComputerGuru
I’ve been doing Native desktop software (distinct from web, embedded, backend,
etc) since the early 2000s, so I’m not unaware of the complexities ;)

------
mhh__
This is exactly what I think Everytime my python code (99% I'm forced to use
because of library support) breaks because I overwrite a library function in
my loop, or every "Wat" with JavaScript.

How many hours and thousands of lines of pointless tests have been wasted
because of bad type systems - I really don't get the fuss about about Python,
C++ was designed by a committee but python genuinely feels like it wasn't
designed at all beyond the basic syntax (which I like)

~~~
skohan
Python's USP is that it's very loose on ceremony so it's easy for "non
programmers" like scientists to pick up and use.

But like most interpreted languages, the up-front friction is low, but it
starts to buckle under it's own weight when a project reaches medium size.

~~~
stevesimmons
"buckling under its own weight when a project reaches medium size" is a
subjective view!

A counterexample is the company when I worked for 8 years. They took Python
very seriously. By the time I left, 4,000 developers were making 20,000
commits a week in a codebase of some 30,000,000 LOC.

~~~
skohan
I mean, I think it's possible to write quality software in virtually any
language if you're serious about it. I would argue that in the case of python,
you'd be succeeding in in spite of the language at that scale rather than
because of it.

------
StillBored
And my win32 app written in C++ ~25 years ago compiles and runs just fine with
the latest visual studio...

Maybe people should choose their tools based on mature technology stacks
rather than whatever happens to be cool this month.

------
blackhaz
"If you know what is missing, and you know where it is missing, why not add it
back yourself? You useless piece of crap!” -- I only code occasionally, but
wouldn't this effectively lower the overall skill in the profession and, also,
potentially introduce bugs? Thinking about Bruce Almighty style "yes to all"
fixes here.

~~~
afandian
The typo may not be limited to a semicolon. Introducing one automatically
might actually introduce unintended changes (like the huge number of bugs that
arise from blockless if statements in C syntax).

------
allo37
Hah, if he finds Gradle arcane and unintuitive, wait until he actually starts
developing the Android app itself...

------
kissgyorgy
I fully disagree with "Fail 2". Tools shouldn't automatically update
dependencies, developers should be full control of what and when to update
them. Dependency handling is a very complex topic, it's hardly something you
can just left to the computer, maybe minor bumps when everyone agree that only
minor bugs got fixed, but that sometimes can break the whole world.

As with the missing semicolon; the compiler can't be sure if that's a typo, so
the line should end there, or you just really missed the semicolon only. It
doesn't understand the code the way you do.

As for "Don’t make me think." \- the whole software development is about
thinking. Can't do any part on autopilot.

~~~
watermelon0
> the whole software development is about thinking

Sure, but I'd prefer to think about the problem that I'm solving, and not
about which combination of packages I need to successfully compile and run the
application.

I don't want to spend time manually upgrading dependencies, or syntax,
especially if this is something that can be automated by build tools or IDEs.

------
bartread
This article resonates strongly with me.

One thing that doesn't:

> To which I’d reply “If you know what is missing, and you know where it is
> missing, why not add it back yourself? You useless piece of crap!”

I had a friend at school who used to make the same complaint about BBC BASIC
back in the 80s. If you missed a double quote you'd get an error something
like:

    
    
        NNN Missing "
    

where NNN was the line number.

Thing is, and this is true in plenty of other cases, if the computer guessed
at where to insert the " and got it wrong, especially if it didn't tell you
what it had done, this could lead to some pretty weird side-effects in terms
of program behaviour that might be harder to debug/fix. Same is true with
other languages. I mean, even if it did tell you, how many people actually
read compiler messages other than errors every time they compile?

Nowadays, with background error highlighting it's pretty much a non-issue.

This, on the other hand...

> And don’t make me waste my time fixing problems that you have caused.

F###ing f### me but this boils my p###. I am sick and tired of, particularly
JavaScript, architectural astronauts making breaking changes - often changing
fundamental concepts - in their APIs and libraries with little consideration
to the effect it will have on their users. It's particularly irksome when
they've actively evangelized to build that community. Angular, D3, gulp - even
TypeScript - have all made significant changes that have wasted massive
amounts of my time, and the time of plenty of other developers I know.

It's not like I've gone out of my way to use OSS without "contributing back":
often these are inherited projects. For my own side-projects, I try to avoid
using libraries where I can because I simply don't want the hassle. (Although
it's basically unavoidable, particularly if you use Node as a back-end.)

Still, you can't escape it entirely even if you limit yourself to browser
APIs. There have been changes in behaviour around Web Audio, accelerometer and
compass, and full screen support that have broken my code out of the blue.

It's really tedious.

Back in the day I remember that Java was much better for this: you could be
fairly confident about running Java 1.0 and 1.1 code unmodified on Java 1.5,
at least. It's been years since I've been in the Java game so it sounds like
that might have gone to the wall now as well, at least when it comes to
dependencies outside of the JDK itself.

~~~
hrktb
> if the computer guessed at where to insert the " and got it wrong,
> especially if it didn't tell you what it had done, this could lead to some
> pretty weird side-effects in terms of program behaviour that might be harder
> to debug/fix.

As a lot of things, this is a matter of how often it gets it wrong.

For instance in ruby world, rubocop has an option to autofix. To your point,
it makes it clear what it fixes so you can review. It’s also conservative
enough to bail on anything that could have strong effects, like block endings.

That said in years using it I can’t remember any time I really regretted
making it autofix stuff.

~~~
mook
Rubocop is a linter, so it tends to have an easier time: it only needs to
process input that is already correct, though it might have style issues. It
doesn't need to do anything that might change the meaning of your program.
Inserting quotes will change the meaning of the program, so getting it right
is much harder.

------
anoncorpprog
I'm primarily a lurker, but after reading this I had to add a comment. I
recently had this exact same experience across multiple different languages
and IDE's etc.

Most recently it was trying to get a laravel PHP app to work on my 2015 MBP,
(which apparently was using a system installed version of php, preventing me
from connecting to a postgres database on AWS using SSL because it wasn't
compiled with SSL support...)

Today it was an ios app that started to fail compile because 1 of the devs
used an ios 13.0 only feature.

Last week it was a .net core windows service, that I had to read several pages
of documentation on, in order to upgrade from 2.2 to 3.1, in order to simply
add telemetry reporting.

I feel the premise of this post is more around the concept than it is
specifically about gradle issues. It's simply this feeling of drowning in just
getting something back to a working state through the endless cycle of
trial/error, StackOverflow, and googling different terms.

Too many times what started as a journey of inspiration when I wanted to add a
cool feature/idea turns into hours of frustration. I normally end up getting
it to work, but all my motivation is gone and I sit there and ponder how is it
possible to be doing this for 10+ years, and find myself constantly in these
ruts across the board.

It's articles like this rant that make me feel that I'm not alone!

------
737maxtw
This doesn't really surprise me. The Java toolchain has always been a bit
painful to me, although I come from the world of .NET where we were able to
learn from Java's early mistakes and settled on a fairly simple toolchain.

But even in our world we still have some level of package hell, typically in
the form of version redirects.

Anywho, back to the case of Android, it seems as though nobody ever thought
about what it would be like to rapidly iterate the way google does on a
toolchain that tends towards liking things to stay in place.

------
jonnypotty
What do people do if there is no new good functionality to implement? Change
things around to minimise their own cognative dissonance and mistake that for
improvement?

It feels better to someone to change 'compile' to 'implement' and so it
happens. It ruins part of the contract between the software and existing
users, but the users get it for free and they're not organised so who cares?

I agree with virtually all of what you say apart from automatically updating
dependencies that may or may not work. You're having to work around a problem
that shouldn't exist and I think an IDE making dependency choices is a bad
idea. What we really need is ONE build tool and package manager and a standard
way of using them for each language.

We seem to have this idea that a large choice of software tools means better
software tools. Just not true. We are not completely rational 'consumers' in
this economy. New software adoption is hard and has a cost associated. There
are large insentive to stay with your current tool chain. Software companies
knowingly or unknowingly exploit this by not having to really consider their
users.

Microsoft, can, within reason do ANYTHING to visual studio as there is no
viable option for people or organisations change over to.

I reckon a big reason people love Rust is because no one has fucked it up with
lots of shitty 'tools' yet.

------
georgeecollins
I used to enjoy Android development, but they change the tools so often. The
documentation is often behind. I honestly can't tell you what the benefit is
to almost all of the changes, except that it breaks my code.

I would really love it if a project I made two years ago would still compile,
but it doesn't.

------
mikro2nd
> “Simply install Flargnle in the normal way…”

I've lost count of the number of times I heard/read, "Just type `npm install
flargnie` and it'll all work."

Only it doesn't.

And being unfamiliar with the craptastic and hostile ecosystem that is node's,
that's usually the point I just bail and find another tool.

~~~
ComputerGuru
You should use a better font. OP said flargnle but you tried installing
flargnie (note the difference in the second-to-last letter; you may need to
copy-and-pasts this text into Microsoft Word and change the font to MS Comic
Sans to see the difference, but one is an ell and the other is an aye). That
should take care of it!

~~~
mikro2nd
It's called a typoo

------
jmiserez
For git: set help.autocorrect to make it shut about minor typos:

[https://git-scm.com/book/en/v2/Customizing-Git-Git-Configura...](https://git-
scm.com/book/en/v2/Customizing-Git-Git-Configuration#_help_autocorrect)

~~~
OJFord
I use this (and frequently _use_ it) - but I wish it were a feature of the
shell, more generic than just for git (or everything independently). Seems
like it shouldn't be too hard on the shoulders of completions.

------
semi_good
Gradle is designed to keep people who spend time getting good at it employed.

It’s a real embarrassment to our industry.

~~~
ashtonkem
I never really understood the argument for configuring a build tool in a
separate programming language, let alone in _two_ separate languages. I have
never once said “thank god I have regular language functionality here”, and
more often said “what undocumented function do I need to call again?”

Makes me want XML and Maven back; at least my IDE can guide me based on the
schema files it parsed.

------
srameshc
The same happened with my React Native app. Apple wanted changes, "Users
should not be required to login" and I didn't bother because I was working on
something else and after about 6 months, I can't fix it.

------
hn_check
On the flip side, I have the NextDNS CLI running on a Jetson Nano. I found it
was logging too much for my comfort (meaningless reverse DNS logs, and I'm
somewhat paranoid about flash exhaustion) so I cloned the repo, commented out
a couple of lines, and did go build.

Actually built for Linux on my MBP.

Boom, all dependencies, and in seconds a perfect binary. I've had similar
experiences with a number of projects, including huge projects like Firefox.

Like it all things in life, it varies. Some projects and toolsets are perilous
mountains of crapitude. Others are just magically delightful.

------
aogaili
If you think this is a pile of "shite", try web development...

~~~
hombre_fatal
Having spent at least 5 years fulltime in (each) Android, iOS, and Javascript
client development, I'd say they're all about the same from how "shite" they
get in a growing project. The magic incantations in gradle just become magic
incantations in webpack.config.js and magic incantations in Xcode menus.

If anything, Javascript clients have the advantage of being able to bring your
own fundamental abstractions since you're not stuck having to compile your
abstraction to a narrow API like UIKit.

Web development gets the worst reputation because it's the only one most
people have experience with.

------
twelve40
to be fair though... this is an alternative system that's not fully locked to
one company's software AND hardware (for development and the actual phones),
has multiple players, and at least an appearance of an open system, and all
the quirks and incompatibilities that come with that. Sometimes I'm just
grateful Android survived and continues even in its messy and imperfect form,
because the world where everything mobile is dictated by just one company
would be pretty sad.

------
nathan_f77
I agree with this 100%. I recently tried to update an old iOS app written in
Swift. I would have to install an older version of Xcode to upgrade Swift from
version 2 to 3, and then use the latest Xcode upgrade from 3 to 4. Then I'd
have to update every single dependency and figure out any breaking changes. I
wanted to see if I could hire someone to help me with this, but they just gave
up after looking at it, and recommended rewriting the whole project from
scratch. (It's a hobby project so I don't have the budget for a rewrite.)

This is generally how dependencies work across all languages and frameworks,
and I think the status quo is extremely inefficient. When a library maintainer
releases updates with breaking changes, we waste thousands of developer-hours
on upgrades and fixing all these changes.

I've been thinking about a new kind of package manager and repository that
strictly enforces a certain level of test coverage, and also forces library
maintainers to codify the upgrade process. For example, if you decide that you
want to rename a `get` method in `v0.1.0` to `fetch` in `v1.0.0`, then your
`v1.0.0` release MUST include an automated code-mod script that automatically
runs when a developer updates the library version. This wouldn't work so well
for dynamically typed languages, but this rename example should work
flawlessly in a statically-typed language.

The code-mod script should also include lots of test cases, and be tested on
lots of other real-world libraries. Similar to how Rust developers detect
regressions in the Rust compiler by building a large number of crates.

There's probably a lot of reasons why this wouldn't work in the real world,
but one can dream! There was a lot of controversies when Elm made this kind of
decision about their package ecosystem and removed native modules [2]. Deno is
working on a high quality Standard Library [4] with no external dependencies,
and where all code is reviewed by the Deno core team (and presumably with a
high level of test coverage.)

[1] [https://github.com/rust-lang/crater](https://github.com/rust-lang/crater)

[2] [https://dev.to/kspeakman/elm-019-broke-us--
khn](https://dev.to/kspeakman/elm-019-broke-us--khn)

[3]
[https://news.ycombinator.com/item?id=17842400](https://news.ycombinator.com/item?id=17842400)

[4] [https://deno.land/std](https://deno.land/std)

~~~
DreamScatter
Julia package manager somewhat has features like this, and there's a bot which
can make a pull request to update breaking changes from the core language.

------
bfrog
Why is rust the most loved language? Perhaps it's because the creators and
curators seem to care so much about these exact things.

------
maaarghk
building the contract tracing app going well then?

------
5cott0
If android phones would update once in a while we wouldn't be stuck with all
this gradle dependency rot.

~~~
BenjiWiebe
If manufacturers would provide an option for unlocking bootloaders on all
phones, and component manufacturers would release driver source code (or at
the very least datasheets), then I could/would gladly update my phones.

------
jpxw
> The compiler would say “Missing semicolon on line 427.” To which I’d reply
> “If you know what is missing, and you know where it is missing, why not add
> it back yourself? You useless piece of crap!

That’s not the role of a compiler, for good reason. I stopped reading the
article after reading this line.

------
marczellm
The Android dev experience used to be built on Eclipse. Woohoo!

