Using loops with ELSE


UPDATE 8-Jun-2018: This post has been changed to reflect new rules

Loop constructs return NULL when there is a BREAK, and generally return a VOID! if they never run their bodies. This gives some nice expressive power, such as this example from some code that appends encapped data to executables…which uses both THEN and ELSE:

opt while [modulo (length of executable) 4096 <> 0] [
    append executable #{00}
    true ;-- not strictly necessary as the BINARY! is true, but clearer
] then [
    print [{Executable padded to} length of executable {bytes long.}]
] else [
    print {No padding of executable length required.}

What you get out of this is equivalent to this R3-Alpha code:

either 0 = modulo length? executable 4096 [
    print {No padding of executable length required.}
    while [0 <> modulo length? executable 4096] [
        append executable #{00}
    print [{Executable padded to} length? executable {bytes long.}]

It’s a way to avoid repeating yourself.

This adjusts an earlier rule, under which loops returned NULL when the body never ran, and loops that would BREAK would give BLANK!


Although it could be written more efficiently as:

m: modulo length? executable 4096
either m > 0 [
	insert/dup tail executable #{00} 4096 - m
	print [{Executable padded to} length? executable {bytes long.}]
	print {No padding of executable length required.}


That’s not really the point (it’s not performance critical code, and the point is experimenting with readability).

But so long as we’re talking about what isn’t the point, one thing to consider in R3-Alpha is that the introduction of a variable can be a large cost, if it winds up meaning you have to add a use [m] […] statement around it. You might be surprised:

r3-alpha> delta-time [loop 1000000 [n: 0 n: n + 1 n: n + 1]]
== 0:00:00.327438

r3-alpha> delta-time [loop 1000000 [n: 0 use [m] [m: 2 n: n + m]]] 
== 0:00:01.218473

So finding ways to not need variables can be interesting from an efficiency standpoint. Although tuning the efficiency of enfix is another thing that is being worked on, I’m just saying there are lots of factors. (Not so much looking at CPU cycle granularity at this point in Ren-C)


The thing is… that I would never use code like you used in your r3 example and personally had problems reading your ren-c code. But maybe I’m just old and have some habits.

Ps: I would not use the use in tight loops. I know its dark side.

Pps: I don’t have problem with this addition… just could not let the use of while instead of insert/dup without comment.


I guess. Though I’ll be a broken record about how it doesn’t work for me if all your moments of electing to comment are negative things. :angry:

I can understand that if it is unfamiliar, also might be hard to grasp…which is why I experiment with it and point it out. But is it really so hard to read:

 switch x [
     1 [print "x is one"]
     2 [print "x is two"]
 ] also [
     print "x was 1 or 2, printed which above, and prints this"
 ] else [
     print "x was neither 1 nor 2, and only this prints"

So really my point was just that this protocol by which the infix operators like ALSO and ELSE run is available to loops too…triggered by a parallel circumstance. (“Did the construct ever ‘take a branch’ on the basis of a condition?”…except here the ‘branch’ is the loop’s body.)

Now you know.