guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Closure?


From: Kjetil S. Matheussen
Subject: Re: Closure?
Date: Mon, 14 Jul 2008 18:30:47 +0200 (CEST)


"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 <bank>
   (def-var sum 0)
   (def-method (add n)
      (set! sum (+ n sum)))

(define bank (new <bank>))
(-> 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.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]