8 ms·
I don't agree on the fact that lombok has brought us out of the dark ages. We used to use it, but it has some drawbacks. One of them, it's an additional depende
by fedeb95 4y ago
I don't agree on the fact that lombok has brought us out of the dark ages. We used to use it, but it has some drawbacks. One of them, it's an additional dependency. This, for a simple thing such as pojo, seems a bit overkill to me. The additional amount of time used to write some cose isn't worth the risk of additional bugs hidden in having one more dependency.
- marginalia_nu 4y agoRecord classes arguably do a lot of the same thing without the drawbacks.
- wtetzner 4y agoThe biggest thing missing from records that Lombok provides is withers.
- pron 4y agoIn the works: https://github.com/openjdk/amber-docs/blob/master/eg-drafts/reconstruction-records-and-classes.md https://github.com/openjdk/amber-docs/blob/master/eg-drafts/...
- ivan_gammel 4y agoI hope they will find a better solution, as this proposal will break encapsulation. Let’s say you model allowed transitions via business methods and thus restrict certain state changes. You can either serialize or deserialize state or perform an allowed transition. If wither becomes a language feature, it will allow forbidden state changes that cannot be caught by validation in constructor, which will allow deserialization of states A, B, C, but will not know that A->C is forbidden, thus making the following possible: var r = new R(A); r = r with { state = C; } // passes, resulting in untraceable error much later where alternative could be: r = r.transitionTo(C); // throws exception
- deleted 4y ago[deleted]
- logicchains 4y agoThe proposal is meant for records, and records are used for "plain old data", explicitly without any encapsulation.
- ivan_gammel 4y agoNope. If records were structures, they would not be allowed to have methods or overloaded constructors or even default constructor. The most obvious example of encapsulation in records is validation of state.
- kaba0 4y agoThey still don’t have encapsulation, all members are readable on purpose. Withers will likely go through the same default constructor so constraints can be upheld, though.
- ivan_gammel 4y ago>They still don’t have encapsulation, all members are readable on purpose. Public state does not mean no encapsulation. The purpose of encapsulation is to bundle state and behavior and hide them both behind an interface, but that interface can offer read access to state. The key here is behavior. >constraints can be upheld My example above demonstrates a constraint that cannot be implemented in a constructor.
- plumarr 4y agoIt can't but that's not due to the proposed solution for withers. The cause is Records themselves. Record are immutable on purpose and you want to add a mutation constraint whish will not play nicely. The proposed constraint will be triggered in this case : var r = retrieveFromDb(); (value is A) r = r.with(C) -> throw an exception But this only work if B is generated by the wither. If I deconstruct the record manually and reconstruct with C manually, it'll work. So this offer no garantee that this transition will never occur. I would even argue that this constraint can't be implemented at the level of the class, at least if the class is only a data carrier without external dependencies.
- dmitriid 4y agoStrange how you consider property assignments from C# but only in the very limited scope of `with`. Why not have all other lessons from C# like `{get; set;}` and object initialisation (among other things) syntax is beyond me. (Well, "we don't adopt strategies [whatever that means] from less successful languages" is a reason I guess https://news.ycombinator.com/item?id=28985688 https://news.ycombinator.com/item?id=28985688)
- pron 4y agoWhat I meant was that we don't adopt a feature just because some other language has it, let alone from languages that don't have the same philosophy as we do of trying to have as few features as we can get away with. Records are overall more valuable than properties (due to various reasons, from serialization to interaction with collections). But once you have records with "withers" the question becomes how valuable is it to also have properties. It doesn't seem like it would be helpful enough to overcome the drawbacks. BTW, C# didn't add properties as a "lesson." Properties in C# and JavaBeans have the same pedigree: RAD UI composer tools of the 90s [1]. They came to C# by way of VB. So really, Java would be adopting a VB solution, and there needs to be a good reason for that. [1]: https://en.wikipedia.org/wiki/Rapid_application_development https://en.wikipedia.org/wiki/Rapid_application_development
- dmitriid 4y ago> and there needs to be a good reason for that. A year ago I already said all the good reasons. There are many reasons why things like Lombock exist. There are reasons why people loathe writing interminable chains of builder methods. But sure. None of these are good reasons because something something Visual Basic. What Java will inevitably end up with is a yet another half-assed approach that only exists for a small part of the language and is not applicable to the rest of it. > BTW, C# didn't add properties as a "lesson." That's not what I wrote. This is literally from your link: "Digression: learning from C#" And look. Right below it, emphasis mine --- start quote --- The C# approach was sensible for them because they could build on features they already had (default parameters, properties) --- end quote --- And look. "Extrapolating from records" section basically says: Java has nothing, and will need to rebuild everything from scratch for this not to be a half-assed solution. Oh well.
- sverhagen 4y agoNot that I want to switch out one compiler plugin for the other, but Immutables gives you withers, if I'm not mistaken. I've not been much into withers, until today that is. But for everything else, Immutables has been doing a pretty decent job at my work outfits.
- deleted 4y ago[deleted]
- Matthias247 4y agoBut they require a new JDK version, and a surprisingly high amount of Java projects are still stuck on JDK8.
- pron 4y agoJDK 8 is now a minority, and if we count only projects that are still undergoing significant development it's a significantly smaller minority. The main reason some projects are still stuck on 8 is because they use old libraries that have made breaking changes, and don't have resources to adapt their use, let alone take on new ones.
- yakubin 4y agoOr they develop for Android. Not a minority.
- crummy 4y agoAre most android devs still working with Java or Kotlin?
- yakubin 4y agoI’ve worked for 2 companies so far which maintain a bit of Android code and neither used Kotlin. GitHub search for “#android language:Java” reports 49K repositories, while “#android language:kotlin” reports 25K repositories. GitHub is biased towards greenfield projects, not legacy corporate codebases, so I’d expect the ratio of Java to Kotlin code in non-open-source software to be much higher. I wouldn’t be surprised if it’s more than 10 times higher.
- pjmlp 4y agoAt least the lucky ones having Android 12 as baseline can now make use of Java 11 subset (because as usual Google only takes the parts of standard library they care about).
- pron 4y ago
- exabrial 4y agoLombok is a compiler extension, not a dependency. It does actually need to be present at runtime!
- actionfromafar 4y agoDoes not? But you could still see it as a transitive dependency of sorts.
- exabrial 4y agoyep :) I suck at typing
- hgsgm 4y agoIt's a compile-time dependency.
- exabrial 4y agoIn fact, no, it is not a dependency; your code will never see Lombok, only its effects. Lombok IS a compiler extension. It exploits one of the weirdest features that was introduced in Java 1.6: You can instruct javac to call a custom extension whenever it encounters a certain Annotation. This annotation doesn't need to be on the Applications classpath either. Weirdly, I haven't see this feature widely exploited by anyone _until_ lombok came around. Reference: https://openjdk.org/groups/compiler/processing-code.html https://openjdk.org/groups/compiler/processing-code.html
- yCombLinks 4y agoIf it's not included in the base java compiler it's a dependency.
- pjmlp 4y agoI never used it, nor do I plan to.
- misja111 4y agoWith Lombok I always felt that it was trying to fix a symptom while it ignored the underlying problem. If you don't like to write out getters and setters in your code, then consider not to implement them at all. Just use value classes with public fields. Or nowadays you can also use records. Some people use the argument that the advantage of getters/setters is, that you can add custom logic to them. But IMO that is an antipattern. And even more so if you then hide that enriched setter or getter using Lombok. Code should indicate to the readers what is doing, it shouldn't try to hide stuff that could be important.
- sverhagen 4y agoI feel that when I programmed in C++ before I went to Java, it was much more common to include more logic in your setters than just assigning the argument to the field. This is now almost twenty years ago, I was less experienced and the team I was on where I was writing C++ was small and inexperienced too, so maybe that's a misconception. But certainly, in Java the additional logic in setters is frowned upon; but so are public fields. So, it's really a cultural thing in that community. Thank goodness for records :)
- jillesvangurp 4y agoI never particularly liked Lombok either but I do appreciate what it does. Which is to remove a lot of boilerplate code related to setters, getters, hashcode, and equals functions, builder classes, etc. Writing that kind of boiler plate manually increases the likelihood of bugs, inconsistencies and allows other weirdness to creep into your code base. Also it's rather stupid work to do. These days, I use Kotlin, which removes the need for Lombok while still being able to play nice with it. The most recent version of Kotlin actually added a compiler plugin for Lombok annotations that makes it easier for people with legacy Java code bases with Lombok to introduce Kotlin to their code bases. Kotlin doesn't have direct support for lenses but it is a pretty popular feature with some frameworks. Arrow has an implementation for example. And Arrow is of course inspired by Scala. I've also used the Fritz2 framework for browser UIs. It uses compile time generation of lenses. I think they are a bit of a double edged sword. Looks like a lot of complexity for not a whole lot of gain to me. I like keeping things simple instead. This stuff does have the distinct taste of over engineering to it.
- iLoveOncall 4y agoThe risk of bugs because you forgot to update a setter after changing a field or something like this is way higher than the risk of bugs in Lombok.
- fedeb95 4y agoRisk is measured by multiplying likelihood with impact. A single setter, low impact, a single bug in lombok, or misused feature, impacts a lot