From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Kjetil S. Matheussen" Newsgroups: gmane.lisp.guile.user Subject: Re: Closure? Date: Mon, 14 Jul 2008 18:30:47 +0200 (CEST) Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7BIT X-Trace: ger.gmane.org 1216053210 23933 80.91.229.12 (14 Jul 2008 16:33:30 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 14 Jul 2008 16:33:30 +0000 (UTC) To: guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Mon Jul 14 18:34:17 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 1KIQzX-00065L-HZ for guile-user@m.gmane.org; Mon, 14 Jul 2008 18:33:35 +0200 Original-Received: from localhost ([127.0.0.1]:42980 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KIQyf-0000BP-Ba for guile-user@m.gmane.org; Mon, 14 Jul 2008 12:32:41 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KIQyb-0000Ax-8s for guile-user@gnu.org; Mon, 14 Jul 2008 12:32:37 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KIQya-0000AL-9f for guile-user@gnu.org; Mon, 14 Jul 2008 12:32:36 -0400 Original-Received: from [199.232.76.173] (port=49407 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KIQya-0000AI-3o for guile-user@gnu.org; Mon, 14 Jul 2008 12:32:36 -0400 Original-Received: from smtp.getmail.no ([84.208.20.33]:57805) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KIQyZ-0001yN-Pw for guile-user@gnu.org; Mon, 14 Jul 2008 12:32:36 -0400 Original-Received: from pmxchannel-daemon.no-osl-m323-srv-004-z2.isp.get.no by no-osl-m323-srv-004-z2.isp.get.no (Sun Java System Messaging Server 6.2-7.05 (built Sep 5 2006)) id <0K4000M078LSDU00@no-osl-m323-srv-004-z2.isp.get.no> for guile-user@gnu.org; Mon, 14 Jul 2008 18:32:16 +0200 (CEST) Original-Received: from smtp.getmail.no ([10.5.16.1]) by no-osl-m323-srv-004-z2.isp.get.no (Sun Java System Messaging Server 6.2-7.05 (built Sep 5 2006)) with ESMTP id <0K4000DR38JFG020@no-osl-m323-srv-004-z2.isp.get.no> for guile-user@gnu.org; Mon, 14 Jul 2008 18:30:51 +0200 (CEST) Original-Received: from cm-84.215.136.96.getinternet.no ([84.215.136.96]) by no-osl-m323-srv-009-z1.isp.get.no (Sun Java System Messaging Server 6.2-7.05 (built Sep 5 2006)) with ESMTP id <0K4000EO58JFPA30@no-osl-m323-srv-009-z1.isp.get.no> for guile-user@gnu.org; Mon, 14 Jul 2008 18:30:51 +0200 (CEST) In-reply-to: X-X-Sender: kjetil@ttleush X-detected-kernel: by monty-python.gnu.org: Solaris 10 (beta) 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:6656 Archived-At: "Maciek Godek" >> I don't know exactly how it works out that using a define in >> local-eval falls foul of the define placement rule, but it is not hard >> to imagine that it could do. > > The other question is: is it really necessary to impose such > limitations on "define". Why is it required to make its position > inside let privileged? > The scheme standard is a bit pedantic. The above I would write like this: (let () (define a) (display a) (newline) (let () (define b 2) (+ a b))) >>> Yes, since there's local-eval and the-environment, everything I've >>> ever dreamed of is possible :) >>> But as I've concluded from the discourse, neither of these is >>> defined in R5RS (and it makes me wonder) >> >> Well I've never thought this through before, but perhaps that is >> because in many cases it is equivalent to create a lambda at the point >> where you would call the-environment, containing the code that you >> would later pass to local-eval. >> >> For example, the ++ example then becomes: >> >> (define ++ (let ((c 0)) (lambda () (begin (set! c (+ c 1)) c)))) >> >> - which is the traditional way of writing this example. > > You didn't focus :> > The whole idea of accessing a closure environment > was in fact to make scheme object oriented > programming more intuitive. > > In guile info pages there's an oo closure example: > > (section 3.1.4.9 "Example 4: Object Orientation") > " > (define (make-account) > (let ((balance 0)) > (define (get-balance) > balance) > (define (deposit amount) > (set! balance (+ balance amount)) > balance) > (define (withdraw amount) > (deposit (- amount))) > > (lambda args > (apply > (case (car args) > ((get-balance) get-balance) > ((deposit) deposit) > ((withdraw) withdraw) > (else (error "Invalid method!"))) > (cdr args))))) > > (define my-account (make-account)) > " > Notice the ugly "case" statement that requires > the variables to be accessed in the following manner > (the same example, a few lines later): > " > (my-account 'get-balance) > => > 0 > > (my-account 'withdraw 5) > => > -5 > > (my-account 'deposit 396) > => > 391 > > (my-account 'get-balance) > => > 391 > " > > This is ugly as it requires doubling the names of functions. > Perhaps it could be overcome with some sort of macro, > but the "with" I proposed allows to avoid the whole "case" > and to write (after slight modifications in the "let" form): > > (with my-account (get-balance)) > > Or maybe I think wrong; I'm new in the world of lisp, > so please forgive me my mistakes :) > I think local-eval is necessary for making a namespace system of the below type without having to use codewalking macros to expand the bodies of functions: (define-namespace bank) (def-bank sum 0) (def-bank (add n) (set! sum (+ n sum)) ;; Note that it's enough to write "sum". (bank.add 50) bank.sum => 50 But for implementing a message passing OO system, it's easier to use macros and hash tables, plus that it probably performs much better: (def-class (def-var sum 0) (def-method (add n) (set! sum (+ n sum))) (define bank (new )) (-> bank add 50) (-> bank sum) => 50 There's a bunch of these systems for scheme. The syntax above is used from http://snd.cvs.sourceforge.net/snd/cvs-snd/oo.scm?view=log Guile's own OO system called GOOPS is also very nice. GOOPS a quite verbose but very powerful and a lot more interactive. It's similar to CL's CLOS, which you should look at if you are not familiar with already.