Common Lisp has a very useful idiom of SETF that can set values to arbitrary places. For example, one can set (1 2)-th item of an array A as:
(SETF (AREF A 1 2) 20.0d0)
Scheme preferred way is to use `*-set!` procedures. However, sometimes it is inconvenient. For example, if I want to swap two elements in the array/vector, I would like to use `swap`:
(define-syntax swap
(syntax-rules ()
((swap ?place1 ?place2 ?tmp)
(begin
(set! ?tmp ?place1)
(set! ?place1 ?place2)
(set! ?place2 ?place1)))))
But it will only work for vectors if `set!` can act as CL's SETF on generalised places, such as
(swap (vector-ref v 5) (vector-ref v 3) tmp)
SRFI-17 contains the definition of such a `set!` and I can use it from there (AFAIR Racket supports it).
I was wondering if there is more Racket-way of doing this? And is there maybe a reason why `set!` wasn't given the same power as SETF?
For example, I was thinking of defining syntax to access my implementation of multidimensional arrays
as
(define-syntax aref
(syntax-rules (set!)
[(set! (aref ?a ?i ...) ?v) (array-set! ?a ?i ... ?v)]
[(aref ?a ?i ...) (array-ref ?a ?i ...)]))
but obviously it won't work now as `set!` expects the `id` not an expression (`syntax-id-rules` won't work either as `aref` is not an `id`).
Regards, Alexey
set!
."--
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "Racket Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/racket-users/TWE4Yemx28Y/unsubscribe.
To unsubscribe from this group and all its topics, send an email to racket-users...@googlegroups.com.
Hi all,Thanks to all replies, at the moment I would tend to agree that generalised `set!` might not be such a great idea after all:
- The notion of 'place' is essentially a pointer to a memory location, but it is not the first-class citizen: the following expressions are not equivalent: (let ((x (aref v 5))) (set! x 100)) and (set! (aref v 5) 100), and it might be the place for confusion.
- The syntax part of it, `(set! (what-ever ...) new-value)`, however, I don't mind: `set!` is a special form/macro after all, not a procedure. No one would demand the procedural clarity from `let` or `define`. The question is rather if it worth having yet another special form.
Summarising the points above, what if instead of `set!` there is a more general abstraction 'location’: