[gambit-list] New types

Eduardo Cavazos wayo.cavazos at gmail.com
Thu Feb 10 21:58:02 EST 2005


Thanks for the suggestion Marc. I think this will work perfectly.

Here is the reason that I'd like to stick with the procedural
representation instead of using Gambit structures directly.

(define-structure point x y)

(define-structure airplane pos vel)

(define a (make-airplane (make-point 10 10) (make-point 0 0)))

;; Accessing the x coordinate of the airplane:

(point-x (airplane-pos a))

;; In an object system like the one I made it's much shorter:

[[a pos:] x:]

Getting at an object inside an object inside an object... in a
struct/record system that typically accompanies Scheme implementations
can be a pain in that it's so verbose. Even in C all you have to write
is the name of the variable and the name of the field (plus the dot or
arrow).

"Different things should look different". By convention I use brackets
whenever accessing or setting a field in an object. To set the value
of x in the airplane above it would look like this:

[[a pos:] x: 5]

As opposed to this:

(point-x-set! (airplane-pos a) 5)

Structs in Xlib have pretty verbose names. It's nice to say this:

[attr border_pixmap:]

Instead of this:

(XSetWindowAttributes-border_pixmap attr)

I can think of more examples, but anyone that has programmed large
Scheme projects surely knows this pain.

In Gambit we have two styles of keywords. foo: and :foo. I use the
post-colon keywords to denote fields. As another convention, I
considered using pre-colon keywords to denote methods.

Eduardo Cavazos

On Tue, 8 Feb 2005 16:11:31 -0500, Marc Feeley <feeley at iro.umontreal.ca> wrote:
> > Is there a way to create new primitive types in Gambit? I'm using 3.0
> > but I'm interested in answers regarding either version.
>
> In 3.0 and 4.0 you can use define-structure:
>
>   Gambit Version 3.0
>
>   > (define-structure foo a b)
>   > (define x (make-foo 11 22))
>   > x
>   #s(foo (a 11) (b 22))
>   > (foo? x)
>   #t
>   > (foo? car)
>   #f
>   > (vector? x)
>   #f
>
> If you really want to keep your procedural representation, you can
> access a procedure's "code" pointer to distinguish closures created
> from one lambda from closures created from another lambda.  Here's some
> sample code:
>
> (define eq-procedure-code? ; this handles compiled and interpreted code
>   (lambda (proc1 proc2)
>     (if (##closure? proc1)
>         (and (##closure? proc2)
>              (if (##interp-procedure? proc1)
>                  (and (##interp-procedure? proc2)
>                       (eq? (##interp-procedure-code proc1)
>                            (##interp-procedure-code proc2)))
>                  (eq? (##closure-code proc1)
>                       (##closure-code proc2))))
>         (eq? proc1 proc2))))
>
> (define make-adder
>   (lambda (x)
>     (lambda (y)
>       (+ x y))))
>
> (define make-multiplier
>   (lambda (x)
>     (lambda (y)
>       (* x y))))
>
> (define f (make-adder 1))
> (define g (make-adder 2))
> (define h (make-multiplier 3))
>
> (pp (eq-procedure-code? f car))  ; => #f
> (pp (eq-procedure-code? f g))    ; => #t
> (pp (eq-procedure-code? g h))    ; => #f
>
>
> Marc Feeley
>


More information about the Gambit-list mailing list