1. length() and looping
- Posted by jessedavis Mar 10, 2017
- 1458 views
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!
2. Re: length() and looping
- Posted by _tom (admin) Mar 10, 2017
- 1436 views
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
3. Re: length() and looping
- Posted by jessedavis Mar 13, 2017
- 1291 views
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.23is not allowed however,
for i = 1.23 + to_integer(23) to 77.3 dois 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
4. Re: length() and looping
- Posted by jimcbrown (admin) Mar 13, 2017
- 1299 views
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).
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
5. Re: length() and looping
- Posted by jessedavis Mar 16, 2017
- 1108 views
Guys,
Thanks for taking the time to discuss this with me. I appreciate it!
Best Regards,
jd