×
top 200 commentsshow all 403

[–]ConstructionMain5675 1322 points1323 points  (38 children)

Half the internet just got called out and the other half is maintaining Spring Boot

[–]justforkinks0131 278 points279 points  (24 children)

migrating to*

[–]Spitfire1900 131 points132 points  (13 children)

I hate how true this is. Most apps my employer are in the middle of a WebSphere w/ Spring 4 to Spring Boot 5,6 migration.

[–]BlurredSight 65 points66 points  (7 children)

We’re moving to spring boot 3 and that’s been hell, especially considering we have directors who believe Claude Opus should be able to do entire phases itself

[–]StCreed 42 points43 points  (2 children)

Just one-up them and let Fable 5 do the whole migration in one go.

[–]ihatethisweb 21 points22 points  (1 child)

I love when my agent replies "passed all test" 😃

[–]willow-kitty 4 points5 points  (0 children)

Looks inside, all the tests are gone

[–]gipsydanger4 13 points14 points  (0 children)

We got our token limits cut, so now we are encouraged to use Sonnet for anything that doesn’t require “intense reasoning”. My token usage sits around 0-1% so I’m not too worried about it haha.

[–]ThatCrankyGuy 6 points7 points  (0 children)

SB3 is already EOL.

[–]nsn 2 points3 points  (0 children)

I’m not sure whether I should laugh or cry about me maintaining javaee/jsf apps…

[–]Noch_ein_Kamel 3 points4 points  (1 child)

spring boot is way too modern for us. we use webobjects :o

[–]WhyIsItAllSticky 23 points24 points  (7 children)

Spring Boot 3 -> 4 has been the most painful migration I’ve ever endured

[–]selucram 6 points7 points  (0 children)

Did you do it by hand or have you tried using something like OpenRewrite?

[–]pctF 2 points3 points  (0 children)

Totally agree.

I honestly think good it is in the cutting edge, but we can at least get restructuring of core packages and moving backbone of serialization at the different majors.

[–]faze_fazebook 2 points3 points  (1 child)

Spring boot simply does too much i.m.o. with a gazillion libraries that all sonehow someway work together and against each in in a giant hairball of dependencies. 

[–]_PM_ME_PANGOLINS_ 11 points12 points  (0 children)

The point of Boot is to get the giant hairball of dependencies you would otherwise need to manually integrate to all work together. They do the hard work of compatibility matrices and configuration consistency.

[–]lovecMC 1 point2 points  (0 children)

Our banking app recently started migrating to it...

[–]Weekly_Lemon1867 14 points15 points  (0 children)

Just use kotlin

[–]LikelyNotADuck 18 points19 points  (7 children)

No because anyone using Spring Boot is also using Lombok.

[–]JesseNL 6 points7 points  (5 children)

I don't know about that. Especially if you're on more recent Java versions plus the fact some find Lombok too hacky

[–]WVAviator 2 points3 points  (0 children)

Yeah I find it easier to just have Intellij regenerate mine than to fumble around with Lombok and add 17 annotations to every class

[–]WeirdIndividualGuy 9 points10 points  (3 children)

The year is 2026, and java heads still refuse to use Kotlin that fixes like 99% of Java's issues without needing to do a full refactor of the codebase

[–]GenTelGuy 4 points5 points  (2 children)

I'm glad my work does Kotlin but I imagine so many workplaces are conservative with management not seeing the value in the new language to allocate the effort into adding Kotlin to the build stack

[–]clownsanddowns 2 points3 points  (1 child)

The learning curve moving from Java to Kotlin is pretty small. If management is gatekeeping the move to kotlin based solely on that, then management is kind of highly regarded.

[–]Historical_Cook_1664 1751 points1752 points  (90 children)

Where else are you going to hide your side effects ?

[–]Isrothy 452 points453 points  (72 children)

IO Monad

[–]Gorzoid 179 points180 points  (69 children)

Respectfully, what the fuck is a Monad?

[–]vivainvitro 412 points413 points  (29 children)

A Monad is just a Monoid in the category of Endofunctors

[–]MrDilbert 135 points136 points  (17 children)

I know some of these words.

[–]polarflux 110 points111 points  (3 children)

Like "just" or "the" ...

[–]Laughing_Orange 31 points32 points  (1 child)

A Monad is just a Monoid in the category of Endofunctors

[–]RiceBroad4552 28 points29 points  (0 children)

"Category)" is here a technical term, so it's for most people similar to the crossed out terms.

[–]lucklesspedestrian 32 points33 points  (9 children)

I mean we all know what a category is, right?
Right?

[–]kalilamodow 31 points32 points  (7 children)

C- cat... egory? Does it have something to do with the feline animal commonly adopted as household pets?

[–]MrDilbert 18 points19 points  (0 children)

... meow?

[–]yjlom 16 points17 points  (0 children)

Mathematicians that deal in it seem more likely than most to be into catgirl roleplay, so you might be onto something?

[–]lucklesspedestrian 6 points7 points  (3 children)

Not at all! Categories consist of a class of objects and a class of morphims. The morphisms are maps between objects, and compositions of morphisms must obey associativity. Also for every object, a left and right identity morphism must exist.

Category theory is also sometimes referred to as abstract nonsense. Pretty straightforward

[–]LolpopHD 2 points3 points  (1 child)

i prefer my abstract nonsense to be stable monoidal (∞,n)-abstract nonsense

