View Full Version : Bug? LScript Foreach is calling by value rather than by reference

09-27-2008, 09:39 AM
Just something that caught my attention the other day and I'd like to hear the opinions of my peers on.

It seems foreach is "calling by value" rather than "by reference". Imho this is abit unfortunate considering who uses of lscript (not hardcore coders). I would venture a guess that foreach is often used as an alternative to the for-loop just for it's convenient syntax, no other reason. But obviously they might be wrong in doing so. I think many would be surprised that it worked in the way it does. Furthermore I found nothing in the manual about it.

generic {

myArr = @1,0,[email protected];

foreach( element, myArr ) {
if( element == 0)
element = 1;

info(""+myArr[1]+", "+myArr[2]+", "+myArr[3]);

This script will return with the array as it began @1,0,[email protected], rather than @1,1,[email protected]

09-27-2008, 10:44 AM
Ya, i would agree i would rather see it called by refrence.

09-27-2008, 11:14 AM
Passing by vlaue is usually the norm with the exception of arrays and other collections, vectors, etc. This is pretty much true with most languages.

But what you are describing here has nothing to do with passing by reference or by value. It's how the control structure is designed. It is an iterator. The "element" was never meant to be a pointer to the actual element in the array, it is a simple loop placeholder for the value at each iteration.

Most other language treat loop controllers the same way. This is no different than C, PERL, Java, etc... If I did a foreach in PERL using the "by key" implementation, I wouldn't expect to be able to reassign the value of the key for each iteration. That wouldn't make sense. If I created an iterator in Java for a Vector class, I couldn't use my iterator variable to change values in the collection. The "foreach" is great for reading values. If you want to assign values, you really should use a different control structure.

09-27-2008, 11:38 AM
This is how it would look in python

myArr = [1,0,0]

for element in myArr:
if element = 0:
element = 1

But it also could look like this.

myArr = [1,0,0]

for ii, element in enumerate(myArr):
if myArr[ii] == 0:
myArr[ii] = 1

But i know Lscript is closer to c. So it may have more restrictions.

09-27-2008, 11:41 AM
:dito: What he said.

09-27-2008, 12:49 PM
myArr = @"a","b","c"@;

foreach( element, myArr ) {

This would return

I wouldn't call it a bug though.

09-27-2008, 01:30 PM
I wouldn't call it a bug though.
We call that a "feature". :)

09-29-2008, 08:40 AM
i think foreach() was documented as passing by value, albeit not too specific about it. i dont think it can be regarded as a bug.

be that as it may, if it was redesigned so that it was passed by reference do we lose anything?

09-29-2008, 09:12 AM
Other languages are interesting for comparison. But, although it might explain why things are the way they are, it doesn't necessarily justify it.

I couldn't find any reference to foreach among my reference files, but perhaps I didn't look hard enough. I agree with everything you guys say. If it was just meant as an iterator then it's fine that it works the way it does. Then it's just bad that the manual doesn't explain the implications further as many lscripters are not seasoned programmers and it isn't the only thing that makes sense (unless you limit yourself to thinking of other languages as blueprints for how things must be implemented).

So while it isn't a bug, it is imho still abit unfortunate that it was/could not have been implemented another way. This would have enabled more uses without deterring from existing uses. I venture a guess though, that it is probably abit trickier to implement, seeing as no other language seems to have bothered.

10-04-2008, 02:49 PM
I hope I'm not hijacking the thread, but the topic is relevant...

Can someone debug this script I wrote 3 years ago that now errors out on line 313 (foreach), please. It's been so long that I've forgotten most of how I came up with the code, even though I put in copious comments. The foreach loop used to work in 8.x at the least, maybe 9.0, but now it doesn't in 9.5.

As you read thru the code, you'll see that 'starpoint' is an object containing vertices created by reading in values from a cvs file (a sample provided herein for testing). 'starpoint' is used in the foreach() as the object from which to extract each 'point' element to have it's colorVmap attribute set.

The failure appears to be coming either from a change in Lscript in what sorts of objects it will accept or somehow 'starpoint' has been deleted or something. What is your assessment?

Thanks for your help!

Here's some sample data to cut/paste into a text doc called 'stars.cvs'

this line is a header and will be discarded

Rename the attached TXT file to .LS.

10-04-2008, 05:20 PM
your script is expecting to process multiple star infos but when you only supply it with 5 it bombs out

// read in 1/10th of the total lines in the file, one at a time and parse
// it into the variable, starData, using a comma as the delimiter.

for(l = 1; l < linecnt/10; l++)
starData = CSVfile.parse(",");

when it breaks the processing down to a tenth of the total stars, its trying to process 0.5 and just skips it. Because of this it doesn`t generate any points and when it reaches the foreach there are no points to iterate over

10-04-2008, 07:04 PM
Cool! Good catch! I would've never seen that one. Thanks! I suppose a test to see if the number of lines is less than 1000 is in order. If so, then skip the 'break it apart' loop.