We’ve built a towering pile of shite(shkspr.mobi)
shkspr.mobi
We’ve built a towering pile of shite
http://shkspr.mobi/blog/2020/06/weve-built-a-towering-pile-of-shite/
208 comments
> 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... (and https://internals.rust-lang.org/t/new-error-format/3438 and https://web.archive.org/web/20160807033841/http://www.jonath...).
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.
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... (and https://internals.rust-lang.org/t/new-error-format/3438 and https://web.archive.org/web/20160807033841/http://www.jonath...).
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.
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.)
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.)
> 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
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
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.
Android is at the other, far end of the spectrum.
So much so that we have separate technologies to write in Javascript and then build it for Android (PWAs).
The server-client equivalent would be writing one codebase, in one language and building for browser, and server separately. Despite server-client predating Android by decades, that still does not happen.
It's a bit of a rant - but I hate anything that comes with IDE - I face greater cognitive load in undertsanding the IDE than writing logic.
So much so that we have separate technologies to write in Javascript and then build it for Android (PWAs).
The server-client equivalent would be writing one codebase, in one language and building for browser, and server separately. Despite server-client predating Android by decades, that still does not happen.
It's a bit of a rant - but I hate anything that comes with IDE - I face greater cognitive load in undertsanding the IDE than writing logic.
People used to use GWT to write Java and ship JS to the browser. Now with WASM this stuff might be coming back.
+1 on Golang on this front for rarely creating any confusion on any front, really.
I shudder to think about the next time I have to do npm decency upgrades. Even worse when you have synchronize typescript types. Which requires reading through random GitHub issues to realize that you need to pin a random @types package to 1.20.30 because that’s the one that magically worked for a commenter with 20 thumbs-up reactions.
I shudder to think about the next time I have to do npm decency upgrades. Even worse when you have synchronize typescript types. Which requires reading through random GitHub issues to realize that you need to pin a random @types package to 1.20.30 because that’s the one that magically worked for a commenter with 20 thumbs-up reactions.
Hehe I tried to freshen up my frontend coding after 5 years break. Man was I up for a surprise. Reasonml project throwing typescript errors at build time bluh
From the article:
Gradle does not do any user research. It never sits down with independent developers, newbies, or seasoned pros. It never tests its error messages. It doesn’t do developer relations. It doesn’t spot bad implementations in the wild and offer helpful suggestion. It doesn’t relentlessly focus on making things easier for users.
Many times I wanted to just ask some library/framework authors that very question, like ‘hey, do you know what real apps using these paradigms look like? Do you think it’s okay for even the most basic apps to look this mutant?’.
The ergonomics of developer tools/libraries is an underrepresented topic. Some would even call it taboo since so many of us don’t want to appear as if we don’t know how to use a technology. It stops us from giving valid feedback in many cases where something is truly unintuitive, or painful to use.
Gradle does not do any user research. It never sits down with independent developers, newbies, or seasoned pros. It never tests its error messages. It doesn’t do developer relations. It doesn’t spot bad implementations in the wild and offer helpful suggestion. It doesn’t relentlessly focus on making things easier for users.
Many times I wanted to just ask some library/framework authors that very question, like ‘hey, do you know what real apps using these paradigms look like? Do you think it’s okay for even the most basic apps to look this mutant?’.
The ergonomics of developer tools/libraries is an underrepresented topic. Some would even call it taboo since so many of us don’t want to appear as if we don’t know how to use a technology. It stops us from giving valid feedback in many cases where something is truly unintuitive, or painful to use.
Maybe this needs to be taught more in universities.
JavasScript (and PHP for example) is an ecosystem with low barrier to entry and large popularity, combined with rudimentary and bad platform (historic reasons) - it's a recipe for piles of shite.
The amount of signal to noise is low because of low barrier/high user base community spamming NPM packages/and spamming ratings/stars/dependencies - it's hard to determine what's "safe" to use, and because the environment is so barebones you need to depend on a lot of third party code or reimplement everything yourself.
C++/C have a similar legacy burden and barebones platform (although C++ std lib now-days is much better, historically it was unusable which lead to a lot of code duplication) but because the barrier to entry is much higher I'd say an average C++ dev is much more competent than average JS/PHP dev and the libraries commonly used in C++ world are obviously higher quality than JS/PHP (tooling fragmentation is a different story because of the unique problems C/C++ face, but still C++ build tools are probably the most sophisticated out there - out of necessity).
Rust falls in to the category of languages designed by competent people without legacy burden and tackles a complex domain (again higher barrier to entry), most languages I've seen in this category have decent tooling and design (eg. C#, F#, Go, Dart)
The amount of signal to noise is low because of low barrier/high user base community spamming NPM packages/and spamming ratings/stars/dependencies - it's hard to determine what's "safe" to use, and because the environment is so barebones you need to depend on a lot of third party code or reimplement everything yourself.
C++/C have a similar legacy burden and barebones platform (although C++ std lib now-days is much better, historically it was unusable which lead to a lot of code duplication) but because the barrier to entry is much higher I'd say an average C++ dev is much more competent than average JS/PHP dev and the libraries commonly used in C++ world are obviously higher quality than JS/PHP (tooling fragmentation is a different story because of the unique problems C/C++ face, but still C++ build tools are probably the most sophisticated out there - out of necessity).
Rust falls in to the category of languages designed by competent people without legacy burden and tackles a complex domain (again higher barrier to entry), most languages I've seen in this category have decent tooling and design (eg. C#, F#, Go, Dart)
Rust has definitely set a new bar for systems programming languages.
Regardless of rust's design in particular, static safety and lifetime management is now non-negotiable, and rust's error messages definitely lead the way although everyone else's are pretty good now.
If D and Rust had a baby I wouldn't anything else.
Regardless of rust's design in particular, static safety and lifetime management is now non-negotiable, and rust's error messages definitely lead the way although everyone else's are pretty good now.
If D and Rust had a baby I wouldn't anything else.
Rust is great. However, because of the ease of creating crates (packages), it seems to be beginning to suffer the same fate as Node and node_modules, with authors bringing in crates (just a `crate install` away) and ending up with ludicrous compile times for the end users.
I definitely agree - this is a problem that is not evenly spread across all programming languages and IDEs. Javascript is easily the worst offender. Java/Android are right up there with it.
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.
Not only the tool is infuriating, the language is baffling. With most tools the first time I ever set eyes on the configuration I had a pretty good idea what was going on without reading any documentation. With Gradle it's like someone invented proto-Java and just left it at that. A build file which was actual Java would be much easier to understand and most importantly edit, because then I could get the IDE to help explore the API.
As a side note, this is probably (intentionally or not) the same tactic that Microsoft used in the 00s to avoid competition: keep changing things fast so that anybody using your tool chain a) has to follow your lead to keep up, b) ends up with huge sunk cost, and c) (if they trust whoever's behind Gradle) keeps being reminded how much they innovate.
As a side note, this is probably (intentionally or not) the same tactic that Microsoft used in the 00s to avoid competition: keep changing things fast so that anybody using your tool chain a) has to follow your lead to keep up, b) ends up with huge sunk cost, and c) (if they trust whoever's behind Gradle) keeps being reminded how much they innovate.
So much this. I've tried multiple times to grok it and it just slid straight back out of my brain leaving me with the same puddle of syntax soup I started with. I've never encountered anything else even close to this bad.
Not to mention that build config is probably the absolute last place you want a weird unreadable language nobody knows, because it tends to be touched so rarely that nobody builds up any familiarity with it.
Not to mention that build config is probably the absolute last place you want a weird unreadable language nobody knows, because it tends to be touched so rarely that nobody builds up any familiarity with it.
You can write nearly all of your gradle build logic in java if you want. Place the java files to configure your gradle build in buildSrc/src/main/java, then write a single line of kotlin in your build.gradle.kts to call your java code.
Here's the javadoc: https://docs.gradle.org/current/javadoc/org/gradle/api/Proje...
Here's the javadoc: https://docs.gradle.org/current/javadoc/org/gradle/api/Proje...
[deleted]
The popularity of Gradle utterly baffles me.
When Gradle got popular the main competition was Maven which involves copy and pasting random pieces of XML from the internet, gave stack traces rather than clear error messages and didn't used to support incremental builds.
When Gradle got popular the main competition was Maven which involves copy and pasting random pieces of XML from the internet, gave stack traces rather than clear error messages and didn't used to support incremental builds.
Before I continue, I would like to point out that Gradle is so bad that it’s making me say “I’d like to go back to XML please”. In any other context this would be an insane thing for me to say, but Gradle is that bad.
XML & Maven has the benefit of having a schema. This means that not only do all my pom.xml files look similar, but the IDE can do meaningful autocompletion and semantic checking for me. It’s verbose and ugly, but at least it’s consistent and has good tooling.
Gradle on the other hand is a Turing complete system, which just adds another layer of potential errors on top of Java compilation, which is the exact opposite of what I wanted. Now also all of my Gradle files are different and I have no idea why, and what the relative pros and cons of each style is.
Could Maven be improved? Sure. I’d kill for something like Cargo for Java. But I did not want to find myself debugging by build tool’s state because I used a setter wrong (true story).
XML & Maven has the benefit of having a schema. This means that not only do all my pom.xml files look similar, but the IDE can do meaningful autocompletion and semantic checking for me. It’s verbose and ugly, but at least it’s consistent and has good tooling.
Gradle on the other hand is a Turing complete system, which just adds another layer of potential errors on top of Java compilation, which is the exact opposite of what I wanted. Now also all of my Gradle files are different and I have no idea why, and what the relative pros and cons of each style is.
Could Maven be improved? Sure. I’d kill for something like Cargo for Java. But I did not want to find myself debugging by build tool’s state because I used a setter wrong (true story).
> copy and pasting random pieces of XML from the internet
Also, I don't see that this is a big deal when dealing with a declarative paradigm. In fact, cutting and pasting random bits of declarative code makes a lot of sense to me. You don't need to understand how it's doing what it's doing, only that it will.
I have yet to discover a situation where some custom thing I needed couldn't be handled with the Exec Plugin or a custom plugin, which are easy to write. The truth is that these uber-custom things are actually pretty rare if you stick to conventions.
Also, I don't see that this is a big deal when dealing with a declarative paradigm. In fact, cutting and pasting random bits of declarative code makes a lot of sense to me. You don't need to understand how it's doing what it's doing, only that it will.
I have yet to discover a situation where some custom thing I needed couldn't be handled with the Exec Plugin or a custom plugin, which are easy to write. The truth is that these uber-custom things are actually pretty rare if you stick to conventions.
Also, if you use the Kotlin compiler plugin, you can actually write blocks of Kotlin code in your Maven POM if you feel the need.
OMFG! So much truth in these Gradle threads! I'm glad I'm not the only one.
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)
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)
The problem of tooling is that that's the place where ugly hacks most often go. Where the beautiful elegant abstractions meet the reality, where third party dependency cruft seeps in, where cross-version compilation gets orchestrated, where all the dev/test/prod compile time configuration, optimization, obfuscation, etc. happens.
And sbt is just bad all around on top of all this, and it should feel bad.
And sbt is just bad all around on top of all this, and it should feel bad.
[deleted]
> crap tools because developers won’t pay for tooling
I'm not sure i understand this argument
crap Linux because developers won’t pay for Linux
crap git because developers won’t pay for git
...that's clearly not the case, no? Every day we use a bunch of developer tools that are not just crap, but amazing and great to work with, and were built as open source. So I'm not sure about equating open source with crap experience.
I'm not sure i understand this argument
crap Linux because developers won’t pay for Linux
crap git because developers won’t pay for git
...that's clearly not the case, no? Every day we use a bunch of developer tools that are not just crap, but amazing and great to work with, and were built as open source. So I'm not sure about equating open source with crap experience.
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.
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.
Even when I'm writing Scala I prefer Maven to SBT, I just prefer declarative build tools to DSLs up in my grill.
In my limited experience, Gradle is increasingly popular for Spring Boot applications.
At the very least, limit the scope of the language until a standardized toolset is cross-functional. I'm not not throwing shade at UWP right now.
> if it’s not open source and free we don’t touch it outside of an enterprise environment.
To be fair, this is due also to the fact that opensource tools are mostly guaranteed to outlive their developers. Should Microsoft go bankrupt tomorrow (don't laugh, it basically happened to SUN), most of their traditional tooling would disappear. In contrast, Gcc might be old and crusty, but it will go on forever like a cockroach.
To be fair, this is due also to the fact that opensource tools are mostly guaranteed to outlive their developers. Should Microsoft go bankrupt tomorrow (don't laugh, it basically happened to SUN), most of their traditional tooling would disappear. In contrast, Gcc might be old and crusty, but it will go on forever like a cockroach.
Gradle might not be perfect, but it's so much better than anything else I've used.
Simple builds have simple config. Doing more complicated things means you need to learn how the tool works, and that can certainly take some time.
I'm really liking the new kotlin DSL, having great IDE support, really makes writing gradle scripts much more pleasant.
I do a fair bit of work on node based projects, and the building tooling in the node ecosystem is just so horrible in comparison.
Simple builds have simple config. Doing more complicated things means you need to learn how the tool works, and that can certainly take some time.
I'm really liking the new kotlin DSL, having great IDE support, really makes writing gradle scripts much more pleasant.
I do a fair bit of work on node based projects, and the building tooling in the node ecosystem is just so horrible in comparison.
NodeJS building tool? Do you mean gyp (which is bad) or high level stuff run via npm/yarn (which is meh) like gulp/webpack/ng whose config files are all horrible?
I too would like clarity. Every time I end up having to do frontend stuff with gulp/webpack/etc I want to shoot myself, and that's fair. The few times I've had to compile native dealing with gyp has been a crapshoot (sometimes just work, sometimes painful; never as bad as gulp/webpack/etc). But most of the time, for Node development, I just need other node libraries, and it's pretty painless. Not as good as some others, but still -miles- better than Gradle.
Maybe a bit off topic. But am I the only one who thinks "simple builds should have NO config"?
A strong argument for Cargo. Most cargo manifests are some dependencies and a bit of metadata, which I think we all can agree is reasonable enough.
> flail around with trying to find out the magic song and dance that’ll make it happy
If you switch to the Kotlin flavor of Gradle then this goes away. You just have to make the compiler happy then, same as for application code.
If you switch to the Kotlin flavor of Gradle then this goes away. You just have to make the compiler happy then, same as for application code.
It's worth considering Bazel instead which is much cleaner and easier to understand. Unfortunately its official support and platform adoption are limited
Whatever happened to Ant? I know Ant sucked because of XML, but at least XML has a lot of tooling around it. Why do people use Gradle instead of Ant?
"[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.
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.
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.
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.
With Android, part of the problem is that a solid ~80% of the "how to" information out there (and a distressingly high percentage of the official documentation) tells you to use things that were either deprecated years ago or are about to be deprecated in the next version of Android. Since the framework has gone through multiple iterations of this dance, you basically need to learn the whole history of any API you're using before you can decide how some part of your app is going to work.
Or you can pull in a library that seems to be popular and maintained and solves the problem that you have.
Or you can pull in a library that seems to be popular and maintained and solves the problem that you have.
That, and there's a lot of "folk knowledge" around how to do things that the docs ignore. The cleanest and most efficient (or even just non-broken) way to do even basic shit is often to ignore how the docs say to do it and use some library. The whole platform feels badly neglected, like the only time anyone gives it serious attention is to throw some half-implemented shiny feature on top so they can announce it at an event, then never touch it again.
I think a large part is that the first-party documentation is pretty bad. My only exposure to the Android toolchain has been writing my own toy application, and it's just sad that the docs are terrible. Things like "this thing that used to be in the platform API had been replaced by that thing in appcomapt" → "nope it's in androidx now" → "this replaces that thing in the platform API, go read the docs for that instead". Essentially, you _have_ to read deprecated documentation to do anything…
At least it's better than some other ecosystems, where it's "this thing is deprecated now. Nothing replaces it and you can't do similar functionality any other way, it's just deprecated." Or maybe I just haven't gotten to that part yet.
At least it's better than some other ecosystems, where it's "this thing is deprecated now. Nothing replaces it and you can't do similar functionality any other way, it's just deprecated." Or maybe I just haven't gotten to that part yet.
>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.
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.
I thought 12 was hyperbole for 3 or 4. All you've done is shown that the default encourages 7 files. Going from that to 12 with some questionably early refactoring sounds quite possible.
The quoted post says "dozens", plural. I can easily see new developers overengineering something that big.
I honestly can't tell if this is a joke? 0.5 KLOC. Seven files. That's not over-engineered?
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.
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.
"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.
"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".
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".
No matter how many times I write a recyclerview, which is usually atleast one for any new screen, it never stops being the worst part of Android dev for me.
I used to say it a lot. It's been a long time now, but heck for old time's sake: how I miss Windows Phone.
[deleted]
> one list view which updated it's contents to filter results out of an SQLite database as you type into a text field
In racket/gui this could be maybe 100 clean lines of code in one file.
In racket/gui this could be maybe 100 clean lines of code in one file.
Probably, yes. Hower, does Racket handle configuration changes (orientation, language, etc.), recycling list items to lower memory usage, arbitrary layouts for lists (and not just a single line of text) with diffs calculated between renders, and more ?
Android is complex, yes. Sometimes for no reason (hello God Activities). But sometimes, it has good reasons to do so.
I actually wrote one, with the bare minimum. HNActivity.kt is 81 lines and handles updating the list, querying
Android is complex, yes. Sometimes for no reason (hello God Activities). But sometimes, it has good reasons to do so.
I actually wrote one, with the bare minimum. HNActivity.kt is 81 lines and handles updating the list, querying
import android.database.sqlite.SQLiteDatabase
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlin.concurrent.thread
class ListItemVH(val view: TextView) : RecyclerView.ViewHolder(view)
class HNActivity : AppCompatActivity() {
private lateinit var recycler: RecyclerView
private val adapter = object: RecyclerView.Adapter<ListItemVH>() {
private var _items = listOf<String>()
fun setItems(newItems: List<String>) {
DiffUtil.calculateDiff(object: DiffUtil.Callback() {
override fun getOldListSize(): Int = _items.size
override fun getNewListSize(): Int = newItems.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
_items[oldItemPosition] == newItems[newItemPosition]
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
_items[oldItemPosition] == newItems[newItemPosition]
}, true)
_items = newItems
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemVH {
val v = TextView(parent.context)
return ListItemVH(v)
}
override fun getItemCount(): Int = _items.size
override fun onBindViewHolder(holder: ListItemVH, position: Int) {
holder.view.text = _items[position]
}
}
private var search: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scrolling)
recycler = findViewById<RecyclerView>(R.id.fab)
recycler.adapter = adapter
recycler.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
findViewById<EditText>(R.id.toolbar).addTextChangedListener {
search = it?.toString()?.takeIf { str -> str != null }
}
}
private fun performSearch() {
thread {
val db = SQLiteDatabase.openOrCreateDatabase("items.sqlite", null)
val query = when (search) {
null -> "SELECT text FROM table"
else -> "SELECT text FROM table WHERE text = ?%"
}
val args = listOfNotNull(search).toTypedArray()
val res = db.rawQuery(query, args)
val text = mutableListOf<String>()
while (!res.isAfterLast) {
text += res.getString(0)
}
adapter.setItems(text)
res.close()
db.close()
}
}
override fun onResume() {
super.onResume()
performSearch()
}
}
Add in another 30 lines for the Activity layout, and you've got your thing.
You've also got every single developer you'll work with hating you, and you'll hate maintaining this code. Just in those few lines, so much can go wrong (thread gets started and activity gets backgrounded? Oops, you crashed.)Now I want to take a shower and use Haskell for the rest of my life.
It would be difficult at best to do these things in racket/gui (to the extent that cocoa/win32/gtk aren't doing them themselves, e.g. diffs between renders I guess?), it certainly does have many shortcomings. racket/gui seems primarily designed to accommodate the needs of Dr Racket, and starts to come up short the further you stray from anything Dr Racket does. I think a big part of this comes down to a lack of manpower, which certainly isn't true of Android.
However I think it should be possible to design interfaces that make simple things simple while still giving you the flexibility to do complicated things. I think neither Android nor racket/gui has accomplished this, but at least racket/gui is fun rather than tedious. I agree with the article that there's a lack of user-centered design in the Android scene.
However I think it should be possible to design interfaces that make simple things simple while still giving you the flexibility to do complicated things. I think neither Android nor racket/gui has accomplished this, but at least racket/gui is fun rather than tedious. I agree with the article that there's a lack of user-centered design in the Android scene.
I once did small project for Android (basically created a library that would receive stream of data over BlueTooth from some device). Setting up the development environment (I've created full system backup prior to installation) and then using it made me hope that it is the first and last time I touch this pile of s... .
what about flutter?
I tried flutter and while it seems better than Android studio, it has its own problems.
I precached but it still required internet access to get some maven deps for android build. Updating is full of hassles and gradle, as always, unexpectedly fails somewhere eg in "assembleDebug" step. Maybe some version mismatch and I am not in a situation to do clean installs that require GiBs of internet. And no guarantee it works even on clean install.
I have come to a conclusion that front end (web or app development) is a mess and it is not for me. Look at Go, or Rust to know how to keep tooling simple and straightforward.
I precached but it still required internet access to get some maven deps for android build. Updating is full of hassles and gradle, as always, unexpectedly fails somewhere eg in "assembleDebug" step. Maybe some version mismatch and I am not in a situation to do clean installs that require GiBs of internet. And no guarantee it works even on clean install.
I have come to a conclusion that front end (web or app development) is a mess and it is not for me. Look at Go, or Rust to know how to keep tooling simple and straightforward.
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.
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.
> You would expect a big software company like Google to know better, but you'd be mistaken.
I don't think it qualifies as speculation anymore to assert that Google has something really broken about it, organizationally, that keeps it from producing truly good software—and often not even decent software—in most of its projects, for some reason. Even very high-profile ones. There's not really any other explanation for how they consistently behave.
I don't think it qualifies as speculation anymore to assert that Google has something really broken about it, organizationally, that keeps it from producing truly good software—and often not even decent software—in most of its projects, for some reason. Even very high-profile ones. There's not really any other explanation for how they consistently behave.
Pure speculation on my part, but it sounds like an organizational case of ADHD or Magpie driven development. A new project is started and everyone jumps ship before it is ready, leaving some other team to come in and continue before jumping. Repeat this over a few times in a product and you end up with an unusable mess. This might explain it.
Friend of mine that worked as a manager for a few years at google. Said he found it extremely difficult to get people to work on stuff that wasn't shiny and to stop refactoring stuff that was good enough.
yeah the culture is all based on promotions.. and you get them by launching something new, not by maintaining or improving existing systems. hence what you said
Google is a large company. I have respect for its core product that is google search. It’s insanely fast and reliable. I can’t remember the last time it was down. Mostly gets the answers I need at the top (I use adblockers so ads aren’t a problem)
The rest of Google has other priorities though. Even gmail’s iOS app had pretty glaring bug that it couldn’t mark a message read.
Google docs fails to save at times. YouTube Kids is just an awful mess. Don’t let your kids even near it. Google Cloud isn’t as reliable as the other clouds. Google can’t do proper human support. They don’t believe in it. If you’re a small shop, going with Google for anything critical is just going to be a disappointment.
Google Search though. I have an insane amount of respect for their engineers who work on performance and reliability.
The rest of Google has other priorities though. Even gmail’s iOS app had pretty glaring bug that it couldn’t mark a message read.
Google docs fails to save at times. YouTube Kids is just an awful mess. Don’t let your kids even near it. Google Cloud isn’t as reliable as the other clouds. Google can’t do proper human support. They don’t believe in it. If you’re a small shop, going with Google for anything critical is just going to be a disappointment.
Google Search though. I have an insane amount of respect for their engineers who work on performance and reliability.
On the tooling side, I think Steve Yegge's infamous and very entertaining platform rant from 2011 nails it: https://gist.github.com/chitchcock/1281611 tl;dr Google doesn't have the platform mentality in its culture, unlike Amazon and MS.
> 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.
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.
>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.
Android Studio isn't necessarily that bad. On a very large project, my AS instance eats up, at the absolute worst, 4GB of RAM. Which, compared to all other IDEs is not that awful.
Gradle however will eat memory and balloon to 8GB on its daemon
>The biggest problem I have with Android development is that compiling even a small app takes over a minute in my 7700k.
Make sure incremental compilation is setup. For small changes, this means that recompiling is lower than 10 seconds.
Android Studio isn't necessarily that bad. On a very large project, my AS instance eats up, at the absolute worst, 4GB of RAM. Which, compared to all other IDEs is not that awful.
Gradle however will eat memory and balloon to 8GB on its daemon
>The biggest problem I have with Android development is that compiling even a small app takes over a minute in my 7700k.
Make sure incremental compilation is setup. For small changes, this means that recompiling is lower than 10 seconds.
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.
And I wholeheartedly agree with your point about compile times and have added it to my comment.
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.
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.
> Many, if not most, dotnet devs run the Jetbrains tools to enhance their VS experience.
In fact, you don't even need VS as part of the experience anymore – Jetbrains Rider has most of the Resharper features (including "extract class" in the latest version) in an IDE based on the IntelliJ platform. It feels much faster than VS + Resharper.
In fact, you don't even need VS as part of the experience anymore – Jetbrains Rider has most of the Resharper features (including "extract class" in the latest version) in an IDE based on the IntelliJ platform. It feels much faster than VS + Resharper.
Yeah but to me Android dev seems to be too much dependent on IDE which I'd say a bad choice and impedes development.
Why can't it be as simple as a bunch of files in a folder, a build file, a manifest, and an asset directory? That's what most apps need.
Why can't it be as simple as a bunch of files in a folder, a build file, a manifest, and an asset directory? That's what most apps need.
Well JetBrains' IDEs are actually great so I don't think this is a valid argument. I worked with Android Studio for 2 years after which I moved to .NET development. I missed AS/IntelliJ so bad, I actually made my company buy me a sole Rider license and it's way, way better than the 'tailored IDE' that Visual Studio is. I'm way more productive and most of my colleagues are astounded by it's capabilities. Android Studio is actually decent, even considering it's quirks, and you'll only notice that when you have to use IDE other than JetBrains' one.
> You would expect a big software company like Google to know better, but you'd be mistaken.
Tensorflow is another data point to say that you are wrong.
Tensorflow is another data point to say that you are wrong.
Eh, compared to PyTorch, I find tensorflow to be extremely painful.
The original Angular is another one.
Oh how everyone ranted about that in 2013. Being from Google was a major selling point.
[deleted]
> Android has the worst tooling environment of them all.
These are Google engineers we are talking about. The same people who bring you gcp. Why are you surprised.
These are Google engineers we are talking about. The same people who bring you gcp. Why are you surprised.
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.
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.
I think you are misunderstanding the negative implications of “being easy to go from Zero to One”.
The problem with the above is that the easier it becomes to go from Zero to One, the more _replaceable_ One becomes. After all, you can learn it in no time!
Naturally this leads to more and more churn and every developer who is already _at_ One or above has to keep going back and re-learning it in order to “keep up with current trends”.
After a while it becomes tiresome to see yet another front-end state management library promising to fix all the problems caused by the previous iteration... Slowly you become jaded enough to find yourself subconsciously hoping these projects fail so you don’t have to waste your time learning their specific _dogma_ (because of course it can’t just be “entities”, “events”, and “handlers”. This new _snappier_ API uses “atoms”, “signals”, and “transducers”)
The reality is that most of the _real_ problems within a system (at least the interesting ones) are are at Two and above. So the constant churn at One just becomes an annoyance that takes focus away from the important bits.
I’d _gladly_ take some churn at the level of solving _my_ domain problems. Unfortunately, thus far, it seems I’m the only one writing anything that fits that bill...
The problem with the above is that the easier it becomes to go from Zero to One, the more _replaceable_ One becomes. After all, you can learn it in no time!
Naturally this leads to more and more churn and every developer who is already _at_ One or above has to keep going back and re-learning it in order to “keep up with current trends”.
After a while it becomes tiresome to see yet another front-end state management library promising to fix all the problems caused by the previous iteration... Slowly you become jaded enough to find yourself subconsciously hoping these projects fail so you don’t have to waste your time learning their specific _dogma_ (because of course it can’t just be “entities”, “events”, and “handlers”. This new _snappier_ API uses “atoms”, “signals”, and “transducers”)
The reality is that most of the _real_ problems within a system (at least the interesting ones) are are at Two and above. So the constant churn at One just becomes an annoyance that takes focus away from the important bits.
I’d _gladly_ take some churn at the level of solving _my_ domain problems. Unfortunately, thus far, it seems I’m the only one writing anything that fits that bill...
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
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
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.
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.
Yeah hitting the up arrow a couple of times then return is a real pain.
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.
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.
Especially lovely now when one might want to use clang and some CFLAG you set breaks a bad check. It's also very annoying to correctly pass PIC and PIE flags when the makefile builds both libraries and executables. I loathe automake.
Really not that bad. Almost always, configure make make install. And the main thing is the expectation. We always expect there to be dependencies and we expect to install them by hand and usually they were documented. Any errors would be easily understood (undefined reference or linker error). Now you have these systems that try to do things for you, you expect things to just work, when they don't your expectations are slighted and you get mad. The upside of all this tooling is the same joy you'd get in the 'bad/good old days.'
Easy for a user, perhaps, but imagine maintaining it!
The FreeBSD or Debian port maintainer maintained it for you.
The seedy underbelly of all of this stuff is that most of the libraries and dependencies and pet projects that somehow became ubiquitous never worked outside of the lone developer's laptop, or the one compsci department's ancient from-scratch installation, etc.
And if you asked him why it didn't work he'd tell you to go fuck yourself.
The seedy underbelly of all of this stuff is that most of the libraries and dependencies and pet projects that somehow became ubiquitous never worked outside of the lone developer's laptop, or the one compsci department's ancient from-scratch installation, etc.
And if you asked him why it didn't work he'd tell you to go fuck yourself.
I remember when I was a kid I tried for days to install gentoo and it just was not working. After so many hours of banging my head against the wall, I realized the CD was corrupted. Re-burning the iso fixed it
Yes, the increase in accessibility seems much nicer now than waves hand before GitHub and Arch Linux Wiki.
But I found the examples given in this blogpost striking: https://tonsky.me/blog/good-times-weak-men/ One of the most prominent tech companies (Apple) released a new music program to replace their older music program. The replacement program included several easy-to-notice UX bugs.
The bugs surely aren't from a lack of attention, expertise, or resources. And while obviously it's not easy to write a program like that, I think the best explanation would sound something like "towering pile of shit".
But I found the examples given in this blogpost striking: https://tonsky.me/blog/good-times-weak-men/ One of the most prominent tech companies (Apple) released a new music program to replace their older music program. The replacement program included several easy-to-notice UX bugs.
The bugs surely aren't from a lack of attention, expertise, or resources. And while obviously it's not easy to write a program like that, I think the best explanation would sound something like "towering pile of shit".
I would disagree strenuously with the fact that it's easier to get started now than in the past, unless you're talking about the early 90s when the World Wide Web was still nascent.
10+ years ago, you could just install a server-side rendered web framework on a VPS or dedicated server you rented from a hosting site, and you'd experience a far smoother developing experience compared to today's Javascript churn. I'll take Django over React+Node.js+Docker+etc. any day.
And compare modern devops to ye olde webmaster ways. It's much easier to get started by writing a few bash scripts and customizing Nginx configs than to learn how to use Kubernetes, Docker, Terraform, etc.
10+ years ago, you could just install a server-side rendered web framework on a VPS or dedicated server you rented from a hosting site, and you'd experience a far smoother developing experience compared to today's Javascript churn. I'll take Django over React+Node.js+Docker+etc. any day.
And compare modern devops to ye olde webmaster ways. It's much easier to get started by writing a few bash scripts and customizing Nginx configs than to learn how to use Kubernetes, Docker, Terraform, etc.
Nah, you can still do that.
Nowadays you can get cheap internet access, and you can buy a used okay-level laptop, get a free domain (like .tk, just a bit better from Google, the .dev), get a free VPS from AWS, and you can run whatever you want on it.
PHP has a built in web server, you can start developing with Laravel/Symfony easier than ever.
You find DigitalOcean tutorials for basic things easily, and you don't have to try to make stuff work on shady adware shared hosting portals.
The old webmaster days. Uh those were horrible. People tried to do blue-green deployments with Capistrano and PHP cache invalidation with atomic rename. And then folks spent years hacking RoR stuff to make it scale.
Yeah, Django is nice, but Python is a mess. Now with mypy finally there's some light at the end of the tunnel.
Nowadays you can get cheap internet access, and you can buy a used okay-level laptop, get a free domain (like .tk, just a bit better from Google, the .dev), get a free VPS from AWS, and you can run whatever you want on it.
PHP has a built in web server, you can start developing with Laravel/Symfony easier than ever.
You find DigitalOcean tutorials for basic things easily, and you don't have to try to make stuff work on shady adware shared hosting portals.
The old webmaster days. Uh those were horrible. People tried to do blue-green deployments with Capistrano and PHP cache invalidation with atomic rename. And then folks spent years hacking RoR stuff to make it scale.
Yeah, Django is nice, but Python is a mess. Now with mypy finally there's some light at the end of the tunnel.
So what’s stopping you from using Django?
If you see that argument, you're making it.
The author is not pining for the good old days. In fact, he specifically says that when he was starting out, the tooling was terrible.
The author is not pining for the good old days. In fact, he specifically says that when he was starting out, the tooling was terrible.
> 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.
I see this a lot as well. And frankly it scares me. It should not be very easy or quicker to go from Zero to One at the expense of footgunning One to Two and beyond.
Practices and culture are easily learned when you are just starting. And those practices stay with you till the end. It is very difficult to unlearn something, especially when you learned it while starting out as it becomes a kind of second nature.
Those practices might not harm when you are making basic sites or demo apps in your spare time. But when an engineer with these practices goes to work on something like the software for controlling Teslas, it suddenly becomes a big problem.
In my view, it is better to take some time to make a solid foundation than to quickly make a leaning tower of software that could, in these days of software in everything, lead to catastrophe.
I see this a lot as well. And frankly it scares me. It should not be very easy or quicker to go from Zero to One at the expense of footgunning One to Two and beyond.
Practices and culture are easily learned when you are just starting. And those practices stay with you till the end. It is very difficult to unlearn something, especially when you learned it while starting out as it becomes a kind of second nature.
Those practices might not harm when you are making basic sites or demo apps in your spare time. But when an engineer with these practices goes to work on something like the software for controlling Teslas, it suddenly becomes a big problem.
In my view, it is better to take some time to make a solid foundation than to quickly make a leaning tower of software that could, in these days of software in everything, lead to catastrophe.
> Those practices might not harm when you are making basic sites or demo apps in your spare time. But when an engineer with these practices goes to work on something like the software for controlling Teslas, it suddenly becomes a big problem.
Well, the reality is that most businesses only need basic sites and you don't need trained engineers to build them. Basic developers can do it as well and giving them the tooling to do so helps.
There is a lot of value in making programming for "basic" stuff like a CRUD web/mobile app about learning to use tools rather than learning to understand the whole system (i.e. programmer vs engineer).
A comparison I really like: To build a house, you need one engineer for statics, but a lot of construction workers actually putting it together. And even that one engineer for the statics is more for safety than actually necessary, if you build some basic house with the basic default material. Because it's proven over and over again that it holds and the margin for errors is quite large before there is any risk of collapse.
Well, the reality is that most businesses only need basic sites and you don't need trained engineers to build them. Basic developers can do it as well and giving them the tooling to do so helps.
There is a lot of value in making programming for "basic" stuff like a CRUD web/mobile app about learning to use tools rather than learning to understand the whole system (i.e. programmer vs engineer).
A comparison I really like: To build a house, you need one engineer for statics, but a lot of construction workers actually putting it together. And even that one engineer for the statics is more for safety than actually necessary, if you build some basic house with the basic default material. Because it's proven over and over again that it holds and the margin for errors is quite large before there is any risk of collapse.
See arguments against excel/vba...
Nothing has changed, today's web frameworks are pretty much worse on all fronts than the mess of excel, access, vb apps written by people without any formal training. At least many of those utilities worked for years after being created, unlike this mess which requires constant reworking just to continue working.
Nothing has changed, today's web frameworks are pretty much worse on all fronts than the mess of excel, access, vb apps written by people without any formal training. At least many of those utilities worked for years after being created, unlike this mess which requires constant reworking just to continue working.
> "good old days" there was Unix and apt and it was brilliant
Apt is still here.
Apt is still here.
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.
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.
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.
> 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.
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.
"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.
Perl also did this in the late 90s. "Possible runaway quote on line 123"
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.
The Vax C compiler used to do this, and mostly got it right.
It was a complete nightmare trying to port code that compiled and ran perfectly well on the dept microvax when we all transitioned to Ultrix and Linux.
As a result of those months of pain, even thirty years later I’m a huge fan of strongly typed languages, compiling with -Wall and -Werror, and have a zero-warning policy.
If you’ve never gone through it, you wouldn’t understand...
It was a complete nightmare trying to port code that compiled and ran perfectly well on the dept microvax when we all transitioned to Ultrix and Linux.
As a result of those months of pain, even thirty years later I’m a huge fan of strongly typed languages, compiling with -Wall and -Werror, and have a zero-warning policy.
If you’ve never gone through it, you wouldn’t understand...
I don't mind missing semicolons. In c++ paren/bracket mismatches are the bane of my existence. Specifically, if you open a paten in a header file and forget to close it, gcc will dump reams of errors and warnings, even on fairly small projects. Usually the problem is the first error, but for a dangling paren, that one's a red herring, you want the last error. It says you have an unclosed curly-brace in the top-level file. This appears to be due to a confluence of footguns:
1. Files are allowed to have different numbers of open & closed brackets. So who knows where the real error is? For all the compiler knows, you left that paren open deliberately in one file and forgot to include the paren-closing file?
2. C++ syntax generally lets you put anything anywhere -- the compiler doesn't seem to mind that I'm defining a new class literally inside the parentheses of a function call? Is that actually legal? Who knows. But I'm still a little confused... after opening that paren I almost immediately use too many closing braces -- why isn't that spotted immediately?
1. Files are allowed to have different numbers of open & closed brackets. So who knows where the real error is? For all the compiler knows, you left that paren open deliberately in one file and forgot to include the paren-closing file?
2. C++ syntax generally lets you put anything anywhere -- the compiler doesn't seem to mind that I'm defining a new class literally inside the parentheses of a function call? Is that actually legal? Who knows. But I'm still a little confused... after opening that paren I almost immediately use too many closing braces -- why isn't that spotted immediately?
Its bad enough when tools change whitespace without my knowledge (unless this is an option I enabled), I sure don't want them changing anything else.
Why is this bad? As someone who has spent a lot of time writing code with auto formatting turned on, I’m genuinely curious which parts of your workflow break when the whitespace changes out from under you.
Most of the pain from this comes from python repos with multiple developers (on different OS) pushing code.
Using indentation for control flow was a bad decision, even if most modern IDEs now have good solutions for it.
Using indentation for control flow was a bad decision, even if most modern IDEs now have good solutions for it.
I tried Atom for ten minutes and then gave up on it because it made undesirable whitespace changes by default.
Doing code formatting is fine; doing code formatting on lines from a checkout that I didn't change is bad. Yes, the file should be reformatted. But let me know before doing it, so I can make a formatting-only commit so it's easier to review when I put up the PR.
Doing code formatting is fine; doing code formatting on lines from a checkout that I didn't change is bad. Yes, the file should be reformatted. But let me know before doing it, so I can make a formatting-only commit so it's easier to review when I put up the PR.
When I'm working on new code, sure, I'll enable it, but other times when working on existing code I just want to make the minimum changes necessary. For example if I'm explaining to someone why their code doesn't work when I try it and what little change would help, sending them their code with dozens of irrelevant changes in addition to the relevant one isn't going to help my case.
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.)
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.)
I dread opening up older swift projects because I know they aren't going to compile. Go is a breath of fresh air.
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.
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.
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.
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.
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.
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?
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?
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.
Unpopular HN opinion: we need more commercial SWE tools. This is the expected outcome of under-organized underfunded ad-hoc development of professional tools.
Whilst reading about this I found myself thinking back to my days as a student, writing C++ with Visual Studio 6.
If you were able to install everything, including the documentation, to your hard drive you never really needed anything else (which was good, because I didn't have internet access at home to begin with - too pricey).
You had high quality development and debugging tools, and then in MSDN you had this absolutely exhaustive, encyclopaedic documentation that covered every possible topic in depth, and a good enough search function that you could usually find what you were looking for without too much difficulty.
In some ways - not all ways - those were the days.
If you were able to install everything, including the documentation, to your hard drive you never really needed anything else (which was good, because I didn't have internet access at home to begin with - too pricey).
You had high quality development and debugging tools, and then in MSDN you had this absolutely exhaustive, encyclopaedic documentation that covered every possible topic in depth, and a good enough search function that you could usually find what you were looking for without too much difficulty.
In some ways - not all ways - those were the days.
Hmm, if you put it like, "We should pay for quality tools." I think it comes off less unpopular maybe?
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.
I've noticed that too! It's like basic business principles are warped in the presence of too many computers.
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
19 breaking changes in ... 10 years?
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
19 breaking changes in ... 10 years?
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.
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.
Rider and IntelliJ also have the features you mentioned, and then some.
> 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"
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"
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.
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.
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.
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.
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.
> 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.
> 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).
Hm, that is actually a point where (in my experience at least) the Java community tends to do pretty well: in nearly all cases where I see an API that is deprecated there is a comment that at least tells you what you should use instead. Additionally, "deprecated" usually means that it still works, which is a whole lot better than having it simply disappear.
Hm, that is actually a point where (in my experience at least) the Java community tends to do pretty well: in nearly all cases where I see an API that is deprecated there is a comment that at least tells you what you should use instead. Additionally, "deprecated" usually means that it still works, which is a whole lot better than having it simply disappear.
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.
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.
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.
> 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
Oh, that's where the simple projects "start the project".
Even with wheels around, that's where you'll get an error message that eventually decodes as "There is no C-Compiler on this platform". And then you're installing clang or gcc. And make. And configure. And fuckit, just install build-essentials.
And then you start hunting C dependencies. Which I can because I have some experience building C, enough to never to it again. And then you start learning which link error with libpython indicates which minor version of python is actually required. And eventually you start looking into really weird hacks with chroots to be able to have multiple python-devel headers around. Or use containers to compile a python library.
Sorry. I like the language python. But installing python packages to do something... I don't know, it eventually hurt something inside me. I severely never want to deal with python in production anymore unless I can just globally install it in a container and stop caring.
Java tends to be tolerable. People tend to overuse maven beyond all repair, and gradle can be funky. But none of them compare to the hell python requires.
Oh, that's where the simple projects "start the project".
Even with wheels around, that's where you'll get an error message that eventually decodes as "There is no C-Compiler on this platform". And then you're installing clang or gcc. And make. And configure. And fuckit, just install build-essentials.
And then you start hunting C dependencies. Which I can because I have some experience building C, enough to never to it again. And then you start learning which link error with libpython indicates which minor version of python is actually required. And eventually you start looking into really weird hacks with chroots to be able to have multiple python-devel headers around. Or use containers to compile a python library.
Sorry. I like the language python. But installing python packages to do something... I don't know, it eventually hurt something inside me. I severely never want to deal with python in production anymore unless I can just globally install it in a container and stop caring.
Java tends to be tolerable. People tend to overuse maven beyond all repair, and gradle can be funky. But none of them compare to the hell python requires.
> 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
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”And pyenv for the right Python version
With poetry init, the tool walks you through project setup
With poetry init, the tool walks you through project setup
yep, pyenv is step 0 for sanity.
how do you get poetry on the box though?
to develop:
This is ok-not-great; i’d prefer for python and pypi to put some official funding and weight behind one de-facto 517/518 build system and stabilize things a little. However this is python we’re talking about, so it’ll never happen.
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
pip can be used by itself to install a poetry managed project, so just venv/bin/pip install
as normal.This is ok-not-great; i’d prefer for python and pypi to put some official funding and weight behind one de-facto 517/518 build system and stabilize things a little. However this is python we’re talking about, so it’ll never happen.
I don't understand where the nightmare part comes from.
Building a jvm project these days can be a matter of cloning the git repo and running `./gradlew build`.
Building a jvm project these days can be a matter of cloning the git repo and running `./gradlew build`.
As someone that hasn't used Java in production deployment, I tried to play with an open source project that seems to run on JBOSS Wildfly. After about 3 frustrated hours, I cut my losses, deleted the docker containers and images, and decided it was simply not worth it.
I could build the code in IntelliJ IDEA, but I couldn't for the life of me figure out how to actually run it to simply test it and play around with it. I can only concur there is something seriously wrong with the Java world/community. Perhaps it's too focused towards enterprise, where you can afford to have one person specialise in sitting at a desk, monitoring Wildfly?
I could build the code in IntelliJ IDEA, but I couldn't for the life of me figure out how to actually run it to simply test it and play around with it. I can only concur there is something seriously wrong with the Java world/community. Perhaps it's too focused towards enterprise, where you can afford to have one person specialise in sitting at a desk, monitoring Wildfly?
>“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.
Because what you mean and what the closest syntactically correct program to what you typed are two very different things.
Right? I bet it's the very same people that complain about JavaScript doing exactly that and are then surprised as to why their code doesn't do what it's supposed to...
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.
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.
Archive Link for your convenience, because website seems to be down for me:
https://web.archive.org/web/20200606144232/https://shkspr.mo...
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.
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!
A good (read: native) and well-architectured desktop app probably has more in common with backend development, UI design aside!
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.
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.
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 ;)
Sure, that’s fair. I misspoke.
I mean that it always seems to relate to things with graphical interfaces. To be clear, I don't doubt it's possible to create well-architected things with GUIs.
I mean that it always seems to relate to things with graphical interfaces. To be clear, I don't doubt it's possible to create well-architected things with GUIs.
It is the cost of making computers "user friendly" and providing a positive "user experience". Can't be done without layers of crap, it's a law of physics.
The alternative is to deal with computers how they naturally "want" to be talked to. Then life is simple, you just need _engineers_ to write the software, and to _train_ people to use it.
The alternative is to deal with computers how they naturally "want" to be talked to. Then life is simple, you just need _engineers_ to write the software, and to _train_ people to use it.
I don't know if I buy this. I don't see why it's inherently impossible to create a computer product that is both well-engineered _and_ easy to use.
[deleted]
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)
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)
The way to avoid that is not ugly or particularly tedious:
import library
library.function
That doesn't prevent writing a different value into library of course.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.
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.
"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.
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.
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.
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.
Maybe people should choose their tools based on mature technology stacks rather than whatever happens to be cool this month.
"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.
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).
Definitely should read the Jargon file entry for DWIM.
More and more, though, there’s such magic being performed by complete and libraries that you sometimes want DAIS.
More and more, though, there’s such magic being performed by complete and libraries that you sometimes want DAIS.
Hah, if he finds Gradle arcane and unintuitive, wait until he actually starts developing the Android app itself...
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.
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.
> 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.
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.
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:
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.
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.
> 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.
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.
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.
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!
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!
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.
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.
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.
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.
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.
I would really love it if a project I made two years ago would still compile, but it doesn't.
> “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.
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.
When I look for a tool and I find one written in JS, I usually move on without even trying to install it. I've just been burned too many times.
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!
It's called a typoo
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-Configura...
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.
Gradle is designed to keep people who spend time getting good at it employed.
It’s a real embarrassment to our industry.
It’s a real embarrassment to our industry.
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.
Makes me want XML and Maven back; at least my IDE can guide me based on the schema files it parsed.
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.
[deleted]
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.
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.
If you think this is a pile of "shite", try web development...
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.
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.
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.
[deleted]
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
[2] https://dev.to/kspeakman/elm-019-broke-us--khn
[3] https://news.ycombinator.com/item?id=17842400
[4] https://deno.land/std
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
[2] https://dev.to/kspeakman/elm-019-broke-us--khn
[3] https://news.ycombinator.com/item?id=17842400
[4] https://deno.land/std
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.
Why is rust the most loved language? Perhaps it's because the creators and curators seem to care so much about these exact things.
building the contract tracing app going well then?
If android phones would update once in a while we wouldn't be stuck with all this gradle dependency rot.
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.
> 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.
That’s not the role of a compiler, for good reason. I stopped reading the article after reading this line.
The Android dev experience used to be built on Eclipse. Woohoo!
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.