Parallel "expand".

Parallel "Expand"

Almost all Lisp dialects support both "parallel" and "serial" assignment operators like let and letn in Newlisp. For example

    (setf y 1)
    (let((y 2)(x y)) x)  ==> 1   (parallel)


   (setf y 1)
   (letn((y 2)(x y)) x)  ==> 2   (serial)

Expand-expression in Newlisp

   (expand '(x y) 'x 'y)

results in replacement of x and y in (x y) with values of x and y. Expand-expression in other form:

   (expand '(x y) ((x <value1>)(y <value2>)))

results in replacement of x and y in (x y) with <value1> and  <value2>.

In both cases, the replacement is performed in serial fashion. For  example,
   (expand '(x y) '((x y)(y 3))) ==> (3 3)

In this post I present the implementation of parallel expand,  expand// in Newlisp; two slashes in name remind on parallel lines such that, for instance

   (expand// '(x y) '((x y)(y 3))) ==> (y 3).

Parallel expand expression can be reduced to serial expand with introduction of new variables.

  (expand// <expr> '((<var1> <val1>)...(<varn> <valn>))) =

  (expand <expr> '((<var1>   expand//1) ... (<varn>   expand//<n>)
                   (expand//1 <val1>  ) ... (expand//n <valn>)))

Fexpr expand// can use always the same temporary variables expand//1, ..., expand//n, without need for generating fresh variables each time expand// is called. Other form of expand//,

  (expand// <expr> '<var0> ... '<varn>)

can be reduced on form

  (expand <expr>
         '((<var0>   expand//0) ...        (<varn> expand//<n>)
           (expand//0 <value of var0>) ... (expand//<n> <value of var<n>>))).

Using that idea, the implementation is not very technical

(define (expand// expr)
  (letn((a (args))
        (expand//sym (lambda(n)(sym (append "expand//" (string n)))))
    (if (empty? a)
        (throw-error "expand//: arguments missing.")

        (cond ((symbol? (first a))
               (append (map (lambda(i)(list i (expand//sym $idx))) a)
                       (map (lambda(i)(list (expand//sym $idx) (eval i))) a)))
              ((list? (first a))
               (append (map (lambda(i)(list (i 0) (expand//sym $idx))) (first a))
                       (map (lambda(i)(list (expand//sym $idx) (i 1))) (first a))))))))

       (println "expandlist=" expandlist)
       (expand expr expandlist)))

(setf x 'y)
(setf y 3)
(println (expand '(x y) 'x 'y))           ; => (3 3)
(println (expand// '(x y) 'x 'y))         ; => (y 3)
(println (expand '(x y) '((x y)(y 3))))   ; => (3 3)
(println (expand// '(x y) '((x y)(y 3)))) ; => (y 3)



No comments:

Post a Comment