Recent

Author Topic: Why can't assign to "for..IN" variable?  (Read 8603 times)

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Why can't assign to "for..IN" variable?
« on: June 14, 2018, 10:09:49 am »
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][+][-]
  1. program Project1;
  2. var
  3.   scalar: double;
  4.   vector: array of double;
  5. begin
  6.     for scalar in vector do scalar:= 0; //Error: Illegal assignment to for-loop variable "scalar"
  7.  
  8. end.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Why can't assign to "for..IN" variable?
« Reply #1 on: June 14, 2018, 10:20:29 am »
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

  • Hero Member
  • *****
  • Posts: 583
Re: Why can't assign to "for..IN" variable?
« Reply #2 on: June 14, 2018, 10:40:09 am »
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

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Why can't assign to "for..IN" variable?
« Reply #3 on: June 14, 2018, 11:13:49 am »
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

  • New Member
  • *
  • Posts: 19
Re: Why can't assign to "for..IN" variable?
« Reply #4 on: June 14, 2018, 11:42:55 am »
in Ada 2012, for example, this feature was added. So it is quite new there.

Code: Pascal  [Select][+][-]
  1. for x of b loop
  2.     x := -x; -- access and modify each element
  3. end 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.
Intel i7-3610QM
Fedora 28

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: Why can't assign to "for..IN" variable?
« Reply #5 on: June 14, 2018, 11:49:18 am »
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

  • Hero Member
  • *****
  • Posts: 583
Re: Why can't assign to "for..IN" variable?
« Reply #6 on: June 14, 2018, 11:54:12 am »
It 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][+][-]
  1. for ii:= 0 to high(vector) do vector[ii]:= 0;

Phemtik

  • New Member
  • *
  • Posts: 19
Re: Why can't assign to "for..IN" variable?
« Reply #7 on: June 14, 2018, 12:03:17 pm »
Hehe, you made even one.
You need this to be totally sure that you have no range error.

Code: Pascal  [Select][+][-]
  1. for ii:= Low(Vector) to high(vector) do vector[ii]:= 0;
Intel i7-3610QM
Fedora 28

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Why can't assign to "for..IN" variable?
« Reply #8 on: June 14, 2018, 12:03:33 pm »
It 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][+][-]
  1. for ii:= 0 to high(vector) do vector[ii]:= 0;
Code: Pascal  [Select][+][-]
  1. var
  2.   vector: array of double;
  3. begin
  4.    FillChar(@vector[Low(vector)], High(vector)-low(vector),0)
  5. end;
  6.  
no for at all and probably faster.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Why can't assign to "for..IN" variable?
« Reply #9 on: June 14, 2018, 12:04:53 pm »
Hehe, you made even one.
You need this to be totally sure that you have no range error.

Code: Pascal  [Select][+][-]
  1. 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.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Why can't assign to "for..IN" variable?
« Reply #10 on: June 14, 2018, 12:07:02 pm »
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).
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.
« Last Edit: June 14, 2018, 12:10:12 pm by Thaddy »
Specialize a type, not a var.

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: Why can't assign to "for..IN" variable?
« Reply #11 on: June 14, 2018, 12:25:37 pm »
FillChar(
The ":= 0" was only a minimum example  ;)

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.
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][+][-]
  1. 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: Thaddy
but not the record or class itself.
Why not?
Code: Pascal  [Select][+][-]
  1. for AObject in ClassArray do AObject:= nil;

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Why can't assign to "for..IN" variable?
« Reply #12 on: June 14, 2018, 12:34:01 pm »
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.
Specialize a type, not a var.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Why can't assign to "for..IN" variable?
« Reply #13 on: June 14, 2018, 12:40:20 pm »
Code: Pascal  [Select][+][-]
  1. var
  2.   vector: array of double;
  3. begin
  4.    FillChar(@vector[Low(vector)], High(vector)-low(vector),0)
  5. end;
  6.  
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.


« Last Edit: June 14, 2018, 12:41:58 pm by marcov »

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: Why can't assign to "for..IN" variable?
« Reply #14 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.
« Last Edit: June 14, 2018, 12:45:12 pm by kupferstecher »

 

TinyPortal © 2005-2018