Arc Forumnew | comments | leaders | submitlogin
Creating a list with n entries of default value
3 points by jsgrahamus 594 days ago | 10 comments
How would one create a list given the size of the list and the default value?


2 points by zck 594 days ago | link

You can use n-of:

    arc> (n-of 3 "hi")
    ("hi" "hi" "hi")
Documentation here: https://arclanguage.github.io/ref/list.html#n-of

Although be careful -- n-of will evaluate your default value multiple times. This could be bad if it either takes a while or does IO:

    arc> (n-of 3 (rand 10))
    (7 8 1)

-----

3 points by jsgrahamus 594 days ago | link

Thanks, zck.

Didn't know there was a built-in function, so tried creating one on my own.

  arc> (def make-list (size val)
         (let alist nil
           (def make-list2 (alist size val)
             (if (is size 0)
               alist
               (make-list2 (cons val alist) (- size 1) val)))
           (make-list2 alist size val)))
  *** redefining make-list
  #<procedure: make-list>
  arc> (make-list 5 -1)
  *** redefining make-list2
  (-1 -1 -1 -1 -1)
  arc>
Comments?

-----

2 points by jsgrahamus 594 days ago | link

Shouldn't be redefining, right?

This seems better:

  arc> (def make-list (alist size val)
         (if (is size 1)
           (cons val alist)
           (make-list (cons val alist) (- size 1) val)))
  #<procedure: make-list>
  arc> (make-list nil 5 -1)
  (-1 -1 -1 -1 -1)
  arc> (make-list nil 11 -1)
  (-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1)
  arc> (make-list nil 111 -1)
  (-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1   -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1   -1 -1 -1 -1 -1
   -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1   -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1   -1 -1 -1 -1 -1
   -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1   -1 -1 -1 -1)
  arc>
But I shouldn't have to invoke make-list with a nil list to begin with.

-----

2 points by zck 594 days ago | link

> But I shouldn't have to invoke make-list with a nil list to begin with.

You can use a helper function:

    (def make-list (size val)
         (make-list-helper nil size val))
    
    (def make-list-helper (alist size val)
         (if (is size 1)
             (cons val alist)
           (make-list-helper (cons val alist) (- size 1) val)))
But this clutters up the namespace. We can use a local helper function to move make-list-helper inside the body of make-list, and wrap it in afn to make it able to recurse.

    (def make-list (size val)
         (let helper (afn (alist size val)
                          (if (is size 1)
                              (cons val alist)
                            (self (cons val alist) (- size 1) val)))
              (helper nil size val)))

-----

2 points by akkartik 594 days ago | link

Yes you don't need the nil argument. Since make-list returns a list, do the conses on the way out of recursive calls rather than on the way in:

  (def make-list (size val)
    (if (> size 0)
      (cons val
            (make-list (- size 1) val))))
This is identical to your version, except I dropped the now-unnecessary base case (if now generates the initial list at the bottom-most recursive call) and moved the cons outside the call to make-list.

-----

2 points by jsgrahamus 594 days ago | link

Great. Still wrapping my head around recursion.

Thanks.

-----

1 point by akkartik 594 days ago | link

I'm surprised by the redefinition warnings. They don't happen for me. Perhaps you have some of your own code being loaded? Or maybe you have an old version? (Though I don't remember make-list ever being a thing.)

-----

2 points by jsgrahamus 594 days ago | link

I'm caught. Still using the old version of arc 3.1 on Windows 7 with racket.

-----

2 points by jsgrahamus 594 days ago | link

How did you know that (n-of) was a function? Where is there a list of all the functions in arc?

-----

1 point by akkartik 594 days ago | link

Discoverability is a perennial issue. Arc 3.1 is pretty comprehensively documented at https://arclanguage.github.io/ref (even if it's a lot to read). n-of is in the page on list operations: http://arclanguage.github.io/ref/list.html Unfortunately changes to Arc 3.1 in Anarki are harder to find; nobody's gotten around to building a copy of Ken Shirriff's reference for Anarki. One good place to the first order is the https://github.com/arclanguage/anarki/tree/master/CHANGES directory on Github.

-----