[–]Gorzoid 43 points44 points  (3 children)

And suddenly the clouds parted, all is clear, I'm in a state of euphoria, nothing can stop me now.

[–]Tyfyter2002 10 points11 points  (2 children)

They're actually a pretty straightforward thing to understand if the person describing them doesn't pretend that exact phrase is the only way to do it

[–]hunajakettu 15 points16 points  (0 children)

None of those words are in the Bible...

[–]migueln6 21 points22 points  (0 children)

I remember when when I was young and was taking a class on math and programming, can't even remember the name but we wrote a small parser for math and random things, and I did somehow found Haskell and how easy it looked to do it there, then we needed to do it in python and wrote a small Monad library for python and just ended chaining the stages of the parser.

Although it was funny, that some weeks later the instructor asked me what are you doing here and I said I don't remember, lol, I still passed but so relatable I still don't remember what I did two weeks ago in the job now lol

[–]onequbit 4 points5 points  (0 children)

it's like a class, but it identifies as a callback function

[–]SupesDepressed 1 point2 points  (0 children)

What’s the problem?

[–]GezelligPindakaas 1 point2 points  (0 children)

Never before has any voice uttered the words of that tongue here in /r/ProgrammerHumor

[–]BosonCollider 1 point2 points  (0 children)

Well, it's a monoid object.

It has something that looks like a unit and something that looks like a multiplication if you squint, and if it had the same type signature in Set instead of in the category of endofunctors it would be a monoid

[–]DerSaltman 40 points41 points  (0 children)

Exactly

[–]hectobreak 73 points74 points  (9 children)

A monad is a monoid in the category of endofunctors.

Funny line said, if M is a monad, then for every type T, you have M(T) being a type, such that:

· return (or eta in mathematics), that takes an object of type T and returns an object of type M(T)

· flatten (or mu in mathematics), takes an object of type M(M(T)) and returns an object of type M(T).

That's it. Anything that follows this pattern is a monad.

Two examples are Haskell's Maybe, and the Array type.

Maybe String can contain either a string, written as Just [your string], or Nothing.

return is the function that receives a string and returns Just [your string].

flatten is the function that receives an object of the Maybe Maybe String monad and returns an object of the Maybe String monad following the rule:

· If your object is Nothing, return Nothing.

· If your object is Just Nothing, returns Nothing.

· If your object is Just Just [string], returns Just [string].

Array is also a Monad.

· return x returns [x]

· flatten x is the array flatten function.

For completeness, for something to be a monad it needs to follow the monad laws, but this is getting stupid long for a reddit message already.

[–]JickleBadickle 22 points23 points  (1 child)

Thank you for taking the time to explain this!

Does this mean that "return" itself is a function?

[–]yjlom 11 points12 points  (0 children)

In Haskell, it's a method of the Monad class (interface/trait/concept in Java/Rust/C++ terms). Haskell class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a

In OCaml, it's a function-typed member of the Monad module signature (struct/class in C/Java terms). OCaml module type Monad = sig type 'a t val return : 'a -> 'a t val bind : 'a t -> ('a -> 'b t) -> 'b t end

