From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Michael Tiedtke Newsgroups: gmane.lisp.guile.user Subject: Message Passing with GOOPS Date: Wed, 24 Jun 2015 22:21:44 +0200 Message-ID: <558B1158.4020607@o2online.de> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="------------020106080303000900030309" X-Trace: ger.gmane.org 1435177383 14622 80.91.229.3 (24 Jun 2015 20:23:03 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 24 Jun 2015 20:23:03 +0000 (UTC) To: "guile-user@gnu.org" Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Wed Jun 24 22:22:53 2015 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Z7rC6-0002Ix-LJ for guile-user@m.gmane.org; Wed, 24 Jun 2015 22:22:50 +0200 Original-Received: from localhost ([::1]:52792 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z7rC5-0002vF-Us for guile-user@m.gmane.org; Wed, 24 Jun 2015 16:22:49 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:46957) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z7rBO-0002Cg-M4 for guile-user@gnu.org; Wed, 24 Jun 2015 16:22:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z7rBK-0003V3-PB for guile-user@gnu.org; Wed, 24 Jun 2015 16:22:06 -0400 Original-Received: from mail230c50.megamailservers.eu ([91.136.10.240]:47838 helo=mail37c50.megamailservers.eu) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z7rBK-0003Tp-G4 for guile-user@gnu.org; Wed, 24 Jun 2015 16:22:02 -0400 X-Authenticated-User: michele.titke.o2online.de Original-Received: from [10.144.174.47] ([89.204.130.47]) (authenticated bits=0) by mail37c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id t5OKLlqB006494 for ; Wed, 24 Jun 2015 20:21:50 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 X-CTCH-RefID: str=0001.0A020204.558B1160.01BB, ss=2, re=0.000, recu=0.000, reip=0.000, cl=2, cld=1, fgs=64 X-CTCH-VOD: Unknown X-CTCH-Spam: Suspect X-CTCH-Score: 0.000 X-CTCH-Rules: X-CTCH-Flags: 64 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.1 cv=QppngzCd c=1 sm=1 tr=0 a=rLTKjjJC1nbT8x/vFU/mqA==:117 a=rLTKjjJC1nbT8x/vFU/mqA==:17 a=FurB0epzNeMA:10 a=r77TgQKjGQsHNAKrUKIA:9 a=9iDbn-4jx3cA:10 a=cKsnjEOsciEA:10 a=gZbpxnkM3yUA:10 a=-uLmB9QamyF4LYbXswQA:9 a=3DjhYGCAtNoq7LnX:21 a=PwryuBZzGugr-MZL:21 a=QEXdDO2ut3YA:10 a=eFZHuoB0h9mSmEppD4wA:9 a=bpOrj_swhx_3rxb-:21 a=_W_S_7VecoQA:10 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 91.136.10.240 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:11864 Archived-At: This is a multi-part message in MIME format. --------------020106080303000900030309 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit (use-modules (oop goops)) GOOPS has some nice features (you can even use unexported methods with generics in 1.8) but there is no message passing paradigm. Objective-C has /tell/ Racket has /send/ but Guile/GOOPS is missing /call/. This is a first "raw" definition where the parameter /message/ has to be a quoted symbol. (define-method (call (receiver ) message . arguments) (apply (slot-ref receiver message) arguments)) The class definition still looks like traditional GOOPS but it works. An example: (define-class () (msg #:init-value (lambda () 'hello-world))) (define r (make )) (call r 'msg) => 'hello-world Now I'd like to have an easier syntax for describing the slot. The definition might be: (define-syntax define-message (syntax-rules () ((_ (message-name arguments ... ) body ...) (message-name #:init-value (lambda (arguments ...) body ...))))) But the following example doesn't work in 1.8: (define-class () (define-message (phone n) (repeat n (lambda () (bell) 'rang)) )) GOOPS complains about malformed slots and *seems* to see the unexpanded form.* I could use a little help here, anyone?* Even for the naming scheme: /send/ is already used by unix sockets and methods are part of the implementation of generics. Perhaps /message/ isn't that bad. The missing symbols from my pretext: (define (natural-number? n) (and (exact? n) (integer? n) ; 'integer?' does not check for exactness ... (> n 0))) (define-public (repeat n closure) "Execute closure n times." (if (not (or (natural-number? n) (= n 0))) (error "repeat: the parameter n must be an exact natural number or zero.") (let loop ((i 0)) (if (< i n) (begin (closure) (loop (1+ i)))) ))) From my pretext.rkt (define-syntax *broadcast* (syntax-rules () ((_ object-list method ...) (map {lambda (object) (send object method ...)} object-list)))) (define-syntax *broadcast** (syntax-rules () ((_ object-list method ...) (map {lambda (object) (send* object method ...)} object-list)))) (define-syntax *define/on-delegate* (syntax-rules () ((_ delegate-object (method-name ...)) (define (method-name ...) (send delegate-object method-name ...)) ))) PS Perhaps it's better to recreate a clean object model without 3,000 lines of C code like GOOPS. But then GOOPS really creates the illusion of an object oriented environment with a MOP ... --------------020106080303000900030309 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mail37c50.megamailservers.eu id t5OKLlqB006494 (use-modules (oop goops))

GOOPS has some nice features (you can even use unexported methods with generics in 1.8) but there is no message passing paradigm. Objective-C has tell Racket has send but Guile/GOOPS is missing call.

This is a first "raw" definition where the parameter message has to be a quoted symbol.

(define-method (call (receiver <object>) message . arguments) =C2=A0 (apply (slot-ref receiver message) arguments))


The class definition still looks like traditional GOOPS but it works.

An example:

(define-class <receiver> ()
=C2=A0 (msg #:init-value (lambda () 'hello-world)))

(define r (make <receiver>))
(call r 'msg) =3D> 'hello-world


Now I'd like to have an easier syntax for describing the slot. The definition might be:

(define-syntax define-message
=C2=A0 (syntax-rules ()
=C2=A0=C2=A0=C2=A0 ((_ (message-name arguments ... ) body ...)
=C2=A0=C2=A0=C2=A0=C2=A0 (message-name #:init-value (lambda (argument= s ...) body ...)))))

But the following example doesn't work in 1.8:

(define-class <house> ()
=C2=A0 (define-message (phone n)
=C2=A0=C2=A0=C2=A0 (repeat n (lambda () (bell) 'rang)) ))

GOOPS complains about malformed slots and seems to see the unexpanded form.
I could use a little help here, anyone?
Even for the naming scheme: send is already used by unix sockets and methods are part of the implementation of generics. Perhaps message isn't that bad.


The missing symbols from my pretext:

(define (natural-number? n)
=C2=A0 (and (exact? n)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (integer? n)=C2=A0 ; 'integer?' = does not check for exactness ...
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (> n 0)))

(define-public (repeat n closure)
=C2=A0 "Execute closure n times."
=C2=A0 (if (not (or (natural-number? n) (=3D n 0)))
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (error "repeat: the parameter n must b= e an exact natural number or zero.")
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (let loop ((i 0))
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (if (< i n)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (begin
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (c= losure)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (l= oop (1+ i)))) )))


From my pretext.rkt

(define-syntax broadcast
=C2=A0 (syntax-rules ()
=C2=A0=C2=A0=C2=A0 ((_ object-list method ...)
=C2=A0=C2=A0=C2=A0=C2=A0 (map {lambda (object) (send object method ..= .)}
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 object-list)))= )
(define-syntax broadcast*
=C2=A0 (syntax-rules ()
=C2=A0=C2=A0=C2=A0 ((_ object-list method ...)
=C2=A0=C2=A0=C2=A0=C2=A0 (map {lambda (object) (send* object method .= ..)}
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 object-list)))= )

(define-syntax define/on-delegate
=C2=A0 (syntax-rules ()
=C2=A0=C2=A0=C2=A0 ((_ delegate-object (method-name ...))
=C2=A0=C2=A0=C2=A0=C2=A0 (define (method-name ...)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (send delegate-object method-nam= e ...)) )))


PS
Perhaps it's better to recreate a clean object model without 3,000 lines of C code like GOOPS. But then GOOPS really creates the illusion of an object oriented environment with a MOP ...

--------------020106080303000900030309--