From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Panicz Maciej Godek" Newsgroups: gmane.lisp.guile.user Subject: Re: Simplified slot access in goops Date: Tue, 2 Dec 2008 20:30:11 +0100 Message-ID: <1eb53f5d0812021130u5b41964pa20464a35ce67715@mail.gmail.com> References: <49dd78620812011425k2720df81tbf3820b429ba7ba@mail.gmail.com> <87ljuyylav.fsf@unknownlamer.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1228246242 29717 80.91.229.12 (2 Dec 2008 19:30:42 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 2 Dec 2008 19:30:42 +0000 (UTC) Cc: guile-user@gnu.org, Neil Jerram To: "Clinton Ebadi" Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Tue Dec 02 20:31:44 2008 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1L7ay6-00089r-6G for guile-user@m.gmane.org; Tue, 02 Dec 2008 20:31:34 +0100 Original-Received: from localhost ([127.0.0.1]:38463 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L7awv-0007ql-F3 for guile-user@m.gmane.org; Tue, 02 Dec 2008 14:30:21 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L7awo-0007qA-PT for guile-user@gnu.org; Tue, 02 Dec 2008 14:30:14 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L7awo-0007pn-36 for guile-user@gnu.org; Tue, 02 Dec 2008 14:30:14 -0500 Original-Received: from [199.232.76.173] (port=46371 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L7awo-0007pk-09 for guile-user@gnu.org; Tue, 02 Dec 2008 14:30:14 -0500 Original-Received: from yw-out-1718.google.com ([74.125.46.152]:39844) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1L7awn-0000Eu-Kf for guile-user@gnu.org; Tue, 02 Dec 2008 14:30:13 -0500 Original-Received: by yw-out-1718.google.com with SMTP id 9so2812907ywk.66 for ; Tue, 02 Dec 2008 11:30:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:cc:in-reply-to:mime-version:content-type :content-transfer-encoding:content-disposition:references; bh=zsauuCFM/ECTuy4QOMhoU6q1hfq+4l5y+Gs2bm1FopM=; b=nbI+GsFikJd8WUIRUrHa0qVXx9Py3CphPnORYtyyxkbn1vrgBflfUYPfbceX2ytqHM nKjZySykqHt51b5hZZ175tDBZ8fs7w02bG/Anb8ThXT501wrt/SGHk/e3cc5ALBpi7mP dtvPuf9P456OfDOmo6WRfYxfAz+1OjGD9j+wY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:cc:in-reply-to:mime-version :content-type:content-transfer-encoding:content-disposition :references; b=OjYijo6uKYkKQ9ktpBerSYpnAh1ofd+IR3aTqJ3nMNkrwTMUnrAH0o4JV+En3GE3FT yw9Q+jplrSM2RD7wqJz59tIFiCJZHI6W11ZO8Pznw5YKttHvkEuBD00jHSF/9S+bvAnX 4vc8TX+tN4bg3gPSC1GqMPRwoX3/9Cq1mZJAk= Original-Received: by 10.142.207.8 with SMTP id e8mr5001393wfg.198.1228246211937; Tue, 02 Dec 2008 11:30:11 -0800 (PST) Original-Received: by 10.142.141.9 with HTTP; Tue, 2 Dec 2008 11:30:11 -0800 (PST) In-Reply-To: <87ljuyylav.fsf@unknownlamer.org> Content-Disposition: inline X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:6989 Archived-At: Neil wtote: >> I think this is a nice interface; but I'm less sure about the >> implementation. Why do you need to use primitive-eval at all? >> >> Isn't CL's with-slots a bit like this? It might help to look at how >> that is implemented. Well, I've been having similar doubts, so I came up with something which turned out to be similar to CLOS's with-slots. The previous solution indeed required primitive-eval (or something similar), because it wasn't just a syntax transformation -- that is, it invoked the class-slots and class-of functions The workaround requires the user to enumerate all the slots that he or she is going to access. I wrote two macros, so you can write (continuing the example from the previous letter): (with-object-slots (o a b c) (set! a 5) (set! b (* a a)) (set! c (+ a b)) (list a b c)) => (2 25 30) you don't have to use the original slot names; you can also use the `with-object-slots' macro supplying aliases: (with-object-slots (o (x a) (y b) (z c)) (set! x (+ y z)) (list x y z)) => (55 25 30) the only problem is that you can't mix both ways, ie. ! (with-object-slots (o a (y b)) (+ a y)) would be incorrect (it is possible to implement such a macro, but for now this one should suffice). It's still ok to write (with-object-slots (o (a a) (y b)) (+ a y)) => 80 The second macro, let-slots allows to make aliases for slots of more than one object, for instance: (define p (make C)) (let-slots ((o a b c) (p (pa a) (pb b) (pc c))) (set! a 5) (set! pa a) (+ pa a)) Everything should work just fine. The implementation is based solely on R5RS macro system and the make-procedure-with-setter, that is afaik specific to guile Clinton wrote: > with-slots uses symbol-macrolet[0] to bind each of the variable names to > symbol macros within its body. I don't know of anything in Guile that is > equivalent. R5RS pattern language allows to create syntactic aliases for practically any form. Some time ago I've found the following `let-alias' macro that does just this: (use-syntax (ice-9 syncase)) (define-syntax let-alias (syntax-rules () ((_ ((id alias) ...) body ...) (let-syntax ((helper (syntax-rules () ((_ id ...) (begin body ...))))) (helper alias ...))))) ;; And here's the code for the aforementioned with-object-slots and let-slots: (use-modules (oop goops)) (define slot-ref (make-procedure-with-setter slot-ref slot-set!)) (define-syntax with-object-slots (syntax-rules () ((_ (object (alias1 slot1) ...) expr1 ...) (let-alias ((alias1 (slot-ref object (quote slot1))) ...) expr1 ...)) ((_ (object prop1 ...) expr1 ...) (let-alias ((prop1 (slot-ref object (quote prop1))) ...) expr1 ...)))) (define-syntax let-slots (syntax-rules () ((_ () expr1 ...) (begin expr1 ...)) ((_ (binding1 binding2 ...) expr1 ...) (with-object-slots binding1 (let-slots (binding2 ...) expr1 ...))))) It is also possible to define the `with-slots' macro exactly as it is in CLOS (but I think let-slots is fine) Cheers M.