This document lays out the tentative development plan for Protolk. It will be updated as development progresses and the plan evolves.
- [X]
pob
record type - [X]
%make-pob
procedure - [X]
pob?
procedure - [X]
%pob-props
/%pob-set-props!
procedures - [X]
%pob-methods
/%pob-set-methods!
procedures
Props:
- [X]
%has-prop?
procedure - [X]
%prop
procedure - [X]
%set-prop!
procedure - [X]
%unset-prop!
procedure
Methods:
- [X]
%has-method?
procedure - [X]
%method
procedure - [X]
%set-method!
procedure - [X]
%unset-method!
procedure
- [X]
make-pob
procedure (with keyword args) - [X]
send
procedure - [X]
prop-reader
procedure factory - [X]
prop-writer
procedure factory
stdpob
predefined pob:
- [X]
[stdpob derive #!key props methods]
- [X]
[stdpob ancestors]
- [X]
[stdpob has-ancestor?]
- [X]
[stdpob _resolve-prop name #!optional default]
- [X]
[stdpob _resolve-method name #!optional default]
- [X]
[stdpob _method-missing name args]
- [X]
[stdpob _receive message args]
- [X]
[stdpob responds-to? message #!optional args]
- [X]
[stdpob _display port]
Make stdpob methods available as procedures, e.g. stdpob-derive
,
stdpob-_resolve-prop
.
Misc:
- [X] pob record printer invokes
_display
method - [X] Egg install
- [X] setup file
- [X] meta file
- [X] tests/run.scm
- [X] documentation page
The API of Milestone 2 is overly flexible, and the internals overly complex. The goal of this milestone is to simplify the system, focusing on realistic use cases and useful flexibility, not flexibility for its own sake.
- [X] Prototypal inheritance is a fundamental characteristic of pobs,
so the
base
should be stored as a slot in the pob, rather than as a prop. - [X] The abilities to resolve props and methods are inherent to all pobs, so these procedures should be stored as slots in the pob, required in every pob.
- [X] Prop and method resolver procedures should be copied from the base pob when the pob is derived.
- [X] Extensive refactoring and cleanup.
- [X]
%method-context
parameter primitive - [X]
%active-pob
procedure. Read-only equivalent to(car (%method-context))
. - [X]
own-prop
procedure and setter - [X]
assert-active-pob
procedure. Raises unless the given pob is equal to (%active-pob). - [X]
define-private-method
macro - [X]
in-method
macro - [X]
define-method
macro - [X]
super
macro - [X]
super*
macro. Like super, but passes the same args the current method received. - [X]
super?
procedure - [X]
apply-super
macro
Demos:
- [X] Basics
- Deriving from stdpob
- Overriding stdpob props and methods
- Adding custom props and methods
- [X] Emulating classical inheritance
- [X]
send
syntax:[pob msg args...]
- [X]
own-prop
syntax:@foo
- [X] Update demos
Revamping the core model based on lessons learned and new ideas. Possible directions include:
- Shift responsibility for method/super context setup from the method
body to the object’s
_receive
method. This would probably simplify the definition of methods, and might simplify the implementation of method/super contexts. - Shift responsibility for privacy enforcement from the method body to
the object’s
_receive
method. This would allow the same lambda to be used as either a private or public method, and allow objects to define their own rules for privacy. - For stdpob, maybe use method names to determine privacy. Methods starting with a some character (maybe “_”) are private, others are public. (Or, just store a list of names of private methods. Boring!)
Miscellaneous other stuff:
- [X] Re-export the
pob?
procedure from the protolk module, not just the protolk-primitives module. - [ ] Make std-_display print out the pob’s props. Use a depth limit like Ruby’s default inspect.
- [X] Rename
assert-active-pob
toassert-is-receiver
- [X] Change references to “active pob” to “receiver”.
- [X]
is-receiver?
Returns #t if given pob is the current receiver. - [X] Redefine prop-reader and prop-writer in terms of own-prop.
- [X]
define-prop-readers
Define prop readers on a pob for the given prop names. - [X]
define-prop-writers
Define prop writers on a pob for the given prop names. - [X]
define-prop-accessors
Define prop readers and writers on a pob for the given prop names. - [X]
set-method!
Replace a method in the pob. Like define-method, but you can use an already existing procedure. - [X]
unset-own-prop!
Remove the prop from the pob, so it inherits from its base again. - [X]
set-base!
Set the pob’s base to a new pob (or #f). - [X] Add checks for cyclic ancestry when changing a pob’s base.
Define pob wrappers around existing types. These would provide a pob-ish interface to the wrapped values. E.g. [(pob-wrap-string “12345”) length] is 5.
- [ ] wrapper (ancestor of all wrapper pobs; derived from stdpob)
- equality operators
- type predicates
- etc.
- [ ] hash-table
- [ ] vector
- [ ] list / pair
- [ ] number
- [ ] string
- [ ] char
- [ ] regex
- [ ] port
- others?
- [ ] Function to wrap the given value in an appropriate pob (determined using an alist of predicates). Extensible so users can add new wrappers.
- [ ] Automatically wrap non-pob values when they are passed to
send
, then send the message to the pob.
- [ ] Update
std-method-resolver
to support method aliases. If the value of a method is a symbol (instead of a procedure), begin resolving the indicated method instead, beginning at the pob where the alias was found. (But, the error from method-missing should still indicate the originally requested method name.) - [ ]
define-alias
procedure - [ ] Multiple inheritance (multiple bases). Use a precedence list to determine inheritance and “super” calls.
- [ ] Make primitive prop and method lookups work with hash-tables (or some other efficient data structure) as well as alists, for efficiency when a pob has a large number of props or methods. (Test that this would actually be more efficient.)
- [ ] Ability to automatically convert pob prop and method alists into hash tables (or whatever) when they reach a certain size.
- [ ] Cache lookups of inherited methods. Invalidate cache when ancestor changes.