<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>(blog :sykosomatic)</title>
	<atom:link href="http://sykosomatic.org/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://sykosomatic.org/blog</link>
	<description></description>
	<lastBuildDate>Fri, 25 Dec 2009 06:47:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CouchDB: Making databases fun</title>
		<link>http://sykosomatic.org/blog/?p=89</link>
		<comments>http://sykosomatic.org/blog/?p=89#comments</comments>
		<pubDate>Fri, 25 Dec 2009 06:47:15 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[couchdb]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[igotmypony]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=89</guid>
		<description><![CDATA[So the whole reason I even started writing Sheeple was to use it as a persistent object backend for Sykosomatic, that MUD that I&#8217;ve been sort-of writing since I started working on Lisp, but is still unfinished.
Sheeple is a very dynamic system, and so when I went looking for a database backend to build this [...]]]></description>
			<content:encoded><![CDATA[<p>So the whole reason I even started writing Sheeple was to use it as a persistent object backend for Sykosomatic, that MUD that I&#8217;ve been sort-of writing since I started working on Lisp, but is still unfinished.</p>
<p>Sheeple is a very dynamic system, and so when I went looking for a database backend to build this persistence library around, most things fell short of my expectations&#8230; <a href="http://en.wikipedia.org/wiki/Couchdb">and then I found CouchDB</a>.</p>
<p>I don&#8217;t think I can praise CouchDB enough. Everything about it  so far has just been a dream. After a week of nightmarish interactions with SQL (on a different project), nothing was a bigger blessing than CouchDB&#8217;s easy, wonderful, simple design.</p>
<p>Everything about Couch just reeks of ease-of-use and simplicity. You don&#8217;t need anything fancy. No obnoxious authentication setup or all that bullshit MySQL makes you go through just so you can put your grandma&#8217;s phone number into a goddamn table. No ridiculous, pathetic attempts at making your object model fit in with your schema. No obnoxious &#8216;drivers&#8217; and weird serialization formats to deal with.</p>
<p>All you need to do to get started with CouchDB is a single command to install it through your package manager, start up the daemon, and start throwing http requests at it with curl or something.</p>
<p>That&#8217;s it. That&#8217;s all. CouchDB daemon + http client + JSON library, and you&#8217;re GOOD TO GO. If you want to wrap that up and make it object-oriented or something, that&#8217;s -trivial-. You can tell from the moment you start reading their <a href="http://wiki.apache.org/couchdb/">documentation</a>, or <a href="http://books.couchdb.org/relax/">the wonderful, but apparently still WIP book</a>, that the CouchDB designers have put a lot of effort into making life easy for you. They really do live up to their motto: Relax.</p>
<p>CouchDB has been a dream to work with &#8212; it&#8217;s easy to get set up, easy to use, and easy to manage, all-around. Sure, a big benefit comes just from the fact that CouchDB is one of those shiny new <a href="http://en.wikipedia.org/wiki/Nosql">NoSQL databases</a>. Couch, though, goes the extra mile for you. You know what I don&#8217;t want to do? I don&#8217;t want a <a href="http://www.mongodb.org/display/DOCS/Mongo+Driver+Requirements">&#8216;driver&#8217;</a>. I don&#8217;t want<a href="http://www.mongodb.org/display/DOCS/BSON"> BSON</a>.</p>
<p>You know what I do want? I want to go play with CouchDB some more &#8212; and you should too.</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=89</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Sheeple 3.0.3</title>
		<link>http://sykosomatic.org/blog/?p=88</link>
		<comments>http://sykosomatic.org/blog/?p=88#comments</comments>
		<pubDate>Thu, 17 Dec 2009 17:54:07 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[sheeple]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=88</guid>
		<description><![CDATA[Adlai said we should make an emergency release of Sheeple, since he added effective reply function caching. I agreed. If you do -any- sort of semi-serious data crunching using Sheeple, stay the hell away from 3.0.2!
]]></description>
			<content:encoded><![CDATA[<p>Adlai said we should make an emergency release of Sheeple, since he added effective reply function caching. I agreed. If you do -any- sort of semi-serious data crunching using Sheeple, stay the hell away from 3.0.2!</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=88</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sheeple 3.0.2</title>
		<link>http://sykosomatic.org/blog/?p=85</link>
		<comments>http://sykosomatic.org/blog/?p=85#comments</comments>
		<pubDate>Tue, 15 Dec 2009 23:44:57 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[lisp]]></category>
		<category><![CDATA[releases]]></category>
		<category><![CDATA[sheeple]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[object-oriented programming]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=85</guid>
		<description><![CDATA[It&#8217;s taken a while to get this release out &#8212; we kept adding stuff on &#8212; but it&#8217;s finally out. Even though it&#8217;s a minor version bump, there&#8217;s some important API changes with this new version, including the complete removal of ADD-PROPERTY. Originally, I thought it would be a good idea to force users to [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s taken a while to get this release out &#8212; we kept adding stuff on &#8212; but it&#8217;s finally out. Even though it&#8217;s a minor version bump, there&#8217;s some important API changes with this new version, including the complete removal of ADD-PROPERTY. Originally, I thought it would be a good idea to force users to add a property manually before being allowed to set a value. Then I realized that the Python community has had this ability for a very long time. The freenode Pythonistas seemed to pretty consistently agree that it had never caused serious problems. Thus, A-P is gone, and (SETF PROPERTY-VALUE) is now used to both add a property, and to set a value on existing ones.</p>
<p>There is also now a manual! A pretty one in both PDF and HTML form, which can be found at our <a href="http://common-lisp.net/project/sheeple">new project page on common-lisp.net</a>. There&#8217;s also some mailing lists on that page you might want to sign up for if you feel like tracking Sheeple development.</p>
<p>Things have slowly been ramping up. Ever since I gave <a href="http://vimeo.com/7242003">that talk at the TC Lispers meeting</a>, a few other people have given Sheeple a whirl. I&#8217;m pleased that their experiences have been good, even though Sheeple is still a bit unstable. Of particular note is <a href="http://nklein.com/2009/12/woolly-application-underway/">Patrick Stein&#8217;s Wooly</a>, a GL-based GUI toolkit using Sheeple objects.</p>
<p>Development has slowed down a bit since I started working at <a href="http://clockwork.net">Clockwork</a>, but I&#8217;ve been working with Adlai lately towards a native-Sheeple MOP. So far, the basics of object creation have been taken care of, and a property MOP should be up and running soon. We&#8217;ve also decided to rename persistent-sheeple, but that will get announced once we have enough of a MOP to hook up our objects to CouchDB.</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=85</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projects</title>
		<link>http://sykosomatic.org/blog/?p=82</link>
		<comments>http://sykosomatic.org/blog/?p=82#comments</comments>
		<pubDate>Sun, 01 Nov 2009 07:16:57 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ffffu-]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=82</guid>
		<description><![CDATA[I don&#8217;t understand. I always end up writing libraries.
I wanted to write an application. I wanted to get started this week. I talked to the guy that did pixel art for me last time, he was all over that.
And then I spent the rest of the week dusting off two old libraries, and starting a [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t understand. I always end up writing libraries.</p>
<p>I wanted to write an application. I wanted to get started this week. I talked to the guy that did pixel art for me last time, he was all over that.</p>
<p>And then I spent the rest of the week dusting off two old libraries, and starting a completely new project.</p>
<p>I do this to myself, clearly. I guess it will be nice to have a native 2d physics library, though. That&#8217;s always how this shit starts&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=82</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Release: Sheeple 3.0</title>
		<link>http://sykosomatic.org/blog/?p=79</link>
		<comments>http://sykosomatic.org/blog/?p=79#comments</comments>
		<pubDate>Wed, 21 Oct 2009 10:34:12 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[releases]]></category>
		<category><![CDATA[sheeple]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=79</guid>
		<description><![CDATA[Sheeple 3.0 is finally out!
After months in development, it&#8217;s finally done. A major rewrite of the entire Sheeple system, this new version boasts a completely new, cleaned up, and serious&#8217;d interface, reworked, lightweight objects, and efficient property access (right now, matching CCL&#8217;s slot-value performance.) You can download a tarball here, or use asdf-install to grab [...]]]></description>
			<content:encoded><![CDATA[<p>Sheeple 3.0 is finally out!</p>
<p>After months in development, it&#8217;s finally done. A major rewrite of the entire Sheeple system, this new version boasts a completely new, cleaned up, and serious&#8217;d interface, reworked, lightweight objects, and efficient property access (right now, matching CCL&#8217;s slot-value performance.) You can download a tarball <a title="sheeple downloads page" href="http://github.com/sykopomp/sheeple/downloads">here</a>, or use <a href="http://www.cliki.net/ASDF-Install">asdf-install</a> to grab the latest version.</p>
<p>I&#8217;m really excited about this release. I would write more about it and all the goodies it has, but I have a<a title="Sheeple presentation!" href="http://tclispers.org/events/october-meeting"> presentation</a> to finish. Expect more in a later post.</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=79</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick Sheeple update&#8230;</title>
		<link>http://sykosomatic.org/blog/?p=72</link>
		<comments>http://sykosomatic.org/blog/?p=72#comments</comments>
		<pubDate>Thu, 15 Oct 2009 07:20:38 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[lisp]]></category>
		<category><![CDATA[sheeple]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=72</guid>
		<description><![CDATA[Okay, so I haven&#8217;t actually posted anything about Sheeple in a while.
Sheeple took a break for a few weeks, but development is up to full steam again. There&#8217;s some shiny new special sauce going on under the hood now, with some -very- promising early results.
See this paste for some picobenchmarks on various implementation. Notice: direct-property [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, so I haven&#8217;t actually posted anything about Sheeple in a while.</p>
<p>Sheeple took a break for a few weeks, but development is up to full steam again. There&#8217;s some shiny new special sauce going on under the hood now, with some -very- promising early results.</p>
<p>See <a title="omg-optimized" href="http://paste.lisp.org/display/88658">this paste</a> for some picobenchmarks on various implementation. Notice: direct-property access is now as fast as slot-value on CCL. <img src='http://sykosomatic.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Unfortunately, the rest of Sheeple doesn&#8217;t perform that well quite yet. The new fancy secret sauce allows for a lot of optimizations that weren&#8217;t done before. Once this code is stabilized and tagged as 3.0(!), I&#8217;m bringing back a bunch of different caching schemes Sheeple was using for dispatch. Tonight&#8217;s benchmarks were promising &#8212; I think Sheeple may actually be able to perform better and faster than optimized CLOS implementations such as CCL&#8217;s and SBCL&#8217;s.</p>
<p>We&#8217;ll see. We&#8217;ll see&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=72</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing: ChanL</title>
		<link>http://sykosomatic.org/blog/?p=70</link>
		<comments>http://sykosomatic.org/blog/?p=70#comments</comments>
		<pubDate>Wed, 14 Oct 2009 20:50:09 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[chanl]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[csp]]></category>
		<category><![CDATA[threads]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=70</guid>
		<description><![CDATA[For the longest time, I wanted to start learning about issues related to concurrency, and how to handle them in Lisp. I kept reading around to learn about different approaches to writing concurrent code, and studied up on things like Software Transactional Memory, futures/promises, and Erlang-style actors. After boggling to understand all these different approaches, [...]]]></description>
			<content:encoded><![CDATA[<p>For the longest time, I wanted to start learning about issues related to concurrency, and how to handle them in Lisp. I kept reading around to learn about different approaches to writing concurrent code, and studied up on things like <a title="STM" href="http://en.wikipedia.org/wiki/Software_transactional_memory">Software Transactional Memory</a>, <a title="futs" href="http://en.wikipedia.org/wiki/Futures_and_promises">futures/promises</a>, and <a title="the language" href="http://en.wikipedia.org/wiki/Erlang_(programming_language)">Erlang</a>-style <a title="the model" href="http://en.wikipedia.org/wiki/Actor_model">actors</a>. After boggling to understand all these different approaches, I was left with a bit of disappointment: None of them seemed to be the right combination of generalized+clean+easy.</p>
<p>STM caught my eye for a while, but it still has its issues, and I&#8217;m still not sure how I feel about the whole &#8220;thrash until you can agree on something&#8221; issue &#8212; it seems to me like it&#8217;s just the same as wrapping code in  (with-lock-held &#8230;). Futures/promises looked easy enough for simple one-shot tasks, but that&#8217;s not necessarily what you want to do when you write heavily-parallel code: Sometimes you want threads constantly yielding values. Erlang-style actors are, of course, one of the big success stories when it comes to people trying to write heavily-parallel code. It just seems so damn ugly &#8212; and it -is- nice to be able to share data sometimes.</p>
<p>Then, magic happened: I came across something called <a title="CSP" href="http://en.wikipedia.org/wiki/Communicating_sequential_processes">Communicating Sequential Processes</a>, through <a title="tech talk" href="http://video.google.com/videoplay?docid=810232012617965344#">Rob Pike&#8217;s Google Tech Talk on Newsqueak</a>. It was really amazing, it seemed to be just what I needed: a relatively low-level synchronisation mechanism that works naturally with the concept of multiple parallel threads/processes. I&#8217;m totally sold on Rob&#8217;s point of view here: don&#8217;t try to pretend you&#8217;re not parallelizing code (hear that, STM? That&#8217;s right). Instead, make the parallelization part of your interface. Deadlocks are a bug &#8212; find them.</p>
<p>I spent a good while thinking about CSP, wondering why the heck everything else is the talk of the town. The more I thought about it, the more I was amazed that CSP wasn&#8217;t everyone&#8217;s obvious choice when it came to parallelization. I kept wondering why no one seemed to even know about it. Then again, it&#8217;s not entirely obscure &#8212; <a title="stackless" href="http://en.wikipedia.org/wiki/Stackless_Python">Stackless Python</a> uses this exact same concept. Clearly, the only way I could really get a good idea of what CSP is all about, and what its advantages/disadvantages are was by actually using it.</p>
<p>As it turns out, there was already an existing library for CL that implemented these: <a title="csp library" href="http://www.cliki.net/csp">csp</a>. The API, unfortunately, was a bit weird, and I couldn&#8217;t get myself into really using. I just didn&#8217;t get it &#8212; is CSP a red herring meant to distract me from some other Right Thing? I figured the only way to find out, then, would be to implement my own library.</p>
<p>Enter ChanL, my attempt at implementing channels in CL. I&#8217;ve been working with Adlai on these for a couple of weeks, and we just tagged v0.4. As the library developed, and we started writing examples, things started becoming more and more clear. Channels, as it turns out, are just high-level enough to make a lot of tasks extremely easy that would otherwise be a bit obnoxious to write with locks.Well, sort of: it turns out to be a little tricky to convert existing, very-linear code into channels unless you&#8217;re used to them (STM certainly wins in that front, I have to say)&#8230; but once you&#8217;ve embraced the concurrent nature of your algorithm, channels become a powerful beast.</p>
<p>The most interesting part, I think, is that channels turned out to be extremely useful for implementing -other- sorts of (sometimes simpler) concurrency mechanisms. Futures/promises, for example, were implemented in about 20 lines of code. The whole chanl/examples/futures.lisp file is 93 lines long, including comments, several convenience macros for creating futures, a select function, and a parallelized version of LET, as well as a fully-functional cross-thread condition-handling mechanism. That&#8217;s a lot of stuff, and it was made simple because of how nice channels are. Actors can be implemented similarly, and, in fact, I&#8217;m working on them already, although the code isn&#8217;t online yet.</p>
<p>All-in-all, after working with channels for a few weeks, my impression is that they&#8217;re much closer to a generalizable solution to handling concurrency than all these other constructs that keep popping up (again, perhaps with the exception of STM, which has different issues). I&#8217;m still honestly perplexed as to why channels aren&#8217;t more widely accepted and used. Perhaps it&#8217;s high time that changed.</p>
<p>If you ever feel like messing around with channels, go ahead and try it out. It&#8217;s asdf-installable with (asdf-install:install :chanl), or you can download it at <a title="github chanl download" href="http://github.com/sykopomp/chanl/downloads">Github</a>. It&#8217;s got a fully-documented API, and you can even write your own unique channel styles fairly easily.</p>
<p>Next time: ChanL code samples/examples.</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=70</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sheeple goes on a diet</title>
		<link>http://sykosomatic.org/blog/?p=68</link>
		<comments>http://sykosomatic.org/blog/?p=68#comments</comments>
		<pubDate>Fri, 14 Aug 2009 06:15:35 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=68</guid>
		<description><![CDATA[I&#8217;ve been working on rewriting Sheeple these past couple of days. The new version will be a major bottom-up redesign, mainly to the lowlevel stuff. The early results without too-crazy optimization are already showing up, and it&#8217;s quite nice.
These numbers are on Clozure CL  x86  Linux:
SHEEPLE&#62; (time (loop repeat 100000 do (allocate-std-sheep)))
(LOOP REPEAT 100000 [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on rewriting Sheeple these past couple of days. The new version will be a major bottom-up redesign, mainly to the lowlevel stuff. The early results without too-crazy optimization are already showing up, and it&#8217;s quite nice.</p>
<p>These numbers are on Clozure CL  x86  Linux:</p>
<pre>SHEEPLE&gt; (time (loop repeat 100000 do (allocate-std-sheep)))
(LOOP REPEAT 100000 DO (ALLOCATE-STD-SHEEP)) took 119 milliseconds (0.119 seconds) to run
                    with 2 available CPU cores.
During that period, 106 milliseconds (0.106 seconds) were spent in user mode
                    3 milliseconds (0.003 seconds) were spent in system mode
50 milliseconds (0.050 seconds) was spent in GC.
 4,000,000 bytes of memory allocated.
 19 minor page faults, 0 major page faults, 0 swaps.</pre>
<p>And a single sheep object:</p>
<pre>SHEEPLE&gt; (time (allocate-std-sheep))
(ALLOCATE-STD-SHEEP) took 0 milliseconds (0.000 seconds) to run
                    with 2 available CPU cores.
During that period, 0 milliseconds (0.000 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 40 bytes of memory allocated.</pre>
<p>Now, that&#8217;s still a bit heavy compared to CLOS (which only allocates 24 bytes for a raw instance), and to be honest, I&#8217;m not aiming at beating CLOS. It&#8217;s like a class-based system trying to beat out structs. On the other hand, it&#8217;s actually pretty nice to shrink everything down to more usable levels.<br />
The current Sheeple release, for example, the one built on top of CLOS, is quite a monster:</p>
<pre>SHEEPLE&gt; (time (loop repeat 100000 do (allocate-sheep)))
(LOOP REPEAT 100000 DO (ALLOCATE-SHEEP)) took 11,273 milliseconds (11.273 seconds) to run
                    with 2 available CPU cores.
During that period, 10,716 milliseconds (10.716 seconds) were spent in user mode
                    204 milliseconds (0.204 seconds) were spent in system mode
3,249 milliseconds (3.249 seconds) was spent in GC.
 244,000,000 bytes of memory allocated.
 9,419 minor page faults, 0 major page faults, 0 swaps.</pre>
<p>So yeah, this is a huge improvement.</p>
<p>Keep in mind that all of these numbers don&#8217;t yet take into account what the full cost of a raw (clone) will be, although it won&#8217;t be much higher than what it is right now (I believe it will only be two extra words, because an item will be added to the parents list).</p>
<p>It&#8217;s a bit fun to mess around with stuff so carefully at a lower level&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=68</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sheeple MOP</title>
		<link>http://sykosomatic.org/blog/?p=60</link>
		<comments>http://sykosomatic.org/blog/?p=60#comments</comments>
		<pubDate>Wed, 05 Aug 2009 08:43:39 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[lisp]]></category>
		<category><![CDATA[sheeple]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[object-oriented programming]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=60</guid>
		<description><![CDATA[There&#8217;s been some work done on Sheeple&#8217;s MOP, and I figured I&#8217;d write a bit about what got done today&#8230;
The original reason for writing Sheeple, like I said before, was to use it with Sykosomatic (which I still haven&#8217;t written an entry for, meh). That said, Sykosomatic&#8217;s object system needs to be fully persistent. Sheeple [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been some work done on Sheeple&#8217;s MOP, and I figured I&#8217;d write a bit about what got done today&#8230;</p>
<p>The original reason for writing Sheeple, like I said before, was to use it with Sykosomatic (which I still haven&#8217;t written an entry for, meh). That said, Sykosomatic&#8217;s object system needs to be fully persistent. Sheeple itself is not persistent &#8212; it works like a standard run-time object system.</p>
<p>Because I&#8217;m a masochist and a nerd, I figured I&#8217;d simply write Sheeple as the regular object system that it is, then &#8220;just&#8221; add a Metaobject Protocol like CLOS&#8217; once the base language was set. Ho boy, did I ask for trouble. MOPs are a royal pain in the ass to do properly, and they&#8217;re a bit mind-bending. Regardless, Sheeple has been slowly getting MOP features over time. The neat part? The MOP itself is written in CLOS (as are a lot of Sheeple&#8217;s internals).</p>
<p>What I managed to get done today is the protocol for manipulating properties and property behavior through property metaobjects.</p>
<p>To show how it works, let&#8217;s go over an example of how one might implement persistent-sheeple, so maybe the damn thing can actually be used for Sykosomatic&#8230;</p>
<pre>
<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_in_pkg.htm" class="symbol">in-package</a> <span class="keyword">:sheeple-user</span></span>)</span>

<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defpar.htm" class="symbol"><i><span class="symbol">defvar</span></i></a> <span class="special">*max-oid*</span> 0</span>)</span>
<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defcla.htm" class="symbol"><i><span class="symbol">defclass</span></i></a> persistent-sheep <span class="paren2">(<span class="code">standard-sheep</span>)</span>
  <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">oid <span class="keyword">:initform</span> <span class="paren4">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_incf_.htm" class="symbol">incf</a> <span class="special">*max-oid*</span></span>)</span> <span class="keyword">:reader</span> oid</span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defcla.htm" class="symbol"><i><span class="symbol">defclass</span></i></a> persistent-property <span class="paren2">(<span class="code">standard-property</span>)</span> <span class="paren2">(<span class="code"></span>)</span></span>)</span>
</pre>
<p>The first step to changing behavior is to make some subclasses. We&#8217;ll be dispatching on these.</p>
<pre>
<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defmet.htm" class="symbol"><i><span class="symbol">defmethod</span></i></a> <a href="http://www.lispworks.com/reference/HyperSpec/Body/f_init_i.htm" class="symbol">initialize-instance</a> <span class="keyword">:after</span> <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">sheep persistent-sheep</span>)</span> &amp;key</span>)</span>
  <span class="paren2">(<span class="code">allocate-sheep-externally sheep</span>)</span></span>)</span>

<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defmet.htm" class="symbol"><i><span class="symbol">defmethod</span></i></a> add-parent <span class="keyword">:around</span> <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">new-parent standard-sheep</span>)</span>
                               <span class="paren3">(<span class="code">child persistent-sheep</span>)</span></span>)</span>
  <span class="paren2">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/s_if.htm" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren3">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/a_or.htm" class="symbol">or</a> <span class="paren4">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/a_eql.htm" class="symbol">eql</a> new-parent =dolly=</span>)</span>
          <span class="paren4">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/a_eql.htm" class="symbol">eql</a> <span class="paren5">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/f_find_c.htm" class="symbol">find-class</a> 'persistent-sheep</span>)</span>
               <span class="paren5">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/f_clas_1.htm" class="symbol">class-of</a> new-parent</span>)</span></span>)</span></span>)</span>
      <span class="paren3">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/s_progn.htm" class="symbol"><i><span class="symbol">progn</span></i></a>
        <span class="paren4">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/f_call_n.htm" class="symbol">call-next-method</a></span>)</span>
        <span class="paren4">(<span class="code">add-parent-externally new-parent child</span>)</span></span>)</span>
      <span class="paren3">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/a_error.htm" class="symbol">error</a> <span class="string">"We don't support adding non-persistent~
              sheep as parents!"</span></span>)</span></span>)</span></span>)</span>
</pre>
<p>The first and most important part of having a persistent object is that it&#8217;s somehow allocated externally. All Sheeple are standard CLOS instances, so this method will get called each and every time the sheep object is created.</p>
<p>We also go ahead and write a method for <code>add-parent</code>. This is important because we want to make sure that we can successfully serialize the sheep. We must always have at -least- <code>=dolly=</code> as a parent, so we have to make an exception for that. Other than that, no non-persistent sheep are allowed into a persistent-sheep&#8217;s hierarchy list. Note that methods defined on add-parent must not override the standard behavior (basically, the <code>(standard-sheep standard-sheep)</code> method must always be called). Other than that, clients are free to go wild with what they do with this one.</p>
<p>With this much code (aside from serialization and db-management stuff!) we can now have externally-stored sheep objects. The rest of sheeple will work normally at this point. The whole point of persistent-sheeple, though, is to be able to store property values externally, so here we go&#8230; </p>
<pre>
<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defmet.htm" class="symbol"><i><span class="symbol">defmethod</span></i></a> add-property <span class="keyword">:around</span> <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">sheep persistent-sheep</span>)</span> pname
                                 value &amp;key transientp</span>)</span>
  <span class="paren2">(<span class="code">register-property-externally sheep pname</span>)</span>
  <span class="paren2">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/s_if.htm" class="symbol"><i><span class="symbol">if</span></i></a> transientp
      <span class="paren3">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/f_call_n.htm" class="symbol">call-next-method</a></span>)</span>
      <span class="paren3">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/f_call_n.htm" class="symbol">call-next-method</a> sheep pname value
                        <span class="keyword">:property-metaclass</span> 'persistent-property</span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defmet.htm" class="symbol"><i><span class="symbol">defmethod</span></i></a> add-property-using-property-metaobject <span class="keyword">:before</span>
    <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">sheep persistent-sheep</span>)</span> value
     <span class="paren3">(<span class="code">property persistent-property</span>)</span> &amp;key</span>)</span>
  <span class="paren2">(<span class="code">allocate-property-externally sheep pname</span>)</span></span>)</span>
</pre>
<p>Because Sheeple requires that properties be specifically added to the hierarchy-list, we have these two functions: The first one takes care of creating a property metaobject for the second one to dispatch on. In this case, we make our :around method on <code>add-property</code> accept a keyword that tells it whether a property should be transient or not.</p>
<p>For the purpose of this exercise, we assume that a transient property is simply a regular property on a persistent-sheep. Since we want to make sure we&#8217;ve got the property available when we restore the database, though, we register its existence regardless of whether it&#8217;s transient or not.</p>
<p>Next up, in a-p-u-p-m, we actually dispatch on the property object itself, instead of just the class. This :before method sits there to make sure we have external DB space to allocate a value on, since we&#8217;re sure in this case that we&#8217;ll be assigning actual values to this one.</p>
<p>Once that&#8217;s set, it&#8217;s just a matter of making sure we can get/set those values, and we&#8217;re home free&#8230;</p>
<pre>
<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defmet.htm" class="symbol"><i><span class="symbol">defmethod</span></i></a> direct-property-value <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">sheep persistent-sheep</span>)</span>
                                  <span class="paren3">(<span class="code">property persistent-property</span>)</span></span>)</span>
  <span class="paren2">(<span class="code">get-property-value-externally sheep <span class="paren3">(<span class="code">property-name property</span>)</span></span>)</span></span>)</span>

<span class="paren1">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/m_defmet.htm" class="symbol"><i><span class="symbol">defmethod</span></i></a> <span class="paren2">(<span class="code"><a href="http://www.lispworks.com/reference/HyperSpec/Body/a_setf.htm" class="symbol">setf</a> property-value</span>)</span> <span class="paren2">(<span class="code">new-value <span class="paren3">(<span class="code">sheep persistent-sheep</span>)</span>
                                  <span class="paren3">(<span class="code">property persistent-property</span>)</span></span>)</span>
  <span class="paren2">(<span class="code">set-property-value-externally sheep <span class="paren3">(<span class="code">property-name property</span>)</span>
                                 new-value</span>)</span></span>)</span>
</pre>
<p>And that&#8217;s it. We override the standard getting/setting behavior so nothing is set locally: Storage lives in the database.</p>
<p>Keep in mind here that a built-in :before method for <code>(setf property-value)</code> will take care of calling <code>add-property</code> as appropriate when the sheep object does not have a direct property metaobject registered for that property-name.</p>
<p>Now we can actually use it:</p>
<pre>
<span class="paren1">(<span class="code"><i><span class="symbol">defproto</span></i> =psheep= <span class="paren2">(<span class="code"></span>)</span>
  <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">foo <span class="string">"bar"</span></span>)</span>
   <span class="paren3">(<span class="code">baz <span class="string">"quux"</span> <span class="keyword">:transientp</span> <a href="http://www.lispworks.com/reference/HyperSpec/Body/a_t.htm" class="symbol">t</a></span>)</span></span>)</span>
  <span class="paren2">(<span class="code"><span class="keyword">:metaclass</span> 'persistent-sheep</span>)</span></span>)</span>
</pre>
<p>(note: <code>defproto</code> changed a bit in recent commits, more on that later&#8230;)</p>
<p>And there you have it! <code>(setf (foo =psheep=) "Blargh")</code> is all it takes to start changing stuff in your new persistent sheep. The rest of sheeple will work as expected. It&#8217;s worth noting that roles belonging to this object won&#8217;t be persisted, since we only messed around with object creation and properties.</p>
<h3>Discussion</h3>
<p>While I&#8217;m very pleased that the MOP has come this far, I have to admit that it probably doesn&#8217;t work very well right now. It&#8217;s very new, and very much still a work-in-progress. There&#8217;s probably certain things that could be cleaned up and all that, but I think it&#8217;s certainly a step in the right direction.</p>
<p>I&#8217;m honestly not entirely sure what I&#8217;m doing half the time. Even though I&#8217;ve read through AMOP several times, some of this is still a bit confusing, and I haven&#8217;t actually used CLOS&#8217; MOP very much at all. I&#8217;m playing it by ear (with a hell of a lot of help from the debugger!)</p>
<p>Hopefully, as the MOP grows (and evolves), it&#8217;ll settle into something generally useful. For now, though, YMMV if you want to mess with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=60</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Games and storytelling</title>
		<link>http://sykosomatic.org/blog/?p=54</link>
		<comments>http://sykosomatic.org/blog/?p=54#comments</comments>
		<pubDate>Sat, 01 Aug 2009 04:02:40 +0000</pubDate>
		<dc:creator>sykopomp</dc:creator>
				<category><![CDATA[roleplaying]]></category>

		<guid isPermaLink="false">http://sykosomatic.org/blog/?p=54</guid>
		<description><![CDATA[So i went missing for a few days.  One reason is that I got distracted from code by a recently-purchased copy of the World of Darkness Storytelling system rulebook.
I really love  White Wolf&#8217;s approach to these games. I&#8217;ve played MMOs for many years now, and tabletop roleplaying games for a little less, and I found [...]]]></description>
			<content:encoded><![CDATA[<p>So i went missing for a few days.  One reason is that I got distracted from code by a recently-purchased copy of the <a href="http://www.white-wolf.com/" target="_blank">World of Darkness</a> <a href="http://en.wikipedia.org/wiki/Storytelling_system" target="_blank">Storytelling system </a>rulebook.</p>
<p>I really love  White Wolf&#8217;s approach to these games. I&#8217;ve played MMOs for many years now, and tabletop roleplaying games for a little less, and I found that I almost universally went with roleplaying/story-heavy sides of whatever I played, so the Storytelling system&#8217;s strong emphasis on telling a story, rather than leveling up a character by grinding through rats, really resonated with me.</p>
<p>It also helped me think a lot more about what kind of system Sykosomatic should employ &#8212; what can be done in an online world that encourages cooperative storytelling between players, while still having systems for fairly resolving conflicts?</p>
<p>Anyway, I should have an actual full post about what Sykosomatic is and what I&#8217;m aiming for with it before I go too far into more specific aspects of its design.</p>
<p>As far as the WoD goes &#8212; I&#8217;m really liking this system, and I&#8217;m going to try and run a couple of short games over the coming months to get familiar with it. Right now, I have a feeling a modified version of the system is what Sykosomatic will end up using in the background&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://sykosomatic.org/blog/?feed=rss2&amp;p=54</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
