Arc Forumnew | comments | leaders | submitlogin
Real-world eval of (is shorter better)
2 points by kennytilton 6080 days ago | discuss
[Originally posted to comp.lang.lisp where Arc has the CL establishment quaking in its boots.]

I literally grabbed a the first function I saw in my code for an experiment:

; --- the doc --- ; (I just moved the doc down below so one can encounter the code

; the normal way we encounter OPC, cold.) ;

; --- assuming like most yobs you haven't even looked at Arc ---

; CL: (mapcar (lambda (x) (mod x 42)) y)

; Arc: (map [mod _ 42] y) or (map (fn (x) (mod x 42)) y)

I'll show the Arc version first cuz I think it is more obscure and I want you to see it before the CL "dummies" version(s) makes it obvious what is going on:

; --- Arc version ----------- ;

   (def tf-traverse-results (tf result-fn)
     (when tf
       (tf-traverse tf
         [map [map result-fn (results _)]
            (derivations _)]]))
; --- CL version --------------

  (defun tf-traverse-results (tf fn)
   (when tf
    (tf-traverse tf
      (lambda (tf)
        (loop for d in (derivations tf) do
              (loop for result in (results d)
                  do (funcall fn result)))))))
The fun thing there is that I am cheating by using LOOP, which shares with Arc a goal of achieving brevity and fewer parens at the cost of learning syntax, but ...OK, without loop (but using dolist instead!):

  (defun tf-traverse-results (tf fn)
   (when tf
    (tf-traverse tf
      (lambda (tfsub)
        (dolist (d (derivations tfsub))
          (dolist (result (results d))
            (funcall fn result)))))))
[Note to self: maybe don't use LOOP for everything?]

Turns out it is an interesting example because in Arc we get nested _s, fortunately not needing access to the outer binding of _ once the inner is bound (so it ain't all /that/ nested).

Of course one could always use fn:

; --- Arc2 ---

  (def tf-traverse-results (tf result-fn)
   (when tf
    (tf-traverse tf
      (fn (tf)
        (map (fn (d)
               (map result-fn (results d)))
          (derivations tf))))))
Keeping one of the abbreviated fns:

; --- Arc3 ---

  (def tf-traverse-results (tf result-fn)
   (when tf
    (tf-traverse tf
      (fn (tf)
        (map [map result-fn (results _)]
          (derivations tf))))))
It was a random choice, but the tight packing of all these iterations and 1st-class functions might be confusing the issue. Anyway...

The CL versions are both trivial to read and even make obvious the organization of the data structures if one did not know them, which could be me because who can remember all that in a huge application?

I am not sure on the Arc version since I am still new to reading it, but it seems like it would always take more work to unwind in my head. As for the brevity of the denser version, hey, why did God create scroll bars?

The doc: ; A transformation (tf) consists in part of 1 or more derivations

; A derivation relates 1+ operands to 1+ result expressions

; A transformation can have child transformations, forming a TF tree

; tf-traverse visits every TF in a TF tree applying a function

; tf-traverse-results applies a function to each result in each derivation of each TF in a tree