Hi Maciek, I know its been a couple years, but you raised an interesting point that Guile wasn't really able to handle at that point. Your implementation of `in' (commonly known as `with-slots', I believe) follows the mail.
On Thu 27 Nov 2008 12:36, "Maciek Godek" <pstryc...@gmail.com> writes: > (use-modules (oop goops)) > (use-syntax (ice-9 syncase)) With Guile 2.0 (coming shortly!), there is no more need to use ice-9 syncase. > Now suppose we have an instance of a class: > (define-class C () > a b c) > (define o (make C)) > > Using the "in" macro, we can write: > (in o > (set! a 5) > (set! b (1+ a)) > (set! c (+ a b)) > (+ a b c)) > => 22 The problem with this macro is that `o' can be of any type at all, but Guile needs to know at least whether a given identifier is a macro or a local variable or what, at expansion time. So for that reason, with-slots usually takes a list of slots, explicitly: (with-slots o (a b c) (set! a 5) (set! b (1+ a)) (set! c (+ a b)) (+ a b c)) It would be possible to pass the class instead, but then the class would need to be known at compile-time, and you run into a number of issues there. Anyway, here's that with-slots definition: (define-syntax with-slots (syntax-rules () ((_ obj (slot ...) b b* ...) (let-syntax ((slot (identifier-syntax (id (slot-ref obj 'slot)) ((set! id val) (slot-set! obj 'slot val)))) ...) b b* ...)))) Here we use the new settable identifier-syntax. Note that slot-ref / slot-set isn't the most efficient way to reference slots; the best thing is to use accessors, which JIT-compile (sorta) to struct-ref opcodes, but we don't know that accessors exist for these slots. You can define a with-accessors macro though, that does assume accessors are available. In fact with more assumptions, it's possible to compile to struct-ref / struct-set yourself -- see the examples in the "Syntax" chapter of "The Scheme Programming Language" 4th edition (available online) for an illuminating take on the issue. Cheers, Andy The original definition: > (define-syntax let-alias > (syntax-rules () > ((_ ((id alias) ...) body ...) > (let-syntax ((helper (syntax-rules () > ((_ id ...) (begin body ...))))) > (helper alias ...))))) > > (define slot (make-procedure-with-setter slot-ref slot-set!)) > > (define-syntax in (syntax-rules () > ((_ object expr ...) > (primitive-eval > (list 'let-alias > (map (lambda(s)(list(car s)(list 'slot object (list > 'quote (car s))))) > (class-slots (class-of object))) > (quote expr) ...))))) > -- http://wingolog.org/