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.
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
Well, you can do something similar to my C++ solution with a macro in C (assuming some compiler extensions):
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.
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.
Here’s a solution in Common Lisp.
Example Usage:
I didn’t realize the editor was using tabs. Here’s the same code, hopefully properly formatted (indented) this time.
Example usage:
Common Lisp already has PSETQ and PSETF.
(psetq a b b a) ; swap a and b
(psetf (aref v i) (aref v j) (aref v j) (aref v i)) ; swap a[i] and a[j]