my-object
source code: https://github.com/AlexKnauth/my-object
1 Forms and Functions
syntax
(object [field-id expr] ...)
See also object-extend.
If an expr is a function, then that function can be used as a method for the object, but methods are not treated specially; they are just normal fields that happen to have functions stored in them.
Each field-id is public and immutable. Private mutable fields are also possible (see Fish example based on racket guide for objects).
syntax
(object-extend obj option ... [field-id expr] ...)
option = #:inherit (inherit-id ...) | #:super ([super-id1 super-id2] ...)
If the #:inherit option is provided, the inherit-ids are available as bindings within the exprs.
If the #:super option is provided, the super-id1s are available within the exprs, and a super-id1 refers to the super-id2 field of the super object.
procedure
(object-fields obj) → (hash/c symbol? any/c #:immutable #t)
obj : object?
syntax
(send obj-expr method-id arg ...)
(send obj-expr (identity method-expr) arg ...) (send obj-expr . field-id) send
The second form allows the method to be determined at run time, and is equivalent to (dynamic-send obj-expr method-expr arg ...).
The third form is equivalent to (obj-expr #'field-id), and is mainly provided so that send+ can use field-id as a msg.
When send is used as an identifier by itself, it expands to dynamic-send.
syntax
(send* obj-expr msg ...)
msg = (method-id arg ...) | field-id
syntax
(send+ obj-expr msg ...)
msg = (method-id arg ...) | field-id
procedure
(dynamic-send obj method arg ...) → any
obj : object? method : (or/c symbol? identifier?) arg : any/c
syntax
2 Examples
2.1 Posn example based on racket guide for structs
This is based on the examples from Programmer-Defined Datatypes.
> (require my-object)
> (define p (object [x 1] [y 2]))
> p (object [x 1] [y 2])
> (object? p) #t
> (p 'x) ; by the way, you can use #'x here instead of 'x 1
> (p 'y) 2
> (define p2 (p 'x #:-> 3))
> p2 (object [x 3] [y 2])
> (define (posn x0 y0) (object [x x0] [y y0] [add (λ (p) (posn (+ x (p 'x)) (+ y (p 'y))))] [->list (λ () (list x y))]))
> (define p3 (send (posn 1 2) add (posn 3 4)))
> (send p3 ->list) '(4 6)
> (define p3 (posn 1 2))
> (define p4 (object-extend p3 [x 3])) ; or (p3 'x #:-> 3)
> (send p4 ->list) '(3 2)
> (define (3d-posn x0 y0 z0) (object-extend (posn x0 y0) #:inherit (x y) [z z0] [add (λ (p) (3d-posn (+ x (p 'x)) (+ y (p 'y)) (+ z (p 'z))))] [->list (λ () (list x y z))]))
> (3d-posn 1 2 3) (object [x 1] [y 2] [add #<procedure>] [->list #<procedure>] [z 3])
2.2 Fish example based on racket guide for objects
This is based on the examples from Classes and Objects.
> (require my-object)
> (define (make-fish sz) (define size sz) ; private mutable field (object [get-size (λ () size)] [grow (λ (amt) (set! size (+ amt size)))] [eat (λ (other-fish) (grow (send other-fish get-size)))]))
> (define charlie (make-fish 10))
> (send charlie get-size) 10
> (send charlie grow 6)
> (send charlie get-size) 16
> (define (make-hungry-fish sz) (object-extend (make-fish sz) #:inherit (eat) [eat-more (λ (fish1 fish2) (eat fish1) (eat fish2))]))
> (send (make-hungry-fish 32) get-size) 32
> (define (make-picky-fish sz) (object-extend (make-fish sz) #:super ([super-grow grow]) [grow (λ (amt) (super-grow (* 3/4 amt)))]))
> (define daisy (make-picky-fish 20))
> (send daisy eat charlie)
> (send daisy get-size) 32