HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

key => value iteration syntax #37

Closed nadako closed 6 years ago

nadako commented 6 years ago

Continuation of https://github.com/HaxeFoundation/haxe/issues/2421:

for (key => value in map) {
    trace(key, value);
}

for (index => value in array) {
    trace(key, value);
}

Rendered version

jdonaldson commented 6 years ago

Hate to mix proposals, but this ends up being related to tuples as well.

nadako commented 6 years ago

Hate to mix proposals, but this ends up being related to tuples as well.

I think it's only related in that we could use a tuple instead of the proposed {key:K, value:V} type. I mentioned that we might want to provide an optimized read-only KeyValuePair implementation instead. I think we could do that for now and if/when we get tuples - we can make it into an abstract over a 2-tuple.

RealyUniqueName commented 6 years ago

I'd like this proposal to go further:

  1. Add setting for generators to pass for(key => value in collection) to generator without transformation. That will allow effective target-specific implementation. E.g. being able to generate for(key => value as foreach on PHP will make iterating over collections and map/filter operations 2-5 times faster.
  2. Add syntax for iteratitrng over indexes/keys without fetching values.
nadako commented 6 years ago

Add setting for generators to pass for(key => value in collection) to generator without transformation. That will allow effective target-specific implementation.

This is going to be that TFor discussion @Simn wanted to have for a long time now. Yes, we could rework it to support key => value iterations as well, though I'm not exactly sure how right now.

Add syntax for iteratitrng over indexes/keys without fetching values.

Well that would be a normal iterator returned by some .keys() method, like in current Map.

back2dos commented 6 years ago

Maybe this is the right time to also consider loops with arbitrary steps and destructuring loops. The former is something that newbies often ask for and the latter might cover Justin's tuple use case.

markknol commented 6 years ago

I always use a custom iterator to loop forward or backward or in steps or with arbitrary start/end positions. https://try.haxe.org/#27c1e However this works good enough for me, I'd love to have more native Haxe support or some good iterators in std.

jdonaldson commented 6 years ago

Destructuring as @back2dos defines it is super nice. Although what I have in mind is actually distinct, and both approaches could work together!

I don't want to derail discussion on this specific feature in this thread, so here's a separate proposal that goes into more detail for the stack-based approach. https://github.com/HaxeFoundation/haxe-evolution/pull/38

tienery commented 6 years ago

Is it possible to not over-complicate the syntax of Haxe such that it becomes a new C++? Everyone complained about C++'s evolution of features and how that is grown into a language to be more complicated than it should. I don't want the same thing happening to Haxe when it hasn't even matured yet, you're just going to turn off investors.

If you think this isn't constructive criticism of the feature request, may I propose the following:

If we are to make key-to-value pairs, I think making it more like JavaScript than PHP is the better approach, especially considering Haxe is more similar to JavaScript. PHP-like syntax is only going to alienate the current programmers. You can always just extend the Object/Anonymous Structure functionality of Haxe currently such that it completely matches JavaScript.

For example:

var keys = {
  key1: 0,
  key2: 5
};

trace(keys["key2"]);

And in a for loop:

for (key in keys)
  trace("Key is " + key + " and value is " + keys[key]);
back2dos commented 6 years ago

Speculation on potential "investors" is not particularly fruitful, but if that's where you want to go, I would point out that JavaScript's syntax is growing more complex as we speak and there is such a thing as key-value-loops:

for (const [key, value] of Object.entries(obj)) {
  console.log(`${key} ${value}`);
}
tienery commented 6 years ago

I still stand by my counter-proposal, but I had not known about the key-value-loops, and I always thought const was a TypeScript keyword. I realise languages grow and develop, that is a natural thing. Macro systems are especially complex and even I can't grasp them.

In the context of investors, I'm not just talking about people who invest strictly money. I am talking about investors of all types, such as those who invest time and effort to convince their colleagues to use this language over another, which is not strictly bound to money or finance. So as far as people helping you market this language to a wider audience, I stand by that comment and it will remain thus. At least JavaScript has had the chance to mature, while Haxe is still a growing niche community of programmers despite being around for 13 years.

Alienating your core audience is the worst thing you'd want to do for a growing language. Marketing is just as important as the language features. Take that as advice from someone who did a Business course, and don't just dismiss it.

I know this is a huge derail from the subject, but it had to be said. I don't want a language I am indeed fully invested in fall flat on its face. I'm sure the veteran Haxe programmers will stick around, but I'm no where near that level of expertise yet.

Back on topic, however, I still feel the for (key => value in array) is a little overboard, especially since the for keyword can be used in three cases, and not the original two which is complicated enough.

With this proposal, the for keyword would have three use cases:

Normal integer iteration:

for (i in 0...5)

Object iteration:

for (obj in objects)

And perhaps now key-value iteration:

for (key => value in array)

Or my preference:

for (key in keys)

which keeps to the object iteration without adding a new use case, or have both for and foreach such as in C# to make it more obvious what the for loop is doing:

foreach (obj in objects)
 // Replace the `=>` and use `,` for simplicity
foreach (key, value in array)

These are my recommendations, but it is your proposal at the end of the day.

Simn commented 6 years ago

The syntax is good, I don't think we have to discuss that any further.

I'm not sure about the details of the implementation, but relying on inlining for performance makes sense to me.

ncannasse commented 6 years ago

We have some existing problems regarding Map iteration performances but I think that's unrelated. We could add the key=>value iterator for Maps, not sure for Arrays as the => operator is not related to Arrays at all.

sebthom commented 6 years ago

Couldn't it be for arrays like this? for (index => value in array)

Simn commented 6 years ago

Let's get this into Haxe 4.

Simn commented 6 years ago

First problem: key => value in map is parsed as key => (value in map).

Simn commented 6 years ago

I'll merge this as accepted.