Skip to main content

psetq

psetq Macro

Syntax:

psetq {↓pair}* → nil

pair::=var form

Pronunciation:

psetq: [ p—e set kyu- ]

Arguments and Values:

var—a symbol naming a variable other than a constant variable.

form—a form.

Description:

Assigns values to variables.

This is just like setq, except that the assignments happen “in parallel.” That is, first all of the forms are evaluated, and only then are the variables set to the resulting values. In this way, the assignment to one variable does not affect the value computation of another in the way that would occur with setq’s sequential assignment.

If any var refers to a binding made by symbol-macrolet, then that var is treated as if psetf (not psetq) had been used.

Examples:

;; A simple use of PSETQ to establish values for variables. 
;; As a matter of style, many programmers would prefer SETQ
;; in a simple situation like this where parallel assignment
;; is not needed, but the two have equivalent effect.
(psetq a 1 b 2 c 3) → NIL
a → 1
b → 2
c → 3
;; Use of PSETQ to update values by parallel assignment.
;; The effect here is very different than if SETQ had been used.
(psetq a (1+ b) b (1+ a) c (+ a b)) → NIL
a → 3
b → 2
c → 3
;; Use of PSETQ on a symbol macro.
(let ((x (list 10 20 30)))
(symbol-macrolet ((y (car x)) (z (cadr x)))
(psetq y (1+ z) z (1+ y))
(list x y z)))
((21 11 30) 21 11)
;; Use of parallel assignment to swap values of A and B.
(let ((a 1) (b 2))
(psetq a b b a)
(values a b))
→ 2, 1

Side Effects:

The values of forms are assigned to vars.

See Also:

psetf, setq

Expanded Reference: psetq

Basic parallel assignment

psetq assigns values to variables in parallel. All the value forms are evaluated first, then all assignments happen simultaneously.

(let ((a 1) (b 2) (c 3))
(psetq a 10 b 20 c 30)
(list a b c))
=> (10 20 30)

Swapping two variables

The parallel nature of psetq makes swapping values trivial, with no need for a temporary variable.

(let ((a 1) (b 2))
(psetq a b b a)
(list a b))
=> (2 1)

Difference from setq

With setq, assignments happen sequentially, so later assignments see the effects of earlier ones. With psetq, all value forms see the original values.

;; With setq: sequential assignment
(let ((a 1) (b 2))
(setq a (+ b 1) b (+ a 1)) ; a becomes 3, then b becomes 4
(list a b))
=> (3 4)

;; With psetq: parallel assignment
(let ((a 1) (b 2))
(psetq a (+ b 1) b (+ a 1)) ; both see original values
(list a b))
=> (3 2)

Rotating values among three variables

(let ((x 'a) (y 'b) (z 'c))
(psetq x y y z z x)
(list x y z))
=> (B C A)

psetq always returns NIL

Regardless of the assignments, psetq always returns NIL.

(let ((a 1) (b 2))
(psetq a 10 b 20))
=> NIL