1. length() and looping

4.0.5 (362497032f33, 2012-10-11)

Can anyone explain the behavior of the following code? What am I missing?

include std/console.e 
 
 
sequence data = {} 
for i = 1 to 5 do 
data = append(data,64 + i) 
end for 
 
for i = 1 to 5 do 
	printf(1,"%d  %s\n",{i,data[i]}) 
end for 
any_key()		--stops program and awaits <cr> 
for i = 1 to length(data)/2 do	--length(data)/2 = 2, so... 
				-- for i = 1 to 2 do 
	printf(1,"%d  %s\n",{i,data[i]}) 
end for 
any_key() 
printf(1,"First time: length(data) = %d\n\n",length(data)) 
for i = length(data)/2 + 1 to length(data) do	--for i = 3 to 5 do 
	printf(1,"%d  %s\n",{i,data[i]})	 
end for 
printf(1,"\nSecond time: length(data) = %d\n",length(data)) 
any_key() 
puts(1,"Now for the finale!\n") 
for i = 1 to 5 do 
	printf(1,"%d  %s\n",{i,data[i]}) 
end for 
puts(1, "I seem to have misplaced the letter E!\n") 
any_key() 
 

1  A 
2  B 
3  C 
4  D 
5  E 
 
1  A 
2  B 
First time: length(data) = 5 
 
3  C 
4  D 
 
Second time: length(data) = 5 
 
Now for the finale! 
1  A 
2  B 
3  C 
4  D 
5  E 
I seem to have misplaced the letter E! 

new topic     » topic index » view message » categorize

2. Re: length() and looping

integer len = 5 
 
for i = len/2 + 1 to len do 
   ? i 
end for 
 
-->> 3.5 
-->> 4.5 
 
-- never gets to 5.5 since it is larger that "5" 

but, when outputing your data, you are using the implicit truncation of index values so, you "loose" that index value that should have been 5.5 truncated

_tom

new topic     » goto parent     » topic index » view message » categorize

3. Re: length() and looping

Thanks for your quick reply. I think the problem I have with this is that loop indices are by default atoms only, actually floating point only. Euphporia uses a slight of hand to deal with them. Implicit type conversions are not allowed in euphoria. for example:

integer i = 1.23 
is not allowed however,
for i = 1.23 + to_integer(23) to 77.3 do 
is allowed. Note the implicit conversion taking place. Most languages get around this problem by allowing one to declare the type of the index; but, not Euphoria (it MUST be an atom). An integer is a special case of an atom that the compiler often takes advantage of; but, apparently not in this case. However, Euphoria requires the type declaration for all other data types. As I am sure you realize, indices that can be integers are very useful. Attempting integer math using floating point numbers usually leads to a lot of annoying fuzz. With euphoria one has to fool around with an assortment of functions to convert the index to an integer after the fact.

for i = 1.999 + to_integer(1) to 30/3.0 by ceil(2.15) do 
	integer j = to_integer(i) 
	? {i,j,round(i)} 
end for 

None of this really matters. It is what it is. Sometimes I get caught!

Thanks again,
jd

new topic     » goto parent     » topic index » view message » categorize

4. Re: length() and looping

jessedavis said...

Most languages get around this problem by allowing one to declare the type of the index; but, not Euphoria (it MUST be an atom).

Many years ago I wrote a preprocessor for RDS Euphoria called Dredge. One feature it added was the wfor loop. (Short for "While-implemented FOR loop".) In the earliest version, this is how it worked:

You'd code it like this:

integer i 
wfor i = 1.23 + to_integer(23) to 77.3 /* by 2.15 */ do 
... 
end wfor 

and it'd convert it to this:

integer i 
i = 1.23 + to_integer(23) 
while i < 77.3 do 
... 
i += 1 
/* or, if using by keyword, then i += 2.15 */ 
end while 

Note, however, that this by itself would have been illegal:

wfor i = 1.23 + to_integer(23) to 77.3 do 
... 
end wfor 

You were required to declare the variable to use in the loop in advance. (Today, that would no longer be true because of 4.0+'s support for forward referencing - but you would still have to declare it somewhere in the same scope as the loop.)

The primary use of this contruct was because, back then, RDS Euphoria did not allow you to manually set the value of the loop iterator in a for loop. (Today, 4.0+ allows this.) The requirement to manually declare the iterator first was just a result of the different semantics between the for loop (which had automatic variable creation) and the while loop (which did not).

jessedavis said...
for i = 1.999 + to_integer(1) to 30/3.0 by ceil(2.15) do 
	integer j = to_integer(i) 
	? {i,j,round(i)} 
end for 

None of this really matters. It is what it is. Sometimes I get caught!

Thanks again,
jd

Even wfor wouldn't provide perfect protection here. The above (without the 'protection' you added) wouldn't work in a wfor with an integer variable, but I suspect that this might:

--on 32bit 
constant nan=-(2*power(10,308)/(3*power(10,308))), inf=2*power(10,308) 
wfor i = 1 to nan by 2 do 
... 
end wfor 
new topic     » goto parent     » topic index » view message » categorize

5. Re: length() and looping

Guys,

Thanks for taking the time to discuss this with me. I appreciate it!

Best Regards,
jd

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu