4 ms·
Annotation-based programming might seem cool now, but wait a few years. Magic always seems cool when you add it to a project - hey, look - I don't have to do <
by apo 8y ago
Annotation-based programming might seem cool now, but wait a few years.
Magic always seems cool when you add it to a project - hey, look - I don't have to do <tedious thing> anymore.
Then time goes on, and you (or your successor) opens up the project to track down a bug. Only there's no logical flow - things just seem to happen as if by magic.
Lombok strikes me as magic in these ways.
I actually had to go to the project home page to figure out what problem it solves:
https://projectlombok.org https://projectlombok.org
The examples refer to a specific kind of boilerplate, namely the kind that comes from treating classes a dumb bags of properties. Getters directly returning private fields. toString methods, etc.
An alternative approach to Lombok would be to think about how the project ended up with so many dumb data classes. How could the project be refactored to eliminate them, for example?
Doing so would avoid the need for magic and produce a code base in which effect followed cause.
- arcticbull 8y agoI liked to refer to the genre as MOP -- Magic Oriented Programming. Every ecosystem I've seen go down that route ends up bailing out. A good example of this would be Apple's Cocoa Bindings [1] on macOS that were killed with fire when the iOS APIs were defined, and KVO [2] which is flat out rejected at every company I've ever worked. On the other hand, when built into the language, this kind of explicit but automatic code generation can be awesome (as in Rust's #[derive()] traits [3]) but I think the difference there is the compiler/language vendor agree to support it indefinitely. [1] https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaBindings/CocoaBindings.html https://developer.apple.com/library/archive/documentation/Co... [2] https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html https://developer.apple.com/library/archive/documentation/Co... [3] https://doc.rust-lang.org/rust-by-example/trait/derive.html https://doc.rust-lang.org/rust-by-example/trait/derive.html
- Illniyar 8y agoRails would be the opposite example. Magic all the way down and the ecosystem is not even contemplating the idea of bailing on it.
- arcticbull 8y agoGood point!
- raducu 8y agoYes, but as a programmer when I'd start working on a new project, I would call it a Rails project, I've never heard of a Lombok project. Sure, I've seen Spring/J2EE projects that used Lombok... some 10 years ago, but the idea seemed to have died down, maybe it's my own bubble. Automagic is ok for a specific type of problem (Rails for webaps?), Lombok however reminds me a bit of the promises of AOP which failed to gain traction outside frameworks. There are other highly opinionated frameworks/stacks that have mixed adoption in the java world -- jhipster seemed to gain some traction, but people seem to just use bare spring boot nowadays(which is quite opinionated) I don't have absolutely anything against small projects, I'd love to work more on smaller projects, but 18000 lines of generated code is NOTHING, try to convince a medium team to use Lombok, you'll very soon end up with people loving or hating it, removing it for debugging purposes, creating their own generators and very soon it's a real mess. But all that is just my experience, I'm not trying to dismiss Lombok or any approach, if it works for you, great!
- geezerjay 8y ago> I've never heard of a Lombok project. You've must have heard about Spring projects. I'm yet to come across a Spring project that doesn't use lombok. > Sure, I've seen Spring/J2EE projects that used Lombok... some 10 years ago, but the idea seemed to have died down, maybe it's my own bubble. Perhaps it's my bubble as well but I'm still seeing Spring projects in production today that feature lombok extensively. Not all organizations are willing to burn through cash to jump to the flavor of the month every couple of months. If you deployed a system and the system works, you need to discover a very good reason to throw a revolution and start from scratch with a new tech stack.
- throwmeback 8y agoI recall my limited time with Ruby and Rails being the really frustrating, seconded probably only by Tornado (either misleading error messages or no error messages whatsoever, requiring me to get dirty with the debugger for the most minor of things). RubyMine had no idea about more than half of the Ruby code being written in the project. I couldn't grasp the concept of symbols in Ruby reliably enough. E.g. methods used either symbols or strings - I couldn't discern a pattern for which to be used when. This was the magic part of it - things seemed to work seamlessly but when they wouldn't, I had no idea where should I even begin to look. Also every file had to be annotated for the strings to be treated as immutable. No ways to set it globally, project-wide. It felt like a mess. On the plus side, there were gems.
- geezerjay 8y ago> An alternative approach to Lombok would be to think about how the project ended up with so many dumb data classes. Mapping entities to/from data transfer objects is a well established technique, as using dumb POJOs to drive serialzation/deserialization. If you throw CQRS into the mix you can get a POJO/endpoint ratio that is greater than 1:1. Do you want to write bug-prone boilerplate code for all those POJOs you are forced to write? Or do you prefer to simply add lombok to the project and add a single class annotation? It's disingenuous to blindly criticize the extensive use of POJOs and DTOs as if it was code smell. In some applications it's quite the opposite. There is a ver good reason why lombok is very popular, as are other projects designed to complement it. In .NET Core land, where POCOs are used extensively, AutoMapper is also a must-have just because the need to handle POCOs without having to write all the boilerplate code is very real and pervasive.
- ec109685 8y agoWhy bother with getters and setters for a POJO though if it’s all in a project you control? You can always make a property private later if you really need to add behavior to the fetcher.
- ehnto 8y agoAnnotation based magic has always felt like a hack to me. Surely there is a way to solve these problems within the constraints of the language. It adds a layer of ambiguity to what code any class actually contains at run time and that is never ideal.
- 75dvtwin 8y ago> Annotation-based programming might seem cool now, but wait a few years. I even have this experience on my own projects and with much shorter span than a year. When I go back to a code base I worked just 3-4 month ago -- I have very hard time following Dagger injections. Braking one of the Dagger providers (I use dagger 2) creates 10s and 10s of compilation errors. So I have been slowly removing dagger from my code bases. As I just cannot follow it, I do not know it well enough either. I stopped using Lombok for same reason, although I found Lombok is much more intuitive. I thought about going to Kotlin, but it was just too much of cognitive overload (in this particular instance both for backend and android UI). Instead, I am finding the use of rxjava and friends a lot more intuitive and helpful for the type of things I need help with (interconnecting components on different threads, with different lifecycle and data structure semantics, with lots of asynchronous behavior options). And the same rx-<> library is available to many other languages, therefore, the skill I am building up is sort of 'cross-language'.
- woolvalley 8y agoThats fairly funny, since I find Rx to be the very complicated thing if used extensively in a project and hard to reason about memory usage and other things when trying to dig into problems. On top of that it creates huge ass stack traces that makes finding your code difficult unless your debugger can filter out specific packages: https://github.com/ReactiveX/RxJava/issues/4834 https://github.com/ReactiveX/RxJava/issues/4834 Kotlin on the other hand is a fairly clear language!
- mrbrowning 8y agoI grew to really hate annotation-based magic when I worked on a project that used Jackson for JSON serialization. Not only does it circumvent the type system entirely, it also makes errors incredibly hard to track down by virtue of the fact that there are next to no static constraints on how annotations are used. Something as simple as adding a serializable field to an interface or object often ended up requiring a ridiculous amount of trial and error to get right. I think annotations are valuable if used judiciously, but unfettered annotation-based metaprogramming only ever leads to pain in my experience.
- raducu 8y agoJava is not the most powerful language, yet it has huge adoption; the main reason is the number of quite OK and very powerful libraries. Sure, it's very easy to add Jackson, but people severly underestimate the problem of JSON <-> POJO mapping(multiple ways of doing it and different programmers wanting to do it in different ways). So when you start it's very easy to just add some Jackson annotations and you think it's going to be smooth sailing from now on; add some complexity down the road and you just use some stackoverflow recipes to do the thing I want (without any in-depth Jackson knowledge) and it still is ok-ish; add some more complexity down the road and then you feel the frustration of using Jackson. Add in some web annotations, security annotations, ORM annotations, logging, test annotations and so on and it's the same story -- you are in fact doing something very complex and when you depart from the happy path of using the functionality via annotations, it gets quite frustrating. I really don't know anything "better"(time wise) to accomplish the same thing though.
- dmichulke 8y ago> Then time goes on, and you (or your successor) opens up the project to track down a bug. Only there's no logical flow - things just seem to happen as if by magic. This. I use a different but similar analogy borrowing from DnD. - Java and especially annotations need wisdom (WIS) - E.g., Clojure needs intelligence (INT) This holds even for syntax where homoiconicity requires just so much less "experience".
- KoenDG 8y agoSo, like Spring? ba dum tish
- j16sdiz 8y agoLombok only minimal boilerplate, not much magic. Most of them can be generated in IDE automatically, but those generated code hurt readibility. It is difficult to avoid Getter/Setting in Java due to how popular framework works. @ToString are useful for debugging. Why hand code pages of println if it can be generated?
- pjmlp 8y agoRemember the days of Aspects all over Java codebases? I seemed a cool idea, however I thankfully no longer need to fix bugs in such projects.
- raz32dust 8y ago+1, I would rather have the cruft than have magic annotations. These dumb data classes also tend to proliferate when you are using other annotation heavy magic libraries like hibernate/spring. If you are having a dumb data class that is not a class that is meant to be serialized on disk (protobuf/avro etc.), then you are likely doing something wrong. See if you can avoid it.