On 01/23/2013 08:57 AM, Lewis wrote:
I'd always found prototype object systems interesting, and thought
they might be a good fit for racket - so I made one about a month or
so ago

Features:
- Prototype based, no distinction between classes and instances.
- Multiple inheritance, methods are looked up in depth first search
- Declarative syntax, can create an object with a single macro, no need to clone
and mutate
- Immutable objects, which can be inherited by and inherit from mutable ones

https://gist.github.com/4605785  - go to line 195 shows its usage.

Basically, I am after feedback on my code, the concept in general, and
anything really. I actually use it over the  java-style class object
system racket has, it's very much my vision of what objects should be
like. But yes, any feedback would be welcome.

It looks good. Here are a couple comments:

You use 'syntax-local-introduce' and 'syntax-local-get-shadower' to bind 'self', whereas it would be simpler to use syntax-parameters. Look at "Keeping it Clean with Syntax Parameters". (You are already avoiding many of the problems of other unhygienic approaches by using 'syntax-local-get-shadower'... but syntax parameters put a nicer interface on it.)

Your struct definition for 'immutable-object' isn't used anywhere, so perhaps it's leftover from previous experiments code, but its declaration of a 'parents' field doesn't change the inherited field 'parents' from being mutable to immutable; it just adds another one. AFAIK, there's no simple way to have immutable and mutable variants of a struct type where immutability is enforced by Racket without some kind of indirection. By indirection I mean something like the hash: you use mutable hashes for mutable objects and immutable hashes for immutable objects. But it's harder for the parents fields. In the past when I've hit this problem I've just defined two variants and handled them separately (possibly with a super-struct with some shared fields), but I'm not thrilled with that solution either.

Finally, it looks like your lookup operation (the prop:procedure handler and the 'lookup' helper) don't distinguish between "I found the key (msg), and its value is null" and "I didn't find the key". And the recomputation of (p msg) in 'lookup' looks like it could make getting a property take time exponential in the length of the parent chain to the property.

Ryan

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to