Sheeple is a Dynamic, CLOS-like Prototype-based Object-Oriented Programming Framework (or "POOP Framework") that strives to maximize application flexibility, minimize cost while maximizing value, optimize programmer time, and empower application implementers to better assist them leveraging modern paradigms in order to proactively achieve next-gen synergy in tomorrow's web 3.0 world. It is implemented in (mostly) ANSI Common Lisp. Sheeple is fully buzzword compliant.
Initially written as the object system of a text-based game online game engine (Sykosomatic), Sheeple is provided as a module separate from its persistent counterpart, Persistent-Sheeple, as a standalone library for use with any regular Lisp application.
Following the implementation of Sheeple's Metasheep Protocol, Persistent-Sheeple is being rewritten to take full advantage of the protocol, allowing parallel operation of regular sheeple with psheep.
Sheeple is inspired by a number of Object-Oriented systems, mainly:
- Common Lisp Object System (CLOS)
- LPC, a common language for building MUDs
- MOO, implemented and used by LambdaMOO
- Slate, a Smalltalk-like language with Prototype Multiple Dispatch that Sheeple bases its message dispatch system on.
It was written with the purpose of providing a lot of the goodies of CLOS programming in a completely prototype-based environment. As such, it shares a lot of features (and syntax) with CLOS. The most notable features are multiple inheritance and multimethods (called multimessages).
This README contains a basic usage guide, and sort-of-spec of Sheeple. Much heavier documentation, including a tutorial and a MSP spec is to come. Meanwhile, have fun reading the code (hohoho). (You can also contact me directly, using zkat located-at sykosomatic no-spam-dot org)
^this implementation makes use of trivial-garbage for weak-pointers, finalizers, and weak-hash-tables. The current version also only supports SBCL.
While portability is one of the goals for Sheeple, only SBCL is officially supported right now. You are free to test it on other platforms and send patches in if you're interested in using it on that. The code itself is mostly portable, so getting SBCL to run on most major platforms should be a matter of patching up the holes that are left to make it more agreeable with other compilers.
It's fairly effortless to get Sheeple working. To get started, simply
(asdf:oos 'asdf:load-op 'sheeple) (in-package sheeple-user)
And mess around from there. Be aware that if your implementation does not include ASDF, you will have to acquire it and load it yourself. Clisp, for example, will require this. For information on how to do this, check out Cliki, or the ASDF Homepage.
Sheeple should work on most Lisp implementations, although it's mainly written and tested in SBCL on Linux x86.
FiveAM is required if you wish to run the test suite. To run it:
(asdf:oos 'asdf:load-op 'sheeple-tests) (sheeple-tests:sheeple-tests)
And watch the tests roll by. Only one should fail (CLOS Fleecing)
If you want to get Sheeple to run on your favorite platform, feel free to e-mail me: zkat . sykosomatic dot org, I'll help as much as I can (or even do the work for you). Any and all comments are also greatly appreciated.
Because of a combination of the necessity to avoid name collisions in a system very similar to CLOS and a desire to amuse myself (and others), Sheeple has been designed from the beginning to be maximally groan-worthy with its naming scheme. I apologize in advance, and I am not responsible for any issues the naming scheme might cause, such as Chronic Smug Weenie Nose-Tilting Syndrome.
I assure you, Sheeple is Serious Business(tm) for Serious Applications(tm).
Simple, but powerful defclass-like CLONE macro, with cloning options.
Dynamic object management tools (inspection of objects, addition/removal of properties, all without any sort of redefinition).
Dynamic property value access, following a prototype chain (the value of the nearest parent that set the value for a particular property is used if the child did not set one).
Full integration with built-in Lisp types (wolves) by transparent autoboxing (called fleecing).
Multiple inheritance through cloning with dynamic inspection and management (adding/removing) of parents.
Multiple dispatch on messages (methods) -- messages specialize on specific instances, and follow inheritance hierarchy. Multimessage definition is almost identical to CLOS methods, and shares similar semantics.
Dynamic removal of messages, as well as entire buzzwords with undefbuzzword/undefmessage.
Auto-generated readers/writers, with :manipulator, :reader, and :writer property options.
:before, :after, and :around messages
(call-next-message) and (next-message-p)
A sheep creation and property-access Metaobject Protocol, with a larger MOP in development.
Planned features that have not yet been implemented include:
CLOS integration, including autoboxing of entire class hierarchies.
Support more than just SBCL
Please refer to doc/user-guide for a quick-and-dirty intro to Sheeple and how to use it.
If you're extra-patient, you can wait for me to write a full-fledged user guide (slated for completion by the time 1.0 gets pooped out).
Again, you can always contact me directly with questions. I also regularly lurk in the #lisp channel on Freenode (as zkat).
When I started volunteering in a MUD I like, as a builder/programmer, I was able to play with a custom subset of LPC (a C-like prototype-based language) that the MUD used for game objects and scripting. Over time, I made a list of interesting tasks that were easy and useful in LPC, yet couldn't be done either as nicely, or at all, when using CLOS.
In a nutshell, the biggest advantages of using a prototype-based system are as follows:
Much greater dynamicity
Objects can be changed, and those changes can be distributed down the object hierarchy in a much easier and cleaner way than can be done with class-based systems (including CLOS)
Hierarchical data sharing
Not only are slots and methods shared -- so is data. Being able to alter
default' orcommon' values and have them change the values of all children can be useful (although there are facilities to just as easily enforce unique values for each object -- such as collections)
If you decide that your `instance' isn't the end-all of your hierarchy, you can flexibly expand your hierarchy further down. This is incredibly nice and useful for rapid prototyping and exploratory programming, since it does not force you to destroy existing instances, create a new class because that previous class wasn't quite the bottom of the hierarchy that you can just make instances of.
It makes more sense
The Self people argue that manipulating objects directly makes more sense that having the divide with classes. I agree.
Why not Sheeple?
There are, of course, some caveats to using the current implementation of Sheeple...
It's considerably slower than CLOS -
This should not come as a surprise considering the sheer speed of implementations like PCL. Considerable optimization is planned as time goes on and interfaces stabilize, but Sheeple would most probably never be as fast as CLOS. On the other hand, it's considerable faster on SBCL than CLOS on GNU clisp, for both slot-access and dispatch, so it is certainly usable for a certain number of applications, even in this sub-optimal state.
It's buggy right now -
It really is. The API isn't guaranteed to stay as it is until 1.0 ships, and is regularly changing as requirements come up.
It doesn't have a toolkit as complete as CLOS' (yet) -
Conceptually, I think of Sheeple as a superset of CLOS: It can be made to easily emulate the behaviors of class-based systems through a number of tools (some of which are still in the works). A large number of CLOS goodies are planned, including a sizeable MOP, but it may never really reach CLOS-level glory (or bloat, depending on who you ask).
It's not CLOS
It looks a hell of a lot like CLOS, it might even trick people into thinking some jerk with a bad sense of humor wrote a bunch of alias macros around CLOS... but it's not CLOS. Many concepts are different, and it might be hard to get used to them, or even find any use in them. YMMV