Arc Forumnew | comments | leaders | submitlogin
2 points by fallintothis 6139 days ago | link | parent

I think you're looking for prall, defined in arc.arc:

  (def prall (elts (o init "") (o sep ", "))
    (when elts
      (pr init (car elts))
      (map [pr sep _] (cdr elts))
      elts))
Then, you save a function and choices becomes more like:

  (def choices (menu (o result '()))
    (if menu
        (each x (car menu)
          (choices (cdr menu) (cons x result)))
        (prall (rev result) "\n" #\space)))
If having that newline at the beginning of the output is killing you, then you could also use it inside of a do:

  (def choices (menu (o result '()))
    (if menu
      (each x (car menu) 
        (choices (cdr menu) (cons x result)))
      (do (prall (rev result) "" " ") (prn))))


3 points by lojic 6139 days ago | link

Cool. I also just discovered that apparently Arc#join is CL#append, so I could use join instead of cons and skip the rev.

-----

3 points by lojic 6139 days ago | link

  ; Cartesian product of elements of menu
  (def choices (menu (o result '()))
    (if menu
      (each x (car menu)
        (choices (cdr menu) (join result (list x)))) 
      (prall result "\n" " ")))     

  (choices (list
    (list "small" "medium" "large")
    (list "vanilla" "ultra chocolate" "lychee" "rum raisin" "ginger")
    (list "cone" "cup")))

-----

2 points by fallintothis 6139 days ago | link

Ah, I was wondering why append wasn't working, haha. Now I recall reading the source about how Robert Morris thought it was better to overload + for join -- which still seems to work, by the way.

Also, come to think of a nit-picky issue, optional args will default to nil = '(), so you could just as well say:

  (def choices (menu (o result))
    (if menu
        (each x (car menu)
          (choices (cdr menu) (+ result (list x))))
        (prall result "\n" " ")))
Not that it matters all that much.

One artifact I notice is that, since it returns nil but is only printing a newline at the beginning, the printout ends with "large ginger cupnil". I suppose, to avoid that in the repl, you could slap a (prn) at the end of the function definition or use the aforementioned (do ...) block. I got to thinking it might also be nice to have a prnall, but then I noticed that this is just prn:

  (def choices (menu (o result))
    (if menu
        (each x (car menu)
          (choices (cdr menu) (+ result (list x))))
        (apply prn (intersperse " " result))))
Though this could be cleaner with prnall:

  (def prnall args
    (do1 (apply prall args) (prn)))
At any rate, all these thoughts are very pedantic -- but then, so am I.

-----