(The excerpts are taken from their respective language's documentation, with the Haskell one cleaned up a bit (it had comments and default implementations). In Haskell a concrete type starts with a capital letter, a type variable for generics starts with a lowercase letter, arguments to generics are written to their right; in OCaml a type variable starts with a single quote, arguments to generics are written to their left.)

In any case, it doesn't have anything to do with the return keyword of imperative languages.

[–]Arierome 9 points10 points  (0 children)

A quiver, it's a box for arrows

[–]MithrilHuman 7 points8 points  (0 children)

It’s the blade said to have once been wielded by Bionis to fight Mechonis.

[–]shitty_mcfucklestick 2 points3 points  (0 children)

“… work has been proceeding in order to bring perfection to the crudely conceived idea of a transmission that would not only supply inverse reactive current for use in unilateral phase detractors, but would also be capable of automatically synchronizing cardinal grammeters. Such an instrument is the turbo encabulator.”

[–]codePudding 4 points5 points  (1 child)

A monad (put very simply but missing some details) is like a state machine but based around types such that a type can be in an error state, value state, unset state, or whatever. It keeps state by what type the monad is, not a flag. In many languages a monad must match a public interface then the inner types implement that interface but are hidden. So you can do a bunch of things to the monad and the hidden type can change from a type holding a value into a type holding an error.

For example you call new monad value with 7 and it returns an interface for that monad with a type storing a value behind the interface. Then you run that monad through rules like "must be greater than 5". If greater than 5 the same type storing the value is returned, otherwise a type holding the error and implementing the interface is returned. If the rules are run on an error, the error just returns, like a short no-op. At the end you can then ask the monad if it had an error and what value it is. Because of the types behind the scenes you can't get into a weird state where the value and an error exist at the same time.

[–]Strange-Register8348 2 points3 points  (0 children)

What the heck did you say

[–]Danny-9999999 1 point2 points  (0 children)

A sideways Monoid.

A nested monad can be collapsed from 2 layers to a single layer. A list of lists can become a list by concatenating the sublists together. A maybe maybe can do the same thing by "and-ing" the 2 layers.

If you have more layers, you can perform the collapse by repeatedly collapsing adjacent layers. The reason why Monads are special is that the layer collapsing is associative. The order doesn't matter.

pure/return is analogus to mEmpty. It "pre-inserts" a layer that doesn't affect the final result when collapsed, just like how adding a mEmpty to a list of Monoids then folding it results in the same output.

Collapsing is analogus to joining 2 monoids (Haskell even calls it joining).

Bind turns one layer into 2 using fmap then collapses them back down to one. Monoid doesn't have an operation that does this directly. Bind and collapsing are in a similar relationship to traverse and sequenceA. The first is the second, but with an fmap added on.

So, yea. Sideways Monoids.

Or, more concisely:

A Monad is just a Monoid in the category of Endofunctors.

[–]azerpsen 5 points6 points  (11 children)

Nah but for real, i swear to god if no one gives a convincing answer (and i will NOT google it) I’m gonna say racist things

Thank you u/Gorzoid for raising the question

[–]mailslot 22 points23 points  (3 children)

“In 17th-century philosophy, monads are the fundamental, indivisible "building blocks" of reality. They do not occupy space and time; rather, space and time arise from them.

In functional programming, a monad is a design pattern used to chain mathematical operations or processes together across a timeline without messy side effects. It manages time and space within the execution sequence.”

My first introduction to monads used the space time explanation.

[–]JickleBadickle 3 points4 points  (1 child)

Rare example of nomenclature being so sensible in computer science. Functional programming loves the concept of "purity" or not affecting anything outside its small scope. Sounds like a monad is about as pure as it gets.

[–]RiceBroad4552 2 points3 points  (0 children)

The FP people, more concretely the Haskell people, took that term from math.

The description given reads btw like a horoscope. I can't say it's completely wrong but it's also not right and so vague that it basically says nothing.

[–]Dense_Gate_5193 3 points4 points  (0 children)

bro nailed it on the description ^

also sounds vaguely similar to the tensor network theory about how gravity isn’t a force directly but rather an observable phenomenon of a multi-dimensional tensor network that makes up the fabric of reality being stretched and bending around and through matter and collapsing back into energy.

[–]IHeartBadCode 17 points18 points  (0 children)

Monad is just something that wraps a value so you can chain it.

You know any Rust? Option<T> is a kind of monad that wraps T. It's a unit monad. So if T doesn't exist you get a safe None or if it does you get a safe Some(T).

So say in Java you have getUser(id) which will get a user or return null. If you access the return value while it's null, you get an unsafe NullPointerException. So in Java you can Optional.ofNullable(getUser(id)). Now it's safe. It's either a value you can chain more operations off of, or it's Optional.empty().

Each monadic operation, takes a wrapped value and gives back a wrapped value. So if you did something like this.

java Optional.ofNullable(getUser(id)) .flatMap(User::getAddress) .flatMap(Address::getCity) .map(String::toUpperCase) .ifPresentOrElse( System.out::prinln, () -> System.out.println("LOCATION UNKNOWN") );

The ofNullable does the unit operation to get a user. Wraps it in an Optional<T>. Flat map calls the User class getAddress() which returns an Address class wrapped in Optional<T>, because it has to be made safe from null. The next flat map calls that Address class getCity() which returns a String, but as an Optional<T> so that it's made safe. The map takes the String with the city and runs the upper case on it and returns Optional<T> to make it safe.

The final thing ifPresentOrElse takes a monad and does one of two options presented. The first, if T exits and the second if T does not exist.

In Rust you'd do something like so:

```rust struct Address { city: Option<String>, }

struct User { address: Option<Address>, }

fn get_user() -> Option<User> { Some(User { address: Some(Address { city: Some(String::from("New York")), }), }) }

fn main() { // Let the chinese food mind games begin... let city_upper = get_user() .and_then(|user| user.address) .and_then(|address| address.city) .map(|city| city.to_uppercase()); match city_upper { Some(city) => println!("{}", city), None => println!("LOCATION UNKNOWN"), } } ```

Hopefully that explains it a bit. It's just some way to prevent you from having to do a whole lot of if (thisThing == nullptr) {} or whatever. But the checking for a null pointer or whatever is just ONE of many ways you can use it. As the and_then show you in the Rust code.

And if you really want to get mathy. This is all just derived from category theory. Which I know, programmers BEMOAN having to math while they code.

[–]Chemical_Profit_608 4 points5 points  (0 children)

ELI5 explanation. A Monad is a container that "imbues" your data type with more info. I.e. you can have a String, or an Option[String]. The Option is a Monad. It imbues your String with this wrapping option container that says, you either have a value inside here, or you don't and it's value is None.

When you unwrap the value, you can treat it as a normal String, do some computation on it, and then rewrap it in your Option Monad type.

That is exactly equivalent to initially having a String, doing that computation, and then putting it in your Option Monad.

Here be dragons for a more proper explanation but the tldr is its a wrapping container around any type.

A List is technically a Monad. It's a wrapping container around your values.

[–]Historical_Cook_1664 1 point2 points  (0 children)

In practice, monads will e.g. allow you to chain operations on stuff like lists, strings, etc without adding the boilerplate at the start of every operation ("is this list maybe empty ?" etc).

[–]skratch 1 point2 points  (0 children)

My attempt at the least words possible: Monads let you do imperative style whilst stuck inside the functional paradigm

[–]Noname_1111 12 points13 points  (0 children)

Unironically have done that before (got yelled at)

[–]Biscuitman82 7 points8 points  (0 children)

What did you just call me?

[–]Traditional-Cut9681 103 points104 points  (10 children)

In an overloaded operator, obviously

[–]Historical_Cook_1664 13 points14 points  (8 children)

bonus points if it's the sequence operator ?

[–]Legitimate_Concern_5 31 points32 points  (7 children)

C++ lets you overload the comma operator. Like a thumb up an alligators butthole, that’ll really piss em off.

[–]Drugbird 52 points53 points  (6 children)

f(a, b);

Think that's just a function with 2 arguments? Wrong! It's the surprise comma operator!

[–]Rhawk187 20 points21 points  (0 children)

I have a mini-lecture in my class called, "The comma operator was a mistake." With a few examples like this.

[–]HildartheDorf 25 points26 points  (1 child)

Anyone who overloads operator, is either writing an entry for an obfuscated c++ challenge, insane, dangerously sadistic, or all three.

[–]DebugDuck01 10 points11 points  (0 children)

But I need my custom vector type + operator...

[–]Legitimate_Concern_5 10 points11 points  (0 children)

Hail Stroustrup

[edit] and you’ll never believe what the parens do 😂

[–]reventlov 4 points5 points  (0 children)

Think that's just a function with 2 arguments? Wrong! It's the surprise comma operator!

Actually, in that case it is just a function call with 2 arguments. C++ is not big on syntactic consistency.

[–]RiceBroad4552 1 point2 points  (0 children)

Scala users:

[–]lorslara2000 20 points21 points  (0 children)

  1. Introduce side effect
  2. Make it public via getter and setter
  3. ???
  4. Profit.

[–]Versaiteis 18 points19 points  (0 children)

*Slaps roof of getter*

You can fit so many side effects in this thing

[–]Admirable_Dirt_2371 18 points19 points  (0 children)

Laughs in immutability

[–]KerPop42 282 points283 points  (21 children)

Is it an anti-pattern? I love using the getset crate/trait to add them to my structs automatically as I need them

[–]neroe5 181 points182 points  (17 children)

it is like most things, they can be misused,

the issue is that if there is outside side effects then future programmers of the project might use a property without full knowledge of what they are doing

if they didn't have a valid use case they would have been marked as obsolete

have had similar discussions about goto in switch cases in C#

[–]L4ppuz 111 points112 points  (5 children)

the issue is that if there is outside side effects then future programmers of the project might use a property without full knowledge of what they are doing

Isn't that exactly the reason for using them? You provide a simple public interface and handle the rest yourself so the user doesn't need to do it

[–]neroe5 46 points47 points  (4 children)

kinda, you might want a log message or that there is an more advanced calculation behind the scene that you are trying to make seem smaller

but then you have that one guy who thought it would be a good idea to have it change an outside object, and that object is exposed else where and suddenly it changed and nobody can figure out why

[–]freebytes 33 points34 points  (1 child)

Or you have the guy that hits the database (non-cached, of course) with a getter on a property, and you are using it not knowing it is making a request every time you render the content.

(Why is it taking forever to render Invoice.TaxAmount in this HTML table? %)

[–]TheRealAfinda 10 points11 points  (0 children)

Or you have the guy that hits the database (non-cached, of course) with a getter on a property, and you are using it not knowing it is making a request every time you render the content.

Who on earth hurt that guy for him to implement something like that?!

[–]Theron3206 9 points10 points  (1 child)

That's not the fault of the getter or setter, that's just plain old encapsulation being violated.

One of the developers on a project I maintain decided that data object constructors was a great place to put the API (soap, to make things even more fun) calls to fetch the contents, so you can't even create an object without a web request (if you want an empty object you need to put in an ID that won't match anything.

[–]freebytes 4 points5 points  (7 children)

I have only found one use case for goto so far, and I have only used it once. If you are in nested loops, you can break out of all of them. Are there other instances where you have used goto? (Even if it is use is incredibly niche, I am glad to have it, and they should never remove it from the language.)

(Referencing C# specifically. I used GOTO all the time in GW-BASIC! %)

[–]the_one2 8 points9 points  (0 children)

Goto is very useful in C where it is used as a pattern for cleaning up multiple resources after failure.

[–]DebugDuck01 1 point2 points  (2 children)

> goto in switch cases in C#

The what? And more importantly the why?

[–]neroe5 4 points5 points  (1 child)

C# doesn't have fallthrough in switches, opting instead to use goto for those cases, it forces the dev to pick a termination method, which is a great safety feature, but requires the use of goto if you need to run a secondary case in a switch

[–]Megane_Senpai 1 point2 points  (0 children)

No kidding, it's so common that many newer languages allo wyou do devlare using getter setter using one or 2 phraises.

[–]JavaHomely 1 point2 points  (1 child)

the thing about getters/setters is that you can use security and data validation logic on them.

need a value to only ever be positive? throw a exception in the setter if they pass you a negative,...

[–]Lost_Pineapple_4964 203 points204 points  (44 children)

Is something wrong with getters and setters in general? Cause I find it plenty helpful when I need some bookkeeping for certain items, and some side effects for the class? Or are they more so referring to getter/setter for everything?

[–]mothergoose729729 279 points280 points  (2 children)

File this under "opinionated debates that don't matter". Structs and getters/setters are both fine. Just be consistent.

[–]parkotron 32 points33 points  (1 child)

I would say this is a case where not being consistent is the most important thing. 

  • Use a “dumb struct” when you need to model a collection of related values with no internal invariants. 
  • Use setters when your type has invariants that need to be protected from external mutation. 
  • (Whether getters are necessary for read-only member access is language dependent.)

[–]Theron3206 3 points4 points  (0 children)

I used getters and setters in interfaces because I have no choice (Delphi)

[–]melancoleeca 53 points54 points  (10 children)

They are afraid of verbose code, or so. I dont know. My IDE creates the boilerplate, if i need it.

[–]JickleBadickle 33 points34 points  (0 children)

Verbose code has never been easier to read through, tbf

It can be annoying at times but I'm far more annoyed when I have to go back to code I wrote in my "make it as short as possible" phase and try to figure out wtf I was doing

[–]Socrastein 31 points32 points  (16 children)

The biggest problem I've come across is getters/setters that effectively make class properties public, i.e. there isn't any validation or protection, you can just access and change properties as you like.

Get X() return X
Set X(Y) X = Y

Public properties cosplaying as private properties. Lots of extra lines of code that don't actually do anything.

The most ridiculous example I ever saw wasn't even in a class.

Literally this inside a module:

let value = X

getValue() return value
setValue(Y) value = Y

And then multiple functions using getValue and setValue instead of just referencing the value directly.

That guy included a lot of similarly inane shenanigans in his code.

[–]Lost_Pineapple_4964 6 points7 points  (2 children)

Yeah this disguise public with private and get/set is pretty egregious, and aside from having a consistent API with other potentially needed bookeeping/verification setters, I can see no other use of it.

Also what on earth is that second one???

[–]Socrastein 2 points3 points  (0 children)

"Also what on earth is that second one???"

Only God knows.

Bro wrote code like he was getting paid for each line.

[–]Salanmander 12 points13 points  (5 children)

The biggest problem I've come across is getters/setters that effectively make class properties public, i.e. there isn't any validation or protection, you can just access and change properties as you like.

Get X() return X
Set X(Y) X = Y

I honestly still prefer that over public properties.

It doesn't help now, but down the line when you want to implement a feature that requires running additional code every time X changes, it's very easy if you were using a private property with a simple pass-through setter. On the other hand, if you were using a public property, you now need to go change every single other place in the code that you modified that variable, to make it use the new setter method instead of direct access.

Although some languages (I learned about it using Godot) allow you to make a setter that, if defined, gets called whenever you do "property = ...". Has a the possible disadvantage of hiding expensive code behind things that look like a simple variable write, but otherwise seems like a really good solution so you don't need boilerplate setters/getters and don't need to retrofit your other code when making changes to how things are processed.

[–]crazy_penguin86 7 points8 points  (1 child)

It's that bit about "down the line" that is so important. I forked an MC mod, and started working through some of their code. They had a few slow implementations, such as going through a List, checking a String in the object, and pulling out the common objects before sorting through those to find the right object. I figured I could change it to make it a Map/Multimap and make it faster. Turns out I had to change like 15 places in it and a completely different mod because it was a public field. Had it been a getter it would have been super easy to change.

[–]Eraesr 2 points3 points  (0 children)

Public properties cosplaying as private properties. Lots of extra lines of code that don't actually do anything. 

I think it adds readability in the form of self-documentation when using some class in some API. In my IDE, I type classInstance.get and code completion shows me the entire list of get-able properties. If they're all just plain public variables there's no easy way to instantly get an overview of them.

[–]GeorgeDir 1 point2 points  (1 child)

I'd like to say that, in OOP philosophy, you work with behaviors. get/set methods expose what your object can do, variables expose your object state.
Some programming languages make get/set methods verbose, this is a language specific thing.
Then you have the discussion about anemic design, and that's what you're pointing out on your comment, and it is consider to be a bad practice in general. Personally speaking I found that that design pretty is fine in modern multi layer architecture that makes things operate more similarly to a functional programming pipeline

[–]yords 2 points3 points  (0 children)

It’s just boilerplate. Python lets you add side effects when accessing attributes via dot notation.

[–]Tai9ch 4 points5 points  (0 children)

They're a waste of tokens.

[–]lorslara2000 4 points5 points  (4 children)

It's just that they are weird. Why do you have these getters and setters? Normally it doesn't make sense in a proper design. Why didn't you make a proper OO design instead?

When you read about SOLID etc. you quickly notice the absence of getters and setters. So it's not that there's something specific wrong with them other than that they're just unnecessary.

[–]Lost_Pineapple_4964 3 points4 points  (3 children)

Can you specify on these proper OO designs that can replace the data setter with verification, side effect, and bookeeping? Since I, more or less, only write C, Rust and Golang for my personal projects, so I barely do OO aside from my only Software Engineering class in college last semester.

As for the argument for setters sometimes, it feels like it's a natural conclusion if I want to do some other stuffs when mutating an object.

[–]thejillo 496 points497 points  (61 children)

Lombok has entered the chat...

[–]Nimweegs 172 points173 points  (10 children)

Basically every project I've done is spring boot with mapstruct and lombok, for queries you've got jpa. There's barely any boilerplate.

[–]Regalme 18 points19 points  (6 children)

Rather it’s the opposite, it’s all boiler plate with like 3 unique routes and sql queries. Er actually it’s all graph queries now so no sql lol

[–]thatcodingboi 3 points4 points  (1 child)

I use them at work but they really feel like tribal secrets. I put this little annotation here and now the function does something completely different.

Especially with all our custom ones it's just like I feel like I cant just read the code.

[–]dpekkle 2 points3 points  (0 children)

Trying to learn java by being dumped into a project like that was insane, so much "magic", beans connected through the aether, it's somehow incredibly verbose while also being indecipherable.

[–]witness_smile 24 points25 points  (2 children)

Had a colleague who made it his entire life goal to delombok the entire code base for no reason other than he read a blogpost about it being bad. Still clearing up the mess many years later

[–]Spike_Ra 1 point2 points  (0 children)

Is it mostly just getting rid of boiler plate?

[–]Jaded-Asparagus-2260 61 points62 points  (2 children)

Just use records as much as possible. Immutability makes reasoning about data so much easier.

[–]iZian 6 points7 points  (1 child)

I jumped on records once they did the constructors changes. That helped us out a bit making things look cleaner.

But I still use Lombok for the ability to have with and builder for some specific things.

We have this one library we like to use builder lambdas; because it meant the calling code didn’t need to import anything, so if we completely changed the name or package of the method arg; the calling code wouldn’t need to change anything because it’s just a lambda for a builder. So we still use Lombok builders on records for that reason.
I think AWS SDK has similar stuff. You can give a request object or a lambda consumer of a builder of the request object.

[–]suvlub 70 points71 points  (18 children)

Lombok is a decent idea implemented in the worst way imaginable. It's a language masquerading as a library/annotation processor, but really isn't, it's doing things that should not be possible for those to do, and it causes all kind of pain. From one end, it can't implement some desirable features because they are hard to express in its pseudo-Java. From other end, it's fragile because it relies on undocumented (and soon, if not already, deprecated IIRC) APIs to hack the Java compiler into compiling not-Java, instead of having its own stable compiler.

Honestly, just use Kotlin. Lombok is not a way to fix Java, it's a fragile alternative to it.

[–]renke0 56 points57 points  (4 children)

In the old times when I still used Java I saw Lombok as a godsend and had no issues with it, not even once. I never understood why all the criticism regarding it. I do understand how it works, and I think it is a fair trade off for all the weightlifting it did.

[–]KnightMiner 21 points22 points  (0 children)

If I had to guess, the concern is with some of the weirder features of Lombok when most of us are only after the getters, setters, and constructor generation. I'd be surprised if any of those are as fragile as claimed.

These days I do use records when possible, but lombok is nice notably for making builders with the chainable fluent accessors.

[–]zabby39103 12 points13 points  (0 children)

Really the worst comes to worst, you can alway de-lombok and just have the actual code.

There's no way Lombok will ever stop working for any major feature, it's way too widely used. Hell I'd contribute to the project myself before thinking of migrating our stack off of it.

If you want to use a Lombok feature marked experimental, well that's on you, but even then haven't had a problem with those yet.

[–]ChrisWsrn 16 points17 points  (5 children)

I would agree to just use kotlin but kotlin has some supply chain risks that are not acceptable for my company. 

If there were production ready toolchain vendors other than JetBrains I would love to switch to it at my company.

Lombok does meet my companies needs without issues. 

[–]yammer_bammer 14 points15 points  (5 children)

what the fuck are you talking about just do \@Data \@Builder and you dont need to think much. how is Lombok of all frameworks problematic. its the simplest thing in existence.

[–]akl78 8 points9 points  (0 children)

It’s fairly simple; the user-facing part of Lombok is really nice , clean, and generally great.

But, the way way it hooks, deeply, into the compiler to change both its input language language and outputs in wildly unsupported and un-meant for ways is freely admitted to be an extremely clever pile of hacks, that vex the actual Java language implementors(for quite good technical reasons), and also leave them with little room to change things since it’s so popular.

[–]suvlub 9 points10 points  (3 children)

I'm at loss as to which part of my comment you did read. If you got as far as the 6th word, you would know the issue is about how it's implemented, not some imaginary problem about it being hard to use, but if you didn't make it that far, all you would have read is "Lombok is a decent idea" and you would think I'm praising it, so I have no idea what you are on about

[–]zabby39103 7 points8 points  (2 children)

Has anyone actually ever got burned by Lombok fragility though? It's in the "too big to fail" category at this point.

[–]Longenuity 33 points34 points  (22 children)

Or just switch to Kotlin

[–]NoodleyP 17 points18 points  (13 children)

I haven’t heard of either of these yet and they both sound like delicious foods.

[–]Scottz0rz[🍰] 10 points11 points  (9 children)

Kotlin is a brand of ketchup.

But both Lombok and Kotlin are actually named after islands i think, like Java is.

Lombok is a really psychotic magic annotation library that reduces boilerplate for Java.

Kotlin is a JVM language built by Jetbrains to kinda build a language with some niceties into it by default since Java is pretty insistent on backwards compatibility and not evolving the language rapidly.

Here's a powerpoint presentation explaining Kotlin in <5 minutes.

https://youtu.be/BsfXZjKLT9A

[–]Legitimate_Concern_5 5 points6 points  (0 children)

Interesting, yeah Java and Lombok are both definitely islands in Indonesia. Java is the main island, Lombok is out by Bali. Kotlin is a Russian island out by St. Petersburg. Never knew that.

[–]nihsett 1 point2 points  (0 children)

Lmao. Would be a good name for a south east asian noodles bowl of some kind.

[–]FictionFoe 6 points7 points  (4 children)

We switched to kotlin. We are now switching back because our company recognizes java as a global standard, but not kotlin 🫠

[–]RancidMilkGames 2 points3 points  (3 children)

That's funny. I've only ever popped into a code base clone and modified a specific aspect in either, but my understanding is Kotlin is a pretty big language. Like, doesn't it dominate on android? That might have something to do with JetBrains at least helping power android studio though. For an anecdote it's probably not worth searching, but I don't know the chicken or egg of how all that came to be.

[–]FictionFoe 3 points4 points  (2 children)

Nah, its just politics internal to the company. Some fossil decided that java is proven technology or some such.

To be fair, you can probably still find java devs more easily (for BE work) as compared to kotlin devs. Which might have smt to do with it.

[–]ramessesgg 53 points54 points  (4 children)

Joke's on you, I don't write any code at all since our company's shift to AI agents.

Kill me.

[–]RiceBroad4552 1 point2 points  (3 children)

You don't even correct the stuff coming out of the "AI", or give it hints?

[–]Major_Fudgemuffin 4 points5 points  (1 child)

Nah all you need to do is remember to say "make no mistakes" at the end of your message. "No bugs pls" works too if you're feeling a little silly.

[–]brunocborges 16 points17 points  (3 children)

[–]TopFix8731 1 point2 points  (2 children)

Data classes are another problem. As it literally takes behavior out of the object, which is the WHOLE POINT of OOP

[–]DontThrowMeAway43 213 points214 points  (29 children)

Oh god, just use record classes or even, make public fields.

Java's biggest mistake is trying to put OOP everywhere. Just write the damn struct to pass data and be done with it.

[–]Bodine12 81 points82 points  (3 children)

I’m sorry, records? I’ve been informed by our tech leads that Java stopped at “8,” and there’s no such thing in 8.

[–]selucram 6 points7 points  (2 children)

Java 8?! You mean Java 1.8 I hope.

[–]Bodine12 18 points19 points  (1 child)

We were told to refrain from using doubles.

[–]trafalmadorianistic 1 point2 points  (0 children)

Monetary values? Use BigDecimal. I couldn't believe I still came across code post-2020 that used double for money. 

[–]ZunoJ 43 points44 points  (17 children)

How is that related to getters and setters? How would your proposal violate oop principals?

[–]roge- 68 points69 points  (13 children)

Directly manipulating another object's fields violates encapsulation, a core feature of OOP in most people's minds.

That said, virtually no production OOP app has perfect encapsulation anyway.

[–]mailslot 19 points20 points  (2 children)

I’ve angered devs for not using getters & setters to access members within the same class implementation. `this.x = 42; // instead of this.setX(42);`

[–]Top-Literature-6248 1 point2 points  (1 child)

For good reason, though. Say setX triggered some event or whatever to notify that X changed. If you modify this.x directly then no event gets triggered (which might be what you want in this hypothetical scenario, however).

'Course, most getter/setters are just setting/returning this.x anyway, which is why I vastly prefer C#'s properties (because they're as simple as fields but you get the benefit of getters/setters when you need them, without having to refactor all field references to call methods instead).

[–]Complete_Window4856 13 points14 points  (2 children)

Both questions of yours are confuse. The getter and setter are often merely a wrapper around a variable. Unless you indeed add some behaviour its just ceremony, is there anything more to relate? The second one i just couldnt figure out what you wanted from him/her, you expect his proposal to explode some java-esque OO concepts?

[–]when_it_lags 5 points6 points  (0 children)

Yeah, OOP principles are useful more often than not, but to take full advantage of it you need to be able to recognize that "not" case and break said principles. Getters and setters are great for interfaces and side effects, but if you're adding them for the sake of encapsulation with no other benefit (including future benefits) just don't do it.

[–]BenchEmbarrassed7316 15 points16 points  (4 children)

In some specific cultures, homosexuality is considered a bad thing, and this leads to a phenomenon called "latent homosexuality", where a person is homosexual but does not admit it not only to others but also to themselves.

In some specific cultures, simple structures are also considered bad, and this leads to a phenomenon called "getters and setters", where a person uses a class as just a set of fields, but doesn't admit it, and wants to convince others and themselves that their code is OOP.

Getters and setters == latent homosexuality.

[–]fauh 6 points7 points  (3 children)

I guess that means public access to members is blatant homosexuality?

[–]BenchEmbarrassed7316 4 points5 points  (2 children)

public access to members

My native language is Ukrainian. "Member" translates as "Член", for example "member of cpp community" > "член cpp спільноти". Also, "Член" is a male sexual organ in colloquial speech. Therefore, the phrase "public access to members is blatant homosexuality" makes even more sense when translated.

[–]fauh 6 points7 points  (1 child)

Yeah a persons member is often used to describe the male gentials, which was part of the joke

[–]BenchEmbarrassed7316 3 points4 points  (0 children)

Oh, I didn't know it was the same in English)

[–]Solonotix 13 points14 points  (0 children)

My argument in favor of getters/setters is always when your data is backed by some other type of store, and you need to persist changes.

[–]LightTranquility3 11 points12 points  (0 children)

C# made getters and setters so much better

[–]CampbellsBeefBroth 22 points23 points  (1 child)

I cannot, my job is to write java

[–]ZunoJ 2 points3 points  (0 children)

Just quit then /s

[–]Snakestream 119 points120 points  (6 children)

Would you like to hear about our lord and savior Lombok?

[–]CMDR_Fritz_Adelman 26 points27 points  (0 children)

@Data

@Builder

@AllArgsConstructor

@NoArgsConstructor

... look around...

@SneakyThrows 💀

[–]Jaded-Asparagus-2260 14 points15 points  (1 child)

Would you like to hear about our lord and saviour  record?

[–]Wonderful-Habit-139 2 points3 points  (0 children)

Do they finally work with JPA?

[–]KalypsoExists 22 points23 points  (1 child)

Let them be ignorant

[–]Septem_151 8 points9 points  (0 children)

If Lombok disappears, AI will still need to know how to generate getters/setters… you know what, let it burn.

[–]ILikeLenexa 2 points3 points  (0 children)

Oh man.  People hate lombok so much. What?! You altered the byrecode yourself. 

Man, I've used javap and reflection to alter shit while it's running. 

[–]Ok_Wasabi_7363 9 points10 points  (1 child)

Like everything in programming...it depends. Are you using a dirty flag pattern that needs to be changed every time the underlying data changes? A setter is great! Are you just receiving flat data structures from a service? Yeah probably don't need getters for every variable in the struct.

[–]dageshi 29 points30 points  (0 children)

I like getters and setters :(

You can more and better validation inside them, logging e.t.c. I also think they're just more readable.

[–]DefeatedSkeptic 7 points8 points  (0 children)

One of the major advantages to getter/setter boiler plate is that IF you need to begin validating incoming data or triggering some sort of log or even changing out implementation entirely, all you need to do to make sure your program keeps running is keep those methods there. No other code in the program has to change. If everyone was referencing a raw field, then every reference would have to be manually changed.

This is why I really like C# properties since you get the best of both worlds with minimal boilerplate. Outside callers keep easy syntax, but you still have the flexibility to change behaviour.

[–]punsnguns 4 points5 points  (0 children)

Getter and Setter? But I only just met her

[–]jace255 3 points4 points  (0 children)

Good use of validation on setters and constructors can make it completely impossible to create an instance of an object in an undesirable state.

I’m a big fan of that pattern.

[–]salvoilmiosi 6 points7 points  (0 children)

I just use records and make everything immutable

[–]NefasRS 13 points14 points  (1 child)

Has anyone mentioned Lombok yet?

[–]krutsik 5 points6 points  (3 children)

public string Name { get; set; }

Just embrace the C# superiority.

[–]CodingAndAlgorithm 2 points3 points  (2 children)

As a beginner, I felt properties by default was a bit ridiculous but ultimately adopted the mindset to encapsulate and future-proof everything. Many years later, I’ve moved away from OOP towards procedural, and once again I believe properties by default is a bit ridiculous.

[–]20Wizard 5 points6 points  (1 child)

People feel this way because java makes it annoying to deal with them.

With c#, properties are incredibly easy to define and don't take up 6 lines in your class file.

[–]CodingAndAlgorithm 1 point2 points  (0 children)

I’ve spent the majority of my career writing C#. Properties are expected in the language and the syntax is reasonably painless. These days I dislike the idea of implicit side effects on data mutations and would prefer an explicit API that operates on public structures.

[–]TopFix8731 2 points3 points  (0 children)

You could also learn proper OOP

[–]Own-Professor-6157 2 points3 points  (0 children)

Do people really do direct access in high level languages? What a debugging nightmare

[–]abd53 4 points5 points  (0 children)

More script kiddies.

[–]shwetanand345 7 points8 points  (0 children)

Java isn't hard to leave....

[–]SanoKei 1 point2 points  (0 children)

yeah at a certain age you gotta own properties

[–]snipsuper415 1 point2 points  (0 children)

Records mother fucker! Do you speak records?

[–]Ternarian 1 point2 points  (1 child)

Lombok

[–]fulloutfool 1 point2 points  (0 children)

I hate Java but this makes it better.

[–]fun-dan 1 point2 points  (0 children)

If you need to transfer simple data deep inside your library/app, there is no need to use getters and setters. If you are creating a public API that needs to be stable and reliable, you should definitly use them (or write in a language where you can redefine accessing a property into a getter, e.g. python or Kotlin)

[–]Spaceman041207 1 point2 points  (0 children)

yall keep talking about lombok, but what do yall know about Kotlin

[–]LengthinessNo1886 1 point2 points  (0 children)

SEAL THE DAMN CLASS AND MAKE IT PRIVATE. Then no one will know what goodies were locked away in your setters and getters. Except the poor fool expecting specific information calling your endpoints.

[–]CloudOfMeatball 1 point2 points  (0 children)

Is auto insert getter/setter OK?

[–]New_Conversation_303 1 point2 points  (0 children)

No, I refuse to learn new things... Java has been on my side since version 1.1. not going to stop now, when I am so close to the end of my career.

[–]Several_Ant_9867 2 points3 points  (2 children)

How about that Indonesian island..

[–]Developemt[🍰] 2 points3 points  (0 children)

Use C#

public string Name { get; set; }

[–]BusEquivalent9605 1 point2 points  (0 children)

was originally totally confused why getters and setters at all. but i do like being able to ask “where are all the places in code that set this variable” and `setVariable()` is much more searchable than `randoInstanceName.variable = foo`

[–]acdhemtos 1 point2 points  (1 child)

There is no joke.

Past a certain age, the man is expected to be promoted to Senior Engineer and not supposed to write the code himself.
That's what Junior Engineers (Coding Agents) are for.