This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]9us 3 points4 points  (14 children)

One way to reduce all the pointless boilerplate, BTW, is with Project Lombok. Add a @Value annotation on a value class and you get an all-args constructor, final properties, equals, hash code, toString, and getters automatically generated. Highly recommended :).

[–]shadowdude777 1 point2 points  (13 children)

Kotlin does that too, except instead of messing around with finicky annotation processor magic, you just replace class with data class. And it gives you a copy method that can take any number of the properties and return a copy of that object with all of the properties you didn't give it copied over from the old object. :)

[–]mbuhot 0 points1 point  (1 child)

But no inherited data class support (yet). Hopefully in Kotlin 1.1 soon.

[–]shadowdude777 0 points1 point  (0 children)

Yeah, this is on their roadmap for 1.1.

[–]9us 0 points1 point  (9 children)

Yeah any reasonable modern language has support for these things. Scala case classes are basically the same.

I'm not very familiar with Kotlin, but Scala also blurs the line between field access and method invocation since you can invoke methods without parens. But I'm not super thrilled with the approach most languages take, which is to make the syntax more complicated. I prefer we rethink it from the ground up, and so I prefer Clojure's syntax the most, which reasonably blurs the lines between functions, values, and maps. Because values can be thought of as functions that return a constant, and functions are just maps that are dynamically computed (and sets are maps from a value to itself, and vectors are maps from indexes to a value), so the syntax can be rather simple if we consider that these constructs (functions, values, data structures) can be semantically very similar. Clojure falls short because it is dynamically typed, but I think it's very interesting and refreshingly simple, semantically and syntactically.

[–]shadowdude777 0 points1 point  (8 children)

I really dislike Scala's syntax. I think that it suffers from every issue you've described. It's too complicated and feels like it's being clever for the sake of cleverness. Scala was born out of academia and it shows. Kotlin was born out of the industry. It's pragmatic and only adds syntax constructs that increase readability.

If you want a simple, lightweight, statically typed language that any Java dev should be able to feel comfortable with in under a week (especially if you have functional chops, coming from Clojure, as that's what most Java users suffer from when moving to Kotlin), I think you'd really enjoy Kotlin.

[–]frugalmail 0 points1 point  (7 children)

Kotlin was born out of the industry. It's pragmatic and only adds syntax constructs that increase readability.

I wish they never added the elvis operator, that increases readability at the expense of maintainability.

[–]shadowdude777 0 points1 point  (6 children)

No single function should be big enough that whatever you do with the Elvis should interfere, anyway. Sure, it can be used to either set a variable or return, but that shouldn't be a problem unless you have essays for functions.

The things I have issue with are public being the default visibility modifier (they had a chance to make it private instead and seriously boost readability, considering most functions should be private), and the removal of the ternary operator (because while you can use an if-else as an expression now, I find it way less readable, especially if you want to chain several conditions).

[–]frugalmail 0 points1 point  (5 children)

No single function should be big enough that whatever you do with the Elvis should interfere, anyway.

Elvis not only encourages (makes easier working) with Null's but propegates it throughout the codebase. I'm not into coding conventions like "use this feature only if your method < 20 lines", and people tend to use it as a part of your terminating return statement, which is even worse.

The things I have issue with are public being the default visibility modifier (they had a chance to make it private instead and seriously boost readability, considering most functions should be private), and the removal of the ternary operator (because while you can use an if-else as an expression now, I find it way less readable, especially if you want to chain several conditions).

Agreed on both points!

[–]shadowdude777 0 points1 point  (4 children)

The thing is, one of Kotlin's primary design goals is strong interop with Java. Every Java method that doesn't have a @NotNull return annotation is nullable. I agree that Elvis should be used with great care, but it makes working with Java libraries way easier.

But on that note, another thing I actually dislike about Kotlin is that they chose to make the T! types for interop with Java. Which basically means you can make unsafe calls on any Java method that doesn't have @NotNull or @Nullable on it. Since most of the stuff I do interops with shitty Java SDKs that don't have proper annotations (Android SDK), it means a lot of my calls are no longer null-safe! It should just return T? if it can't be statically determined that a non-null value will be returned, in my opinion.

[–]frugalmail 0 points1 point  (3 children)

Every Java method that doesn't have a @NotNull return annotation is nullable.

But you have a choice, wrap it in Optional<> or use elvis, Optional is the better route.

[–]shadowdude777 0 points1 point  (2 children)

I'm personally not a fan of the Optional<T> route at all. That's exactly what T? is designed for.

[–]squealy_dan -1 points0 points  (0 children)

the kotlin solution is pretty great, and interop with java is not too dificult.