DEV Community

Discussion on: Why you should NOT HATE Java!

Collapse
devdufutur profile image
Rudy Nappée

Why ?

Thread Thread
siy profile image
Sergiy Yevtushenko
  • Kotlin requires extra efforts to keep codebase clean and organized: freedom in placing classes/functions across files tend to quickly turn codebase into blob of cold spaghetty. This is solved by defining and maintaining conventions - extra efforts mentioned above.
  • Extension methods blur class API and tend to spread across code base. As a consequence devs often repeat extension methods with very similar of identical functionality. This is also solved by defining and maintaining conventions - more extra efforts.
  • Kotlin requires keeping in mind much more implicit context while writing and reading the code - context-specific keywords, default variable names, etc. This impacts productivity in long living projects, especially when team changes.

There are more reasons, but even those listed above is enough to try to avoid Kotlin for enterprises.

Thread Thread
devdufutur profile image
Rudy Nappée

Indeed great powers implies great responsibility... DSL and extension methods are valuable tools but should be used sparingly.

In Java because there is no extension methods and we can't define a function outside class, we must define a lot of util classes (*Util, plural classname) with their static import, I'm not sure it's better :/

IMO Kotlin offers interesting patterns to compensate some lacks in Java. But teams are free to define coding standard to avoid exotic code.

Thread Thread
siy profile image
Sergiy Yevtushenko • Edited on

I'd rather say that all these are signs of poorly though out and inconsistent language. One laughable example is that code written with infix methods often can be made non-compilable by adding one more line feed.
Another (significant) disadvantage is that Kotlin encourages developer to write hacky, hard to read and understand code. Optional chaining and elvis operator are especially easy to abuse.

Thread Thread
devdufutur profile image
Rudy Nappée

I'm not sure

user?.address?.streetName ?: "No street"

is weirder than

Optional.ofNullable(user).map(User::getAddress).map(Address::getStreetName).orElse("No street")

But I'm sure it's shorter :)

About infix notation, I'm not a big fan in everyday code but it can be handy for DSL. Again, great powers...

Thread Thread
siy profile image
Sergiy Yevtushenko

Your code is shorted for two reasons:

  • It assumes that user has type String, although for fair comparison it should have type Optional<String>
  • You just stepping through object properties (BTW, your code might be a code smell, because it knows too much about User internals). If you try to actually compose operations, your code will not look so short.

You may try to rewrite code below with optional chaining:

public UserProfileResponse userProfileRequestHandler(User.Id userId) {
    User user = userService.findById(userId);
    if (user == null) {
        return UserProfileResponse.error(USER_NOT_FOUND);
    }

    UserProfileDetails details = userProfileService.findById(userId);

    if (details == null) {
        return UserProfileResponse.of(user, UserProfileDetails.defaultDetails());
    }

    return UserProfileResponse.of(user, details);
}
Enter fullscreen mode Exit fullscreen mode

For comparison, monadic version of this code looks so:

public UserProfileResponse userProfileRequestHandler(User.Id userId) {
        return userService.findById(userId)
            .map(user -> UserProfileResponse.of(user, userProfileService.findById(userId)
                .orElseGet(UserProfileDetails::defaultDetails)))
            .orElseGet(() -> UserProfileResponse.error(USER_NOT_FOUND));
    }
Enter fullscreen mode Exit fullscreen mode
Thread Thread
devdufutur profile image
Rudy Nappée

Just assumed User/Address were kt data classes / java POJO but Indeed callee could've been returned a Optional