| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The second form is a "generalized set!" specified in SRFI-17. It is a syntactic sugar of the following form.
((setter proc) arg ... expression) |
setf.
Some examples:
(define x 3) (set! x (list 1 2)) => undefined x => (1 2) (set! (car x) 5) => undefined x => (5 2) |
(define a 0) (define b 1) (set!-values (a b) (values 3 4)) => undefined a => 3 b => 4 (set!-values (a b) (values b a)) => undefined a => 4 b => 3 |
A setter procedure g of a procedure f is such that when used
as (g a b ... v), the next evaluation of (f a b ...)
returns v.
To associate a setter procedure to another procedure, you can use
the setter of setter, like this:
(set! (setter f) g) |
A procedure's setter can be "locked" to it. System default setters,
like set-car! for car, is locked and can't be set by
the above way. In order to lock a setter to a user defined procedure,
use getter-with-setter below.
The intention of this procedure is, according to the SRFI-17 document, to allow implementations to inline setters efficiently. Gauche hasn't implement such optimization yet.
A few macros that adopts the same semantics of generalized set!
are also provided. They are built on top of set!.
set!. The result of this form
is undefined.
(define x (list 2)) (push! x 3) => undefined x => (3 2) (push! (cdr x) 4) => undefined x => (3 4 2) |
When place is a list, it roughly expands like the following.
(push! (foo x y) item)
==
(let ((tfoo foo)
(tx x)
(ty y))
((setter tfoo) tx ty (cons item (tfoo tx ty))))
|
Note: Common Lisp's push macro takes its argument reverse
order. I adopted this order since it is consistent with other
destructive operations. Perl's push function takes the same
argument order, but it appends item at the end of the array
(Perl's unshift is closer to push!).
You can use a queue (See section 11.22 util.queue - Queue) if you need a behavior of Perl's
push.
(define x (list 1 2 3)) (pop! x) => 1 x => (2 3) (define x (vector (list 1 2 3))) x => #((1 2 3)) (pop! (vector-ref x 0)) => 1 x => #((2 3)) |
Note: This works the same as Common Lisp's pop.
Perl's pop pops value from the end of the sequence;
its shift does the same thing as pop!.
inc!) or subtracts (dec!) delta to/from it,
and then stores the result to place. The default value of
delta is 1.
This is Common Lisp's incf and decf.
push! etc. Proc must be a procedure
which takes one argument and returns one value. The original value of
place is passed to the proc, then its result is set to
place.
(define a (cons 2 3)) (update! (car a) (lambda (v) (* v 3))) => undefined a => (6 . 3) (update! (cdr a) (cut - <> 3)) a => (6 . 0) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |