Top five items that bugs me in Kotlin

It’s the 21st century. Why are we still using QWERTY keyboards? We should be able to write mathematical expressions using a stylus just as if we were writing on paper, using subscripts, superscripts and other symbology. The computer, with the right software, should be able to translate that into code.

3 Likes

In this case, c = sqrt(a*a + b*b) is much more efficient and also easy to read. But in the general case, I agree that operators for pow and for binary operations would be better than infix functions.

Computer can already do things like this, it’s not a hard problem. The main problem is that you want to be able to read and modify code and generated/translated code tends to look much uglier than hand-written code. And if you require people to learn both the “paper-language” and the language than is the result of the translation process, you’ve only made things more complicated.

For math people like me a^2 + b^2 is more readable.

No one can imagine Pythagoras’s theorem written as c * c = a * a + b * b. It’s weird.

As for efficiency, it depends on the compiler optimizer of programming language. If 2 is stored in a variable it’s impossible. Otherwise it’s easy

For me, the destructuring matter (a) is more serious.

What I meant was that the hand-written math could be translated into the low-level bytecode or machine instructions. The source code that people work with could remain in the hand-written form, perhaps “cleaned up” by the IDE.

Is this something that could feasibly be implemented as an Android Studio or IntelliJ IDEA plugin?

1 Like

That would be very difficult to work with. You don’t really want to work with painting tools on code (to erase things for example) and interpretation of the drawing would likely be unstable and change between versions of the glorified OCR tool aka programming language.

Also diffs, version control and debugging would be very hard to get working properly.

If you want to try a sort-of graphical programming language, I suggest downloading MPS: https://www.jetbrains.com/mps/, it’s not on the level of using pen input, but you can insert tables, vectors and stuff directly into code (into standard Java code if you like) and you will quickly see the drawbacks of not being able to edit and copy-paste text freely. It feels more like using the Word Equation Editor and less like programming.

That’s 20th-century thinking. Those issues should be solvable. It’s only a SMOP. :wink:

Regarding integer division, I like what they did in Dart with a separate operator for integer division:

1 / 2 == 0.5
1 ~/ 2 == 0
2 Likes

Yes, some languages do it. It’s a good decision. Other alternative is use \ operator as integer division. unfortunately there is a problem with legacy code.

Top item that bugs me in Kotlin is that inst vars by default are public.

2 Likes

Top items that bug me are:

  • The negation operator should have higher precedence than the .-operator. -4.plus(3) should be -1, not -7.
  • Field types should be separated from public getter/setter/property types
  • Interface delegation is dangerous regarding equals/hashCode/toString and both dangerous and difficult to understand regarding adding new (default) methods to the delegated interfaces (including @JvmDefault logic).
  • I really don’t like top-level declarations and how they can be spread over random files inside a package.
  • companion objects sound nice on paper, but in practice I feel they are just overhead and added complexity compared to static methods (for containing factory methods and so on). I’ve pretty much never felt the need to pass a companion object around as a variable or make it implement an interface and if I need that, I can just create a standard (non-companion) object.
  • also the current design makes it impossible to add extension methods directly to types which don’t have an companion object, which isn’t very intuitive or practical.
1 Like

Mostly agree. I personally like the way top level declarations work right now. It might be a bit harder to use them without an IDE but that’s not really a problem I have.

I don’t understand that part. Do you want some way to declare a field separate from it’s getter/setter (java style) or what do you mean?

Essentially yes. A common example would be having a MutableList internally but you want to to give external users only read access. Or it can easily happen that you publicly expose some internal type by writing an initializer without explicit type.

In Java you can easily declare the field with a different type and visibility than the getter, the workarounds for something like that in Kotlin are relatively ugly. Also the logic when a Kotlin property generates a backing field and when not isn’t obvious at first glance, I’d prefer that stuff to be more explicit and less, I don’t know the right word, maybe magical.

1 Like

I don’t agree, I think it’s quite simple to understand.
That said I agree that there should be a better way to use a mutable class internally and make the public getter return the readonly interface, there is a KEEP for this.

Regarding (b), have you tried extension methods? I think that a.pow(b) is very expressive, and plays nicely with converting sqrt(a^2 + b^2) to sqrt(a.pow(2) + b.pow(2)). In mathematical notation, the exponent is superscripted, and I think putting it within () for a traditional IDE is the next-best thing.

2 Likes

I agree that it’s simple to understand, but if you want to for example estimate memory footprint of an object, in Java that is very easy, you just look at the fields and their types while in Kotlin you have to take a deep look at each property, especially if you also use delegates, by lazy{}, custom setters with validation and so on.

I also just like the indirection in Java between internal representation and public interface. It’s a little more boilerplate, but using properties in Kotlin always feels like connecting stuff with live wires instead of using plugs and sockets.

I agree with this point. This annoys me too. I still love Kotlin properties though.

1 Like

1/2 = 0
Java also returns int. So, this one should not be changed even though it’s strange to you because Kotlin is interoperable to Java and it’s one of Kotlin’s great selling point. If the behaviour changes, it’s gonna be big impact. So, I think it would be nice to have another operator for that instead of changing the existing one.

1 Like

While you may not see the benefit of it, it has great benefit. The trouble is that people that haven’t experienced those benefits don’t get how it is beneficial. This is imprecise, but how would you like the ability to “inherit” static fields and methods. It is sort of like a static mixin. That is essentially what allowing companion objects to inherit from other classes allows for.

The simple example is this logging library. For logging you want a logger variable for each class that points to the logger for that class. All I have to do to get that is add this:

companion object : KLogging()

The companion object instance inherits the logger variable from KLogging class without me having to declare it.

If the only purpose of companion objects were to support the limited use cases of java static then I would agree that it is not worth it, but it opens up a lot more possibilities.

3 Likes

This sounds like a very bad idea as I don’t see a is-a relationship here and in case you need multiple mixins you don’t have multiple inheritance. Also in that case the KLogging instance becomes part of the public signature, which doesn’t make sense.

It’s usually recommended to prefer delegation instead of inheritance and a logger is something I’d always declare as a static field in Java (and maybe as a private property of the companion object in Kotlin for a lack of a better place).

Actually, it may very well be possible to use an interface with default implementation to access a logger object. This method is still attached to the companion so the source can be identified.