What is the most painful for me with all this, other than it being 99% self-inflicted and not caused (you could argue it's encouraged by it, but the ultimate cause is the culture) by the language, is the fact that it has infected Kotlin code. Kotlin was built to increase expressive power of the language, doing away with multiple limitations of Java and offering lots of modern-ish features on top of it. The community looks split in half: the Kotlin community tries to get the most out of Kotlin, and the Android community that does anything in their power to make Kotlin back into Java, writing code as if the limitations were still in place and new features didn't exist. I know that the churn and "production readiness" of things on Android generally favors a more conservative approach, but it's still too much. I cry tears of blood every other code review I'm forced to do.
If there's a single, definitive resource that I could point my coworkers to and eventually turn it into enforced guidelines, the author can count on a serious donation from me.
I don’t know any good resources unfortunately. I feel like we need a “motherfuckingwebsite” equivalent for this - “just use a motherfucking function”. I want to link it to whoever insisted on adding a useless TextDecoder class in javascript that you have to instantiate, instead of just calling textDecode(…, “utf8”) using a global function like the rest of the standard library.
I think part of the problem is that most people who hate enterprise java just learn a different language, set their resume on fire and start over somewhere better. That’s certainly what I did. I’m writing rust at the moment, and thankfully the lack of classes and distance from the JVM seems to keep most of this nonsense out. But having all the doubters leave makes the problem within the java ecosystem worse.
I for one would rather punch the person who proposes such a global function as the only mechanism for conversion, because charset conversion is a reasonable thing to do on chunked partial inputs, and maintaining the state for conversion yourself is actually quite painful. Wrapping a stream converter into a one-shot function is much easier than the reverse, wrapping a one-shot function in a stream converter.
Said another way: the functional, simplified interface doesn't mean you have to get simplified or lacking functionality. Haskell wouldn't exist if that was the case. The simplified interface providing as much functionality as the more complex interface is possible because the expressive power of JS is leagues above Java - porting Java patterns that emerged due to Java's shortcomings (some call them "design decisions", and they're also right) to JavaScript is simply not a good use of JS as a language.
Fight me.
Javascript has a separate TextDecoderStream class if you want to support chunked, partial inputs. The TextDecoder class doesn't support streaming input at all. And it never will, thanks to the existence of TextDecoderStream.
TextDecoder only provides 1 method - TextDecoder.decode(). And the method is pure! So you could just make it a global method without any loss of functionality. The entire class has no mutable state whatsoever. Its just a container for some options, passed into the constructor. Those options could just have been passed straight to a global decode() method.
https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder
This might be idiomatic C++, but its terrible javascript. I had a friend who worked on the Chrome team years ago. He said a lot of the browser engineers who design javascript APIs are C++ programmers who don't know javascript properly. So of course they port C++ ideas into javascript directly. They don't know any better. This is why javascript's standard library is an incoherent mess.
String.fromUint8Array: (input: Uint8Array, encoding: string): String;
Would be a fine, simple addition where it probably should be. Maybe calling the default for UInt8Array "String.fromBinary" instead.Lol true
Don't forget all the getters and setters merely updating/reading a variable
Python says "explicit is better than implicit" but Java goes too far with it, and in the most verbose/inflexible ways possible
> and in the most verbose/inflexible ways possible
It's actually extra flexibility meant for two things: being able to override the getter/setter in a subclass, and keeping a consistent interface so users don't need to change how it's called if there was a refactor that adds something to the getter/setter (such as transforming the value because a different representation was more useful internally; particularly useful for libraries).
Python has @property to maintain that interface if need be, but these Java conventions started when no such thing existed in the language. I haven't done Java in a long time, so I don't know if it has it even now..
AS3 and Flex was practically an attempt by these people to take over the language. Thankfully that failed.
TS is great by comparison!
Take his views on "clean code" for instance. Or really any conception of "clean code." Clean code is bullshit. I guarantee you can take anything Uncle Bub or other notable programmers say about clean code, apply them to a tee at your job, and be told that your code isn't clean or "feels icky" by whomever joined the team before you did. No description of clean code that I've read has ever been truly helpful in my career. The only thing you can really do is decide what you think is clean code and for you and your team to reach a level of agreed disagreement so that everyone can get their job done. One person's descriptive variable name is another person's "that's too long I can't read with all these confusing names", and one person's set of short purposeful functions is another person's "I can't tell what's happening cuz I have to jump between all these functions." At the end of the day, you barely have time to write "clean code", because your boss wants features rolled out ASAP.
Uncle Bub is also one of those guys who thinks good code doesn't need comments because it's self descriptive. This is one of the worst ideas to ever have met the software industry. No one's code is self descriptive. It's all a bunch of gobbledygook because it's meant to be run by a computer and just understandable enough for a human. It wouldn't kill us to just write some documenting comments detailing the intention behind code, but sadly most programmers either are too lazy or believe that if they need to add comments then that necessarily means their code smells. The result is that nobody knows anything about any given software project except for those who have been on the project the longest, and even they often don't know because... surprise... nobody wrote anything down! Just like with "clean code", it should be left up to teams how they want to add comments to code, and how much you comment your code shouldn't be influenced by memes from other programmers.
Don't even get me started on FrAgile. It's just a way to dupe programmers into taking on more work and doing the job of middle management for them.
Why don't you write comments describing what the code does?
> and even they often don't know because... surprise... nobody wrote anything down!
Well, read the code
And who mentioned writing comments only about intention?
> Why don't you write comments describing what the code does?
Yes, why don't we?
> Well, read the code
Because code is never long and vague, and human language can never sum up complex ideas or code?
We used to see the same thing with companies that had moved C engineers over to Java. Lots of weirdly overcomplicated C constructs. Meanwhile the newbs who only knew Java were writing FactoryFactoryFactoryImpls. :facepalm
It doesn’t have to be that way (see also Guice).
But the Uncle Bob effect is sadly real.
Then again,Java itself has Spring, starting out as '4 classes for an EJB is insane architecture overload' and ended up in dynamic injection architecture astronaut land.
Foundationdb has official bindings in C, Python, go, Ruby and Java. The real bindings are in C, and all other languages’ bindings are well written, idiomatic wrappers around the same C library exposing the same functionality. The Java bindings need over twice as many lines of code as the Ruby and Python bindings to achieve the same thing.
Even if this style of Java is only 10% less productive than that of idiomatic Kotlin, Go or Python, you will probably break even on the investment of migrating languages after mere months. I think that undersells it. The productivity difference is probably much higher. Especially for large projects.
Improving your personal and teams long term productivity is just about the highest value work you can do.
I disagree. We might understand what I meant by "style"[1] differently. As I think of it, it's comprised of things that have an actual, measurable impact on the effort required to develop the codebase(s) over time. It's not about tabs vs. spaces, snake_case vs. camelCase, or anything even remotely like that. I'm not trying to establish a company-wide set of guidelines for the sake of it - I believe that relatively minor things (in the scope of a single project) can lead to significant savings at the scale of tens of projects and five years of a maintenance window.
As for the guidelines themselves: I don't care what they are, exactly, as long as a) they're there; b) they reduce said effort; and c) they're followed.