Any reason to not keep the good old for loop format?

Likely because they have far more important things to do.

1 Like

It’s quite rude to do such comments on a public forum if you don’t care about community opinion on the topic, because it obviously will get response, it’s not a direct feedback form to Kotlin Team
Such comments discourage any conversations make feel bad everyone who already participated

3 Likes

I already stated the advantages of adding the for loop very clear, but it seems many people just like focusing on what is bad about using a for loop, which is pretty much irrelevant to the topic. Why bother keep explaining the same idea over and over again? The potential cons of adding it that I can think of are make the language more bulky, which I doubt a simple for loop will have impact on that. The other reason is maybe it cost so much development time to implement it. Which I also don’t think it is the case since for loop have been around for so long across so many languages. The resource of implementing a for loop should be manageable.
At the end of the day, only the devs can tell exactly why they choose not to implement that at the beginning and only the devs can make the changes.

like focusing on what is bad about using a for loop, which is pretty much irrelevant to the topic

It’s very-very much relevant. It’s against Kotlin evolution process, adding anything to the language without enough good use cases to add it. It’s not unique for this request

They chose to not implement it because it is a cryptic and error-prone construct and goes against Kotlin idea to avoid mutability everywhere where it’s possible.
Also, assignment in Kotlin is not expression, unlike in C, Java, exactly because of this - it’s error-prone

4 Likes

Can you provide the source for this statement?

I don’t see how adding for loop will be a problem. A for loop written correctly will not cause any error, and many programmers have been trained for years to do that. Programmer that are comfortable with for\in will still use for\in, what’s the deal?

Adding any feature is a problem

Can you provide the source for this statement?

I don’t have the source, it’s just my opinion based on knowledge of other design decisions in Kotlin

I don’t see how adding for loop will be a problem

Adding anything to the language is a problem, especially a new control flow statement, especially when nobody really wants to add it and the only argument for this is that it exists in other languages

3 Likes

Who are “they” then?

Seriously? you think a 100ish views post is the entity of the kotlin programmer? How about all other programmers that use for loop across all other languages? Are those nobody too? You are making some crazy assumption, chill out.

“they” are Kotlin language designers, as I understand their intent, maybe remember some related discussions.

Seriously? you think a 100ish views post is the entity of the kotlin programmer

My assumption based not on this feed, but on the fact that I use Kotlin for more than 6 years and am very active in Kotlin Slack and actively monitor this forum and official issue tracker and I have seen multiple requests for adding binary operators, multy-try-catch and even ternary operator adding requests, but I remember exactly 0 requests about adding a classif for loop

If you concider you topic as feature request, it’s better to create issue on KT issue tracker and collect some feedback. This forum thread after all says “Any reason to not keep the good old for loop format” on which you got multiple answers

2 Likes

Frankly, I understand you being upset and that you don’t like the direction where this discussion went. You wanted a simple answer from the Kotlin team and instead you got a bunch of developers who convince you that you are wrong :slight_smile: I agree with you that the further discussion without anyone from the Kotlin team is kind of pointless.

But… taking the above conversation into consideration, seeing there is a lot of criticism in the community, seeing that other languages also don’t include classic for, do you really believe you would get a different answer from the Kotlin team? They don’t have that much time, so you would probably get simple answer like: “We decided to not include it, because it doesn’t fit Kotlin well” or “It is error-prone and we believe Kotlin provides better alternatives” and that’s it. Good thing about discussing this in the community is that you can get very detailed answers, you get something more than “Because it is bad”. You can either appreciate this and try to take something for yourself from the discussion or you can just got upset that someone doesn’t want to fulfill your request :slight_smile:

2 Likes

Quite close:

KT-1447

5 Likes

probably it’s just me, but i don’t use for loops in kotlin AT ALL :slight_smile:
i prefer chained-like data streams. in android and backend development.

2 Likes

For reference, I would highly recommend one of the many videos by Venkat Subramaniam, such as this one: https://youtu.be/pFbDZQ9M76Y which will better explain the terms I use here.

The C-style for loop is an example of imperative programming. Imperative programming is where you have say what you want to do AND how you want to do it. That is contrasted with declarative programming where you say what you want to do without saying how to do it. Kotlin favors declarative (and more specifically functional) over imperative because it leads to more readable, less error prone code. Kotlin doesn’t force you but it isn’t going to try to make imperative code easier to write when it has excellent declarative alternatives.

The old for loop also encourages mutability while Kotlin and good programming practice says to favor immutability.

The old for loop is also an example of an external iterator where you as the programmer control iteration. It is much better to use internal iteration. An example of internal iteration is the foreach method where it controls the iteration.

