Arc Forumnew | comments | leaders | submitlogin
List comprehensions in Arc
5 points by musk_fan 2185 days ago | 6 comments
Hi,

I really love Python's List Comprehensions: l = [i for i in range(1, 10)] If this can be included in Arc, that would be great. If it's in the documentation but just not yet in the tutorial, please add it to the tutorial (http://old.ycombinator.com/arc/tut.txt). Thanks! I love Arc; it's so beautiful and tiny

Thoughts?



5 points by akkartik 2180 days ago | link

musk_fan, your initial attempt inspired me to build on it :) Now that we can enumerate from a start number to an end, I hanker after something more comprehensive. Also, after reading malisper's description of iterate at http://malisper.me/loops-in-lisp-part-3-iterate, I thought I'd try to mimic its syntax, in hopes that it'll fit better with a Lisp and be extensible.

Here's what I ended up with: http://akkartik.name/post/list-comprehensions-in-anarki. Is the description clear?

-----

3 points by akkartik 2154 days ago | link

List comprehensions are now in Anarki: https://github.com/arclanguage/anarki/commit/b7155e56a6

-----

5 points by i4cu 2184 days ago | link

I don't know python per say, but I don't believe arc supports them. I do know the iterator functions are there for you:

https://arclanguage.github.io/ref/iteration.html

-----

4 points by akkartik 2184 days ago | link

Yes, Arc doesn't come with list comprehensions. But it sounds like a fun exercise to build say a collect macro:

    (collect x for x in xs if odd.x)
I think it may be similar to the loop macro in Common Lisp. There's a Common Lisp implementation of loop at https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/... (via http://malisper.me/loops-in-lisp-part-2-loop by malisper)

-----

3 points by musk_fan 2180 days ago | link

I wrote a simple version that only works like so (l 0 9) == '(0 1 2 3 4 5 6 7 8 9):

     (def l (start end)
       (let lis `(1)
         (pop lis)
         (while (<= start end)
           (= lis `(,@lis ,start))
           (++ start))
         lis))
The (collect ...) structure is really cool; I'd forgotten about that; it's been awhile since I touched CLisp

-----

2 points by akkartik 2180 days ago | link

Great! A few comments:

1. Is there a reason you start with `(1) and then pop? Why not just initialize lis to nil?

2. Here's a slightly more idiomatic implementation (also more efficient, because it avoids deconstructing and reconstructing lis on every iteration):

    (def l (start end)
      (accum acc
        (for i start (<= i end) ++.i
          acc.i)))
Read more about accum and for:

    arc> (help accum)
    arc> (help for)
(I'm assuming Anarki in the above example. The Arc version is slightly different.)

-----