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.
My simple object system builds 'objects' out of procedures with local state. E.g.:
(let ((x 10) (y 20)) (lambda args ...))
The (classic?) problem here is that my 'objects' don't look different from procedures. If I know that I'm dealing with one of my objects, I can ask it what it it is. But if I'm dealing with something that can be any Scheme type, I can ask if it's a procedure, but then I can't tell if it's one of my objects or a proc...
I need a way to have a 'new' procedure type. A type of primitive item that acts just like a procedure but answers #f to the 'procedure?' predicate.
I guess I am abusing procedures with this style of object system. But I'm hacking so it's OK. ;-)
Ed
Afficher les réponses par date
On Sat, 5 Feb 2005 05:24:37 -0600, Eduardo Cavazos wayo.cavazos@gmail.com wrote:
My simple object system builds 'objects' out of procedures with local state.
This is a standard approach to OOP in Scheme. Most people build one of these at some point :)
The (classic?) problem here is that my 'objects' don't look different from procedures. ...I need a way to have a 'new' procedure type. A type of primitive item that acts just like a procedure but answers #f to the 'procedure?' predicate.
A lot depends on what space/speed tradeoffs you want to make. Redefining procedure? is an option that can work, but it will be expensive, especially if you use many objects.
I guess I am abusing procedures with this style of object system.
Not at all, but you should ask yourself why you need objects at all. Really. There is an important revelation about types that lies at the bottom of the object/procedure duality.
david rush
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