Why can't assign to "for..IN" variable? lazarus / 64-FPC development ---------------------------------------------------------------------- kupferstecher · 2018-06-14 08:09 The below code doesn't compile. The error message I understand, but I don't see why this shouldn't work. The compiler would have to make an extra step, i.e. after fetching the value from the array and doing the loop calculations writing the result back to the array. The compiler already detects that the variable is modified, so writing it back in the end of the loop should be no problem. Is there an explanation why this shouldn't work? The iterations aren't changed by such an action. In opposite in a normal for..to loop this would be the case. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1;var  scalar: double;  vector: array of double;begin    for scalar in vector do scalar:= 0; //Error: Illegal assignment to for- loop variable "scalar" end. ---------------------------------------------------------------------- marcov · 2018-06-14 08:20 The for..in is based on an interface that returns a value, not a reference. This for iterations over collections where the results are calculated. Delphi doesn't support it either. ---------------------------------------------------------------------- kupferstecher · 2018-06-14 08:40 Perhaps in the type IEnumerator there could be an additional method like ReturnCurrent. Also iterations over arrays could support it independently to collections. But I see, this would quickly get complicated. ---------------------------------------------------------------------- marcov · 2018-06-14 09:13 I don't know how complicated it would be either. But while I usually think most proposed extensions are mindless bulletlist hunting and syntax grafiti, I think this one would actually be useful. (depending on the work of course). ---------------------------------------------------------------------- Phemtik · 2018-06-14 09:42 in Ada 2012, for example, this feature was added. So it is quite new there. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for x of b loop    x := -x; -- access and modify each elementend loop; Would be a nice feature to have this in Free Pascal also, but I don't know if it's difficult or good to change the behaviour of an existing feature. It would make code cleaner on some occasions. ---------------------------------------------------------------------- kupferstecher · 2018-06-14 09:49 I see it like you [marcov], a lot of extension proposals are not very useful. Furthermore I think its very important that all features are as intuitive as possible. In respect to the for-in syntaxt I expected it to be able to write back the result. But sure it's not a real 'problem'. ---------------------------------------------------------------------- kupferstecher · 2018-06-14 09:54 Quote from: Phemtik on June 14, 2018, 11:42:55 amIt would make code cleaner on some occasions.Yes, like in my example, my solution now is as follows. From typing side its a minor difference, but much easier to make a range mistake. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for ii:= 0 to high(vector) do vector[ii]:= 0; ---------------------------------------------------------------------- Phemtik · 2018-06-14 10:03 Hehe, you made even one. You need this to be totally sure that you have no range error. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for ii:= Low(Vector) to high(vector) do vector[ii]:= 0; ---------------------------------------------------------------------- taazz · 2018-06-14 10:03 Quote from: kupferstecher on June 14, 2018, 11:54:12 amQuote from: Phemtik on June 14, 2018, 11:42:55 amIt would make code cleaner on some occasions.Yes, like in my example, my solution now is as follows. From typing side its a minor difference, but much easier to make a range mistake. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for ii:= 0 to high(vector) do vector[ii]:= 0;Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  vector: array of double;begin   FillChar(@vector[Low(vector)], High(vector)-low(vector),0)end; no for at all and probably faster. ---------------------------------------------------------------------- taazz · 2018-06-14 10:04 Quote from: Phemtik on June 14, 2018, 12:03:17 pmHehe, you made even one. You need this to be totally sure that you have no range error. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for ii:= Low(Vector) to high(vector) do vector[ii]:= 0;nope dynamic arrays are always zero based can't have them start at any other index. ---------------------------------------------------------------------- Thaddy · 2018-06-14 10:07 Quote from: marcov on June 14, 2018, 11:13:49 amI don't know how complicated it would be either. But while I usually think most proposed extensions are mindless bulletlist hunting and syntax grafiti, I think this one would actually be useful. (depending on the work of course). Actually this used to work in trunk for some time. I think changing members of a record or class is OK, but not the record or class itself. Simple types should be left alone at all. For in do syntax almost requires that the actual value member can not be changed. I see no reason why the members of a value member can not be changed. ---------------------------------------------------------------------- kupferstecher · 2018-06-14 10:25 Quote from: taazz on June 14, 2018, 12:03:33 pm FillChar(The ":= 0" was only a minimum example  Quote from: Thaddy on June 14, 2018, 12:07:02 pmI think changing members of a record or class is OK, but not the record or class itself. Simple types should be left alone at all.My first occurance of that error message was with a matrix (array of array of double) where I perform vector-wise operations. So I tried something like this Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for vector in matrix do vector:= filter(vector); I read that dynamic arrays are organized as pointers internally. But when passing an array to a procedure it will be copied if its modified within the procedure (if not passed by var). So this may be a special case. Quote from: Thaddybut not the record or class itself.Why not? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for AObject in ClassArray do AObject:= nil; ---------------------------------------------------------------------- Thaddy · 2018-06-14 10:34 Because that clashes with the premise that an index (be it an element value or otherwise) can not be changed. for in do needs an index internally. ---------------------------------------------------------------------- marcov · 2018-06-14 10:40 Quote from: taazz on June 14, 2018, 12:03:33 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  vector: array of double;begin   FillChar(@vector[Low(vector)], High(vector)-low(vector),0)end; no for at all and probably faster. Personally I would do (High(vector)-low(vector) +1)*sizeof(vector[low(vector)]) though. ... which perfectly makes the case by example, simple is safer for much used constructs. Moreover, the kupferstecher solution also works for partial initialization and initialization that is not a fixed value. ---------------------------------------------------------------------- kupferstecher · 2018-06-14 10:42 @Thaddy I guess the internal index is always an integer looping type from 0 to high, isn't? The index itself is already hidden by the for..in syntax (no variable exposed to the code), so it would be save to modify the iteration variable. ---------------------------------------------------------------------- Phemtik · 2018-06-14 11:01 I think there is no index. I thought, that It would be jumps to the next position in memory by using the size of element. No index variable necessary. ---------------------------------------------------------------------- marcov · 2018-06-14 11:10 it is more something like an iterator while Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i it:=object.getinterface;while it.interateover do  begin     v:=it.getvalue     ..... your code here  end; ---------------------------------------------------------------------- kupferstecher · 2018-06-14 14:54 And with modfied variable it could look like that. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i it:=object.getinterface;while it.interateover do  begin     v:=it.getvalue     ..... your code here      it.returnvalue(v);  end; Still, the iteration isn't disturbed by that (@Thaddy). ---------------------------------------------------------------------- ASerge · 2018-06-14 17:11 Quote from: taazz on June 14, 2018, 12:03:33 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  vector: array of double;begin   FillChar(@vector[Low(vector)], High(vector)-low(vector),0)end; Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   FillChar(Pointer(vector)^, Length(vector) * SizeOf(vector[Low(vector)]), 0) ---------------------------------------------------------------------- Leledumbo · 2018-06-15 11:08 This is quite interesting, I never imagine such a usecase. I can't imagine the required changes, though. Would it be safe to just change the interface to return a reference, considering it was already illegal to change the loop variable (but AFAIK you can turn that off?). Or a new syntax should be provided? i.e.: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for var e in a do ...using the same semantic for var parameters. Probably the latter is required since built-in iterators aren't user modifiable. ---------------------------------------------------------------------- PascalDragon · 2018-06-15 13:30 Quote from: Thaddy on June 14, 2018, 12:07:02 pmQuote from: marcov on June 14, 2018, 11:13:49 amI don't know how complicated it would be either. But while I usually think most proposed extensions are mindless bulletlist hunting and syntax grafiti, I think this one would actually be useful. (depending on the work of course). Actually this used to work in trunk for some time. I think changing members of a record or class is OK, but not the record or class itself. Simple types should be left alone at all. For in do syntax almost requires that the actual value member can not be changed. I see no reason why the members of a value member can not be changed. Records are not allowed for modification either (because they'd simply be a copy of the record, thus the changes wouldn't be visible), but classes will work as will dynamic arrays (just to avoid a misunderstanding: if we're iterating through an array of array of something with an array of something as iterator), because those are implicit pointer types and thus you're modifying the content these pointers point to. ---------------------------------------------------------------------- Thaddy · 2018-06-15 14:51 Quote from: kupferstecher on June 14, 2018, 12:42:18 pm@Thaddy I guess the internal index is always an integer looping type from 0 to high, isn't? The index itself is already hidden by the for..in syntax (no variable exposed to the code), so it would be save to modify the iteration variable. Yes, correct. The members of any structure should be modifiable. Just not the location. Because that is unknown. When (not if) you are assuming is is a sequential sequence you are wrong. That's compiler internals. ---------------------------------------------------------------------- kupferstecher · 2018-06-15 17:23 Quote from: Leledumbo on June 15, 2018, 01:08:00 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for var e in a do ...Thats an interesting idea. It would prevent unintended changes. But on the negative side it makes the syntax more complicated, its not intuitive. I don't see high risk for unintended value changes anyways, because if you assign a value than normally you actually want to change it. Or in other words, outside a for..in loop you aren't protected for unintended assignments as well, so why here. ---------------------------------------------------------------------- Thaddy · 2018-06-15 19:03 The memory manager? I rest my plea...(the memory manager is fine but not for border cases) You should learn the internals. That goes for any language. ---------------------------------------------------------------------- kupferstecher · 2018-06-15 19:48 Do we talk about different things? If I have a loop like that (if it would/will be possible): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i setlength(bmpArray,10);for bmp in bmpArray do bmp:= TBitmap.Create;Then I change the address of the class instance. But for the loop that shouldn't be an issue, as the pointer to the class for the loop organization is just data. If this is an integer or pointer or anything else doesn't matter for the loop. As long as I don't touch the array's addresses. So in the example the bmpArray shall be untouched within the loop (like the iteration variable in a normal for..to loop).