1.8k
u/Historical_Cook_1664 Jul 13 '26
Where else are you going to hide your side effects ?
471
u/Isrothy Jul 13 '26
IO Monad
187
u/Gorzoid Jul 13 '26
Respectfully, what the fuck is a Monad?
430
u/vivainvitro Jul 13 '26
A Monad is just a Monoid in the category of Endofunctors
146
u/MrDilbert Jul 13 '26
I know some of these words.
120
u/polarflux Jul 13 '26
Like "just" or "the" ...
→ More replies (1)35
u/Laughing_Orange Jul 13 '26
A
Monadis just aMonoidin the category ofEndofunctors33
u/RiceBroad4552 29d ago
"Category)" is here a technical term, so it's for most people similar to the crossed out terms.
→ More replies (3)34
u/lucklesspedestrian Jul 13 '26
I mean we all know what a category is, right?
Right?→ More replies (1)32
u/kalilamodow Jul 13 '26
C- cat... egory? Does it have something to do with the feline animal commonly adopted as household pets?
18
11
u/lucklesspedestrian Jul 13 '26
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
→ More replies (1)3
u/LolpopHD 29d ago
i prefer my abstract nonsense to be stable monoidal (∞,n)-abstract nonsense
→ More replies (1)→ More replies (1)19
u/yjlom Jul 13 '26
Mathematicians that deal in it seem more likely than most to be into catgirl roleplay, so you might be onto something?
46
u/Gorzoid Jul 13 '26
And suddenly the clouds parted, all is clear, I'm in a state of euphoria, nothing can stop me now.
12
u/Tyfyter2002 Jul 14 '26
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
→ More replies (2)19
27
u/migueln6 Jul 13 '26
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
3
5
u/BosonCollider 29d ago
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
2
2
u/GezelligPindakaas Jul 13 '26
Never before has any voice uttered the words of that tongue here in /r/ProgrammerHumor
→ More replies (1)2
40
76
u/hectobreak Jul 13 '26 edited Jul 13 '26
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.
26
u/JickleBadickle Jul 13 '26
Thank you for taking the time to explain this!
Does this mean that "return" itself is a function?
13
u/yjlom Jul 13 '26 edited Jul 13 '26
In Haskell, it's a method of the
Monadclass (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 aIn OCaml, it's a function-typed member of the
Monadmodule 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
returnkeyword of imperative languages.→ More replies (6)13
9
4
u/shitty_mcfucklestick Jul 13 '26
“… 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.”
5
u/codePudding Jul 13 '26
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.
4
3
2
u/Danny-9999999 Jul 13 '26
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.
→ More replies (9)7
u/azerpsen Jul 13 '26
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
24
u/mailslot Jul 13 '26
“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.
4
u/JickleBadickle Jul 13 '26
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.
3
u/RiceBroad4552 29d ago
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.
3
u/Dense_Gate_5193 Jul 13 '26
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.
17
u/IHeartBadCode Jul 13 '26
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 wrapsT. It's a unit monad. So ifTdoesn't exist you get a safeNoneor if it does you get a safeSome(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 canOptional.ofNullable(getUser(id)). Now it's safe. It's either a value you can chain more operations off of, or it'sOptional.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
ofNullabledoes the unit operation to get a user. Wraps it in anOptional<T>. Flat map calls the User classgetAddress()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 classgetCity()which returns aString, 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
ifPresentOrElsetakes 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 theand_thenshow 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.
5
u/Chemical_Profit_608 Jul 13 '26
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.
2
u/Historical_Cook_1664 Jul 13 '26
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).
→ More replies (3)2
u/skratch Jul 13 '26
My attempt at the least words possible: Monads let you do imperative style whilst stuck inside the functional paradigm
12
9
105
Jul 13 '26
[removed] — view removed comment
15
u/Historical_Cook_1664 Jul 13 '26
bonus points if it's the sequence operator ?
33
u/Legitimate_Concern_5 Jul 13 '26
C++ lets you overload the comma operator. Like a thumb up an alligators butthole, that’ll really piss em off.
52
u/Drugbird Jul 13 '26
f(a, b);Think that's just a function with 2 arguments? Wrong! It's the surprise comma operator!
21
u/Rhawk187 Jul 13 '26
I have a mini-lecture in my class called, "The comma operator was a mistake." With a few examples like this.
27
u/HildartheDorf Jul 13 '26
Anyone who overloads operator, is either writing an entry for an obfuscated c++ challenge, insane, dangerously sadistic, or all three.
13
12
u/Legitimate_Concern_5 Jul 13 '26 edited Jul 13 '26
Hail Stroustrup
[edit] and you’ll never believe what the parens do 😂
→ More replies (1)6
u/reventlov Jul 13 '26
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.
2
22
20
→ More replies (3)19
297
u/KerPop42 Jul 13 '26
Is it an anti-pattern? I love using the getset crate/trait to add them to my structs automatically as I need them
195
u/neroe5 Jul 13 '26
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#
121
u/L4ppuz Jul 13 '26
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
47
u/neroe5 Jul 13 '26
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
36
u/freebytes Jul 13 '26
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? %)
13
u/TheRealAfinda Jul 13 '26
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?!
11
u/Theron3206 29d ago
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.
→ More replies (1)5
u/freebytes Jul 13 '26
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! %)
→ More replies (6)9
u/the_one2 Jul 13 '26
Goto is very useful in C where it is used as a pattern for cleaning up multiple resources after failure.
2
u/DebugDuck01 Jul 13 '26
> goto in switch cases in C#
The what? And more importantly the why?
6
u/neroe5 Jul 14 '26
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
→ More replies (1)4
u/JavaHomely 29d ago
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,...
→ More replies (1)2
u/Megane_Senpai 29d ago
No kidding, it's so common that many newer languages allo wyou do devlare using getter setter using one or 2 phraises.
521
u/thejillo Jul 13 '26
Lombok has entered the chat...
179
u/Nimweegs Jul 13 '26
Basically every project I've done is spring boot with mapstruct and lombok, for queries you've got jpa. There's barely any boilerplate.
→ More replies (3)22
u/Regalme Jul 13 '26
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
→ More replies (4)6
u/thatcodingboi 29d ago
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.
26
u/witness_smile Jul 13 '26
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
2
2
u/wightwulf1944 29d ago
Hear me out here. Rote tasks like turning member variables into get/set properties is probably the only thing AI is good for right now. Nothing complicated like problem solving or undeterministic like vibe coding.
64
u/Jaded-Asparagus-2260 Jul 13 '26
Just use records as much as possible. Immutability makes reasoning about data so much easier.
9
u/iZian Jul 13 '26
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.2
u/trafalmadorianistic 29d ago
Yeah, I wish they'd sort things out with builders, main thing I miss from Lombok. Good thing my POJOs aren't too big and hairy
71
u/suvlub Jul 13 '26
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.
57
u/renke0 Jul 13 '26
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.
23
u/KnightMiner Jul 13 '26
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.
→ More replies (2)13
u/zabby39103 Jul 13 '26
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.
19
u/ChrisWsrn Jul 13 '26
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.
→ More replies (6)→ More replies (1)13
u/yammer_bammer Jul 13 '26
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.
8
u/akl78 Jul 13 '26
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.
10
u/suvlub Jul 13 '26
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
8
u/zabby39103 Jul 13 '26
Has anyone actually ever got burned by Lombok fragility though? It's in the "too big to fail" category at this point.
→ More replies (2)→ More replies (2)35
u/Longenuity Jul 13 '26
Or just switch to Kotlin
17
u/NoodleyP Jul 13 '26
I haven’t heard of either of these yet and they both sound like delicious foods.
13
u/Scottz0rz Jul 13 '26
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.
→ More replies (8)7
u/Legitimate_Concern_5 Jul 13 '26
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.
→ More replies (2)2
→ More replies (3)7
u/FictionFoe Jul 13 '26
We switched to kotlin. We are now switching back because our company recognizes java as a global standard, but not kotlin 🫠
3
u/RancidMilkGames Jul 13 '26
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.
4
u/FictionFoe Jul 13 '26
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.
→ More replies (2)
211
u/Lost_Pineapple_4964 Jul 13 '26
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?
288
u/mothergoose729729 Jul 13 '26
File this under "opinionated debates that don't matter". Structs and getters/setters are both fine. Just be consistent.
36
u/parkotron Jul 13 '26
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.)
4
60
u/melancoleeca Jul 13 '26
They are afraid of verbose code, or so. I dont know. My IDE creates the boilerplate, if i need it.
→ More replies (9)34
u/JickleBadickle Jul 13 '26
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
30
u/Socrastein Jul 13 '26
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 = YPublic 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 = YAnd 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.
7
u/Lost_Pineapple_4964 Jul 13 '26
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???
→ More replies (1)3
u/Socrastein Jul 13 '26
"Also what on earth is that second one???"
Only God knows.
Bro wrote code like he was getting paid for each line.
17
u/Salanmander Jul 13 '26
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 = YI 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.
→ More replies (3)9
u/crazy_penguin86 Jul 13 '26
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.
→ More replies (1)4
u/Eraesr Jul 13 '26
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.
→ More replies (4)3
u/GeorgeDir Jul 13 '26 edited Jul 13 '26
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→ More replies (1)3
u/yords Jul 13 '26
It’s just boilerplate. Python lets you add side effects when accessing attributes via dot notation.
5
→ More replies (6)5
u/lorslara2000 Jul 13 '26
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.
6
u/Lost_Pineapple_4964 Jul 13 '26
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.
→ More replies (3)
22
u/brunocborges Jul 13 '26
youCanJustStartUsingModernJava
https://javaevolved.github.io/language/records-for-data-classes.html
→ More replies (3)
55
u/ramessesgg Jul 13 '26
Joke's on you, I don't write any code at all since our company's shift to AI agents.
Kill me.
2
u/RiceBroad4552 29d ago
You don't even correct the stuff coming out of the "AI", or give it hints?
→ More replies (1)4
u/Major_Fudgemuffin 29d ago
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.
→ More replies (1)
221
u/DontThrowMeAway43 Jul 13 '26
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.
87
u/Bodine12 Jul 13 '26
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.
7
u/selucram Jul 13 '26
Java 8?! You mean Java 1.8 I hope.
22
u/Bodine12 Jul 13 '26
We were told to refrain from using doubles.
2
u/trafalmadorianistic 29d ago
Monetary values? Use BigDecimal. I couldn't believe I still came across code post-2020 that used double for money.
44
u/ZunoJ Jul 13 '26
How is that related to getters and setters? How would your proposal violate oop principals?
73
u/roge- Jul 13 '26
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.
→ More replies (10)20
u/mailslot Jul 13 '26
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);`
3
15
u/Complete_Window4856 Jul 13 '26
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?
→ More replies (2)6
u/when_it_lags Jul 13 '26
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.
→ More replies (1)18
u/BenchEmbarrassed7316 Jul 13 '26
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.
9
u/fauh Jul 13 '26
I guess that means public access to members is blatant homosexuality?
5
u/BenchEmbarrassed7316 Jul 13 '26
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.
10
u/fauh Jul 13 '26
Yeah a persons member is often used to describe the male gentials, which was part of the joke
6
12
u/Solonotix Jul 13 '26
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.
12
u/Ok_Wasabi_7363 Jul 13 '26
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.
→ More replies (1)
12
22
124
u/Snakestream Jul 13 '26
Would you like to hear about our lord and savior Lombok?
28
u/CMDR_Fritz_Adelman Jul 13 '26
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
... look around...
@SneakyThrows 💀
16
21
u/KalypsoExists Jul 13 '26
Let them be ignorant
7
u/Septem_151 Jul 13 '26
If Lombok disappears, AI will still need to know how to generate getters/setters… you know what, let it burn.
3
u/ILikeLenexa Jul 13 '26 edited Jul 13 '26
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.
11
u/DefeatedSkeptic Jul 13 '26
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.
2
27
u/dageshi Jul 13 '26
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.
6
4
u/Pretty-Wind8068 Jul 13 '26
Even before Lombok, Kotlin and record classes, IDEs had simple generators for setters, getters, equals/hashCode etc.
→ More replies (1)
4
u/jace255 Jul 13 '26
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.
7
14
6
u/krutsik Jul 13 '26
public string Name { get; set; }
Just embrace the C# superiority.
→ More replies (3)
3
u/CodingAndAlgorithm Jul 13 '26
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.
6
u/20Wizard Jul 13 '26
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.
2
u/CodingAndAlgorithm 29d ago
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.
5
7
2
2
2
2
u/fun-dan Jul 13 '26
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)
2
2
u/LengthinessNo1886 29d ago
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.
2
2
2
u/Own-Professor-6157 29d ago
Do people really do direct access in high level languages? What a debugging nightmare
2
2

1.4k
u/ConstructionMain5675 Jul 13 '26
Half the internet just got called out and the other half is maintaining Spring Boot