Arc Forumnew | comments | leaders | submitlogin
3 points by vsingh 5908 days ago | link | parent

I got a little carried away with being clever in that version. But look at the canonical Arc version:

   (rev:accum collect
      (each y whatever
         (awhen (pfft y) (collect (yo-mama (cons y it))))))
This version is pretty straightforward in expressing my intent.

As for the scaling issue, I'm still thinking about your other example. I'm not sure it's a good thing that Loop allows more and more to be tacked on. Subroutines in imperative-style languages like C++ have the same agglutinative property, and we're all familiar with the results of that.



1 point by kennytilton 5908 days ago | link

Where on earth in your intent was reversal? Either the semantic or the run-time cost (ie, now you have introduced an efficiency issue that was not there with mappend/list.

You cannot win this fight, find a white flag, run it up. Why can you not win? Because loop the DSL was written with the most common iterative design patterns in mind, and hard-coded to make them both more succinct, more efficient, and to play well with other iterative patterns we occasionally want to run merged as one iteration.

This is what DSLs are for! Read On Lisp. We build the language up to our requirements. Loop is about iteration, and Lisp stands for list-processing. 2+2 left as an exercise. :)

-----

3 points by vsingh 5908 days ago | link

I suppose I ought to have written it like this the first time:

   (w/collect
      (each y whatever
         (awhen (pfft y) (collect (yo-mama (cons y it))))))
'w/collect' being the first new operator to result from our discussion.

-----

1 point by kennytilton 5908 days ago | link

"w/collect' being the first new operator to result from our discussion."

Oh. Where can I find w/collect? And do you mean it has been added to Official Arc? I must be missing out on the action.

-----

4 points by almkglor 5908 days ago | link

It's not on the arc-wiki. However I can certainly imagine how it would look like as a naive implementation:

  (mac w/collect body
    `(rev:accum collect ,@body))
Here's a slightly more optimized form which removes the need to reverse and adds only one additional variable to the environment built by accum:

  (mac w/collect body
    (w/uniq (hd tl)
      `(let (,hd ,tl collect) nil
          (= collect
            (fn (x)
              (if hd (do (= (cdr tl) (cons x nil)) (= tl (cdr tl)))
                      (do (= hd (cons x nil)) (= tl hd)))
               x))
          ,@body
          ,hd)))

-----