External vs internal iteration I think is why most people don’t miss the old for loop. We simply don’t use external iterators very often. I searched in our apps code base and only find 5 cases of using a for (4 of which were on tests).

So the question is not really between for(int i = 1; i < array.size; i++) and for(i in array.indices) but instead with array.foreach

So the only justification you have provided is compatibility and familiarity, but don’t really break those down to explain why those are advantageous.

There are many examples in the evolution of languages where something that may have been familiar is excluded because there are better alternatives and the fact that people were familiar with the old way mastered little. Someone gave the example of goto being replaced by structured programming. There is also raw pointers and pointer arithmetic going away. This is another example of replacing imperative, external iteration with more declarative, functional alternatives

Why is compatibility important? The only thing I can come up with is easier to port code by hand. In the case of Java there are automated conversation tools. I do not find this a compelling reason to add the old for loop any more than I would find an argument to keep Java style switch alongside when.

So what is familiarity? Familiarity definitely does not imply more readable because the alternatives are all easier to read, less error-prone, and easier to reason about. If you disagree the burden is on you to provide counter examples.

Familiarity may make writing a little faster at the beginning, but that is short lived.

So I see no compelling reason that for should be added.

3 Likes

@deviant @dalewking
You both just mentioned replacing for entirely with forEach() and similar functions. I generally feel the same as you. I consider forEach() to be more flexible and with it I have one syntax to rule them all, instead of switching depending on the case.

However, I’m pretty sure I read somewhere, either in the documentation or a comment by someone from Kotlin team, that we are not supposed to just replace fors with forEach(). I don’t know what was the reasoning. One possible drawback is performance, as at least for now forEach() is not optimized into a for with counter - it creates an iterator which adds overhead. But it doesn’t seem like something that can’t be optimized, so I guess the reason was more “conceptual”.

1 Like

I have observed, albeit on a debug run without using a minifier or any code optimization tools, that forEach does indeed create iterators. However, the solution for that is trivial:

inline fun <T> List<T>.forEach(block: (T) -> Unit) {
  for(element in this) block(element)
}

Simply redefining forEach for List eliminates the iterator. However, I suspect that this isn’t included in the stdlib already because, surprise surprise, using iterators is a very common Java pattern and so code minifiers and optimizers know how to deal with it already.

Oh and also, forEach doesn’t have the same guarantees on a language-level that for has. For instance, a class that doesn’t inherit from Iterable but provides its own operator fun iterator() won’t have a forEach automatically, and therefore they’d have to define it themselves.

1 Like

You’re claiming let’s break our FP oriented and immutability oriented language design principle of Kotlin. Compatibility and familiarity is also considerable part but never as important as main principles of language. Your suggestion actually hurts Kotlin’s main principle.

The most powerful strength of a certain programming language come out from its regulations in its language design but not from adding features.

  • Keep off using goto (C/C++; lang allows but many programmers pay attention to use)
  • No pointer (Java/C#/Python/…)
  • Reference borrowing (Rust)

Those regulations all restrict developer’s ‘free’ and ‘familiar’ coding style. And therefore they get their power in industry.

I recommend you to leap ‘the wall’ if you want utilize full power of new modern language. It is much time saving even if Kotlin team decide to add old for-loop for you.

And also, there is the other kind option, to stay at your familiar good old language. If you don’t want learn more, nor have time to learn and apply, staying is practical and reasonable way.

Well, overhead of iterators is complicated to measure.

Can the old-style for loop replace the new-style for loop? It can’t, there’s no way to iterate over non-indexable collections (e.g. Set, HashMap).

Is the old-style for loop faster than the new-style for loop? No, it’s abysmally slow if you ever use it on a LinkedList, and there will be no warning anywhere.

Sure you often pay the price for a single allocated object that stores a simple counter, which is most likely inlined due to escape analysis, but until that’s measured, the new for loop is just faster, faster to type, works in more cases, and eliminates off-by-one errors.

Nobody here discussed iterating over LinkedList using a classic for. We discussed cases like: for (item in 0..9) or for (index in array.indices). These cases are currently optimized by Kotlin compiler to not use iterators. I don’t know what is (and if) the performance hit, but I guess Kotlin team would not implement such optimization if there would be no benefits.

My point is that using the old-style for loop is a bad habit even in Java. At any point the List implementation or whatever other objects you’re using might have a very slow implementation of get, because it must implement it even if there is no good way to do so. LinkedList is a good example, but there are many others. There are no performance surprises to using iterators.

Because Java actually uses iterator when we use for each syntax in Java, I don’t get it well that we can optimize it.

1 Like

I agree with you, but once again, I have no idea what LinkedList has to do with what I said. These optimizations are not for lists, but for integer ranges.