Parallel Assignment

January 11, 2019

I had trouble writing this program, so I found this snippet due to Kent Dybvig:

(define-syntax pset!
  (syntax-rules ()
    [(_ [x e] ...)
     (for-each
       (lambda (f v) (f v))
       (list (lambda (t) (set! x t)) ...)
       (list e ...))]))

That’s clear and elegant. I knew I needed for-each, and I knew that I couldn’t use let, because that would introduce a new environment and new variables, but I didn’t figure out those beautiful and very idiomatic uses of lambda. Maybe someday I’ll be as good a programmer as Kent Dybvig. Here’s an example:

> (define a 1)
> (define b 2)
> (define c 3)
> (list a b c)
(1 2 3)
> (pset! (a b) (b c) (c a))
> (list a b c)
(2 3 1)

 

You can run the program at https://ideone.com/jO200s.

Advertisements

Pages: 1 2

5 Responses to “Parallel Assignment”

  1. matthew said
    #include <stdio.h>
    
    template <typename T0, typename T1>
    void assign(T0 &t0, T1 &t1, T0 e0, T1 e1) {
      t0 = e0; t1 = e1;
    }
    
    template <typename T>
    void swap(T &t0, T &t1) {
      assign(t0,t1,t1,t0);
    }
    
    int main() {
      int a = 0, b = 1;
      printf("%d %d\n",a,b);
      swap(a,b);
      printf("%d %d\n",a,b);
      swap(a,b);
      printf("%d %d\n",a,b);
    }
    
  2. Lucio said

    The code in C in your email above does a swap of the values of x and y using t as temporary storage. C does not have parallel assignment

  3. matthew said

    Well, you can do something similar to my C++ solution with a macro in C (assuming some compiler extensions):

    #include <stdio.h>
     
    #define assign(t0,t1,e0,e1) \
      ({typeof(e0) _e0 = (e0); typeof(e0) _e1 = (e1); \
        (t0) = _e0; (t1) = _e1; \
      })
    
    #define swap(t0,t1) (assign(t0,t1,t1,t0))
     
    int main() {
      int a = 0, b = 1;
      printf("%d %d\n",a,b);
      swap(a,b);
      printf("%d %d\n",a,b);
      swap(a,b);
      printf("%d %d\n",a,b);
    }
    
  4. matthew said

    That should be “typeof(e1) _e1 = …” of course. And swap should be SWAP if we use the convention that macros that evaluate their arguments multiple times should be in upper case.

  5. chaw said

    I wrote this before reading the solution by @programmingpraxis
    (Dybvig’s pset!). It’s not as clever as that one but I think it works
    as needed.

    (import (scheme base)
            (scheme write))
    
    (define-syntax parallel-set!
      (syntax-rules ()
        ((_ () ()) ; just for completeness
         (values))
        ((_ (d0) (s0)) 
         (set! d0 s0))
        ((_ (d0 d1 d2 ...) (s0 s1 s2 ...))
         (let ((t0 s0))
           (parallel-set! (d1 d2 ...) (s1 s2 ...))
           (set! d0 t0)))))
    
    (let ((a 'va)
          (b 'vb)
          (c 'vc)
          (d 'vd)
          (e 've)
          (f 'vf))
      (parallel-set! (a b c d e f) (b c a e d f))
      (display (list a b c d e f))
      (newline))
    

    (vb vc va ve vd vf)
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: