Arc Forumnew | comments | leaders | submitlogin
Replace loop with xloop
2 points by malisper 3871 days ago | 6 comments
Since we now have two basic looping constructs, I was thinking we could actual just get rid of the original loop and replace it with xloop and then implement all of the other looping constructs in terms of that. Does anyone see any problem with this?


2 points by akkartik 3870 days ago | link

It took me a while to understand this, but you're right. No reason that while (https://github.com/arclanguage/anarki/blob/5c9983144c/arc.ar...) can't be built out of xloop.

Changing the names is a separate matter. We could rename the existing loop to for. Does anybody object to that? It's been baked in since the original arc, so I'm feeling a little cautious about messing with it. Any suggestions for alternative names to the existing for which only works on ranges of numbers? One idea is to call it up since there's already a down just below it that scans downward on ranges of numbers.

In wart I chose to define for with a variable declaration. Compare https://github.com/akkartik/wart/blob/b7b822f4fb/048control.... and https://github.com/arclanguage/anarki/blob/5c9983144c/arc.ar.... Once for declares its own variable I think you no longer need a separate macro for up and down. Thoughts?

-----

2 points by malisper 3870 days ago | link

For some reason I thought for and while were both implemented using loop. Turns out only for is so that probably led to some confusion. I guess it would make sense to implement while with xloop. I do like the idea of moving the current for to up. What I meant originally was to replace the uses of loop with xloop.

I have to agree with you that the current loop should definitely allow variable declarations as it should be the general case of up/down. The remaining cases should be covered by while (unless we want to put the update and the test in the same place which I see no reason for).

Just a question about some of your code. How is while not infinitely recursive? Are macros substituted at runtime in wart?

Edit: I just realized that we can implement the current loop in terms of xloop.

-----

2 points by akkartik 3869 days ago | link

Ok, anarki now has a coherent set of iteration primitives. At bottom is the erstwhile xloop, now called loop: https://github.com/arclanguage/anarki/blob/96a2757190/arc.ar....

Almost all existing occurrences of rfn are now switched to use loop. For example, see the new rev: https://github.com/arclanguage/anarki/blob/96a2757190/arc.ar...

The old loop is renamed to the subtly different for which now declares its own variable. Since for is kinda imperative, it supports break and continue out of the box: https://github.com/arclanguage/anarki/blob/96a2757190/arc.ar.... So does while: https://github.com/arclanguage/anarki/blob/96a2757190/arc.ar...

I've made a subtle change to up and down -- following C, they are no longer inclusive of their second bound. Before:

  arc> (up i 0 3 prn.i)
  0
  1
  2
  3
After:

  arc> (up i 0 3 prn.i)
  0
  1
  2
I think I've caught all their callers and corrected them, but there might be stray bugs in lib/math.arc. (It's amazing how much cleaner math.arc has gotten with the saner, C-inspired bounds.)

As the piece de resistance, compare drain before (https://github.com/arclanguage/anarki/blob/426b07440bb8d8531...):

  (mac drain (expr (o eof nil))
    (w/uniq (gacc gdone gres)
      `(with (,gacc nil ,gdone nil)
	 (while (no ,gdone)
	   (let ,gres ,expr
	     (if (is ,gres ,eof)
	       (= ,gdone t)
	       (push ,gres ,gacc))))
	 (rev ,gacc))))
And after (https://github.com/arclanguage/anarki/blob/96a2757190/arc.ar...):

  (mac drain (expr (o eos nil))
    (w/uniq (gacc gres)
      `(accum ,gacc
	 (whiler ,gres ,expr ,eos
	   (,gacc ,gres)))))
I'm still concerned about changing the semantics of loop and for, especially with the prospect of updates from pg. Fortunately it's easy to roll back these changes :)

-----

3 points by akkartik 3869 days ago | link

A final, more speculative change: for loops are named, so you can break and continue multiple loops at once using the name of the loop variable. Both these fragments have identical output:

  (up i 0 3
    (up j 0 3
      (if (> j i) (break))
      (prn i " " j)))

  (up i 0 3
    (up j 0 3
      (if (> j i) (continue-i))
      (prn i " " j)))

-----

1 point by akkartik 3859 days ago | link

What do people think of how tokens looks with afn vs loop? https://github.com/arclanguage/anarki/commit/1dd646ddcb

-----

1 point by akkartik 3870 days ago | link

Yes, wart has first class macros :) I meant to bring that up when comparing while in arc and wart.

-----