<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Pipe Dreams</title>
	<atom:link href="http://rocketnia.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://rocketnia.wordpress.com</link>
	<description>everlasting peace, one revision at a time</description>
	<lastBuildDate>Thu, 16 Jun 2011 21:39:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='rocketnia.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Pipe Dreams</title>
		<link>http://rocketnia.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://rocketnia.wordpress.com/osd.xml" title="Pipe Dreams" />
	<atom:link rel='hub' href='http://rocketnia.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Introducing Chops</title>
		<link>http://rocketnia.wordpress.com/2011/06/15/introducing-chops/</link>
		<comments>http://rocketnia.wordpress.com/2011/06/15/introducing-chops/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 20:45:42 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Chops]]></category>
		<category><![CDATA[Lathe]]></category>
		<category><![CDATA[chops]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[technobabble]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=130</guid>
		<description><![CDATA[Recently I&#8217;ve been doing a lot of my exploratory programming in JavaScript, thanks to the fact that I know it&#8217;ll run on crazy platforms like the 3DS. -_^ I&#8217;ve programmed in JavaScript off and on since high school, and boi has my JavaScript style changed&#8230;. @_@ JavaScript&#8217;s lack of macros is a bit troubling for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=130&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been doing a lot of my exploratory programming in JavaScript, thanks to the fact that I know it&#8217;ll run on crazy platforms like the 3DS. -_^ I&#8217;ve programmed in JavaScript off and on since high school, and boi has my JavaScript style changed&#8230;. @_@</p>
<p>JavaScript&#8217;s lack of macros is a bit troubling for me, especially given the recent tendency for JavaScript programmers to deal in lots of nested asynchronous callbacks: <a href="https://github.com/jashkenas/coffee-script/issues/1097">&#8220;Unindented functions to clean callback mess.&#8221;</a> <a href="http://kaescripts.blogspot.com/2010/02/asynchronous-callbacks-in-javascript.html">&#8220;Asynchronous callbacks in JavaScript&#8221;</a></p>
<p>I haven&#8217;t felt the pain of the asynchronous callback nesting problem firsthand, but I know a horror close to that one: Monadic programming in Groovy. <a href="https://github.com/rocketnia/blade/blob/9e8af07e08e721a6796da4ae6fd082c108fb0981/jvm/src/test/resources/buildproject/turbine.blade#L791">Observe the indentation.</a></p>
<p>In fact, that indentation-heavy part of the Blade code is what originally got me fed up with using Groovy and interested in making Penknife as an intermediate project on the way to Blade. Well, my work on Penknife has been so focused on modularity and hygiene that it&#8217;s slack on what really matters: Syntax. Oh, syntax, how you really really matter so! :-p</p>
<p><strong><span id="more-130"></span>Blade and Penwhatsit?</strong></p>
<p>Unless you&#8217;ve seen my hobby-horsing rants on the Arc Forum, you probably have no clue what I mean by Blade or Penknife. They&#8217;re projects I&#8217;ve been working on for quite some time now, but I never did get around to blogging about them until now. In summary, they&#8217;re both language ideas which take customizable syntax to the limit, approaching the vision I described in <a href="http://rocketnia.wordpress.com/2010/12/10/a-language-should-support-the-future/">my last post</a>.</p>
<p>What&#8217;s the difference between Penknife and Blade, you ask? Well, they both center around extensible/customizable syntax, but Blade projects are finite collections of declarations, and Penknife projects are discrete, potentially ongoing sequences of commands. Blade is the kind of language that could have good IDE integration, but Penknife is the kind of language that could have good REPL integration. I started working on Penknife after those indentation difficulties with Blade (as I just mentioned), and Penknife is now much farther along in development.</p>
<p>Penknife and Blade are based on square bracket syntaxes which are designed to work seamlessly inside of most other-language code. In most existing programming languages, square brackets are somewhat less common than parens and curly braces, and when they do appear, they&#8217;re usually balanced. (Sure, the half-open mathematical range syntax (0,4] isn&#8217;t balanced, but what programming language uses that? :-p ) So the premise of Penknife and Blade&#8217;s syntax extension is pretty simple: Parse out the square brackets, and compile the outermost ones according to some rule or other that splits off an operator and applies it to the rest of the (unparsed) body. Chops uses this kind of syntax too.</p>
<p><strong>Chops, with flashy examples</strong></p>
<p>Going back to my roots a bit, I&#8217;ve put together chops.js (and lumped it in with some other JavaScript tools <a href="https://github.com/rocketnia/lathe/tree/master/js">here in Lathe/js</a>). It makes no attempt at being a programming language. It&#8217;s <em>merely</em> a text preprocessor. In Chops, each outermost square bracket is compiled by splitting off all the non-whitespace characters at the beginning, and then invoking a particular JavaScript function (<code>parseInlineChop</code>) which takes three parameters: that string, the current Chops environment, and the &#8220;rest&#8221; of the form as an array of strings and arrays.</p>
<p>One of the first things I put together was a little tool to help out with those indentation issues I was talking about. Instead of writing this:</p>
<pre>thisWill( function ( err, a ) {
    return becomeSome( function ( err, b ) {
        return horriblyNested( function ( err ) {
            return code( a, b );
        } );
    } );
} )</pre>
<p>You can write this:</p>
<pre>[&gt; [just thisWill( [next] ); ]
   [just function ( err, a ) { return becomeSome( [next] ); } ]
   [just function ( err, b ) { return horriblyNested( [next] ); } ]
   [just function ( err ) { return code( a, b ); } ]]</pre>
<p>The &#8220;<code>&gt;</code>&#8221; macro parses the last whitespace-delimited word in its body, then parses the one before it with that result provided as a local &#8220;<code>next</code>&#8221; macro, and so on. The &#8220;<code>just</code>&#8221; macro does nothing; its only purpose is to keep the code inside from counting as multiple words.</p>
<p>On Thursday, I took that up a notch. I have a Haskell-style monad notation now:</p>
<pre>[&gt;-&gt; g1 bar
     g2 baz
     [just foo( g1, g2 ) ]]</pre>
<p>This expands into something equivalent to the following (modulo meaningless parentheses and whitespace):</p>
<pre>monadBind( bar, function ( g1 ) {
    return monadBind( baz, function ( g2 ) {
        return foo( g1, g2 );
    } );
} )</pre>
<p>I even have a crazy monad notation of my own devising:</p>
<pre>[&gt;- foo( [&lt;- bar ], [&lt;- baz ] ) ]</pre>
<p>You can actually try out these syntaxes at http://rocketnia.github.com/lathe/chops.html, though that&#8217;s mostly a kind of unit testing sandbox page, and my REPL interface there is <em>extremely</em> unpolished.</p>
<pre>&gt;&gt;&gt; rocketnia.chops.parseChopcode( choppaScript, "[&gt;- foo( [&lt;- bar ], [&lt;- baz ] ) ]" )
--&gt; (monadBind( ( bar ), function ( gs8352752204_2 ) { return ((monadBind( ( baz ), function ( gs8352752204_3 ) { return ( foo( gs8352752204_2, gs8352752204_3 ) ); } ))); } ))</pre>
<p>Here&#8217;s that output prettied up, with some unnecessary parentheses removed:</p>
<pre>monadBind( bar, function ( gs8352752204_2 ) {
    return monadBind( baz, function ( gs8352752204_3 ) {
        return foo( gs8352752204_2, gs8352752204_3 );
    } );
} )</pre>
<p>There&#8217;s also a &#8220;&#8221; macro, so that any opening square bracket followed immediately by whitespace is treated as though it were regular text:</p>
<pre>&gt;&gt;&gt; rocketnia.chops.parseChopcode( choppaScript, "[&gt; foo[ [next] ] bar]" )
--&gt; foo[ bar ]</pre>
<p><strong>Chops, with flashy hand-waving</strong></p>
<p>Chops doesn&#8217;t <em>parse</em> JavaScript. This is totally a text-level translation (unless you go and write an ambitious macro that does the parsing itself), and any kind of malformed or browser-specific JavaScript is just fine. Output languages other than JavaScript are fair game too, including Arc and Haskell.</p>
<p>In fact, the output language doesn&#8217;t have to be textual. I personally intend to use Chops as yet another markup language for generating HTML, and I intend to use an intermediate AST representation. I was building my website in Penknife this way already, but I think Chops&#8217;ll be a bit more straightforward in the short term.</p>
<p>At this point, Chops is a JavaScript library, but there&#8217;s no good way to develop code that uses Chops as a preprocessor. That&#8217;s the next step, as I see it. Node.js is an option, but I&#8217;d mainly like to able to build in the browser, especially in a way that uses some existing online storage API. (Any storage recommendations? I&#8217;ve been trying the GitHub Gist API, but it uses unusual HTTP actions like PUT, which apparently can&#8217;t be sent by typical browsers. ^^; Now that I&#8217;ve seen JSPaste, I&#8217;m kinda thinking about RDBHost&#8230;.)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/130/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=130&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2011/06/15/introducing-chops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>A Language Should Support the Future</title>
		<link>http://rocketnia.wordpress.com/2010/12/10/a-language-should-support-the-future/</link>
		<comments>http://rocketnia.wordpress.com/2010/12/10/a-language-should-support-the-future/#comments</comments>
		<pubDate>Fri, 10 Dec 2010 22:52:20 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Computer Language Design]]></category>
		<category><![CDATA[Penknife]]></category>
		<category><![CDATA[arc]]></category>
		<category><![CDATA[long-winded]]></category>
		<category><![CDATA[technobabble]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=123</guid>
		<description><![CDATA[There&#8217;s one design goal of Arc I find completely self-evident. Arc&#8217;s designed for good programmers. Duh. Programmers in the future will be better than us, because they&#8217;ll be capable of observing our mistakes. If a language doesn&#8217;t target good programmers, it doesn&#8217;t have a very bright future. There&#8217;s way more to this concept than than [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=123&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s one design goal of Arc I find completely self-evident. Arc&#8217;s designed for good programmers. Duh. Programmers in the future will be better than us, because they&#8217;ll be capable of observing our mistakes. If a language doesn&#8217;t target good programmers, it doesn&#8217;t have a very bright future.</p>
<p>There&#8217;s way more to this concept than than Arc tackles, though.</p>
<p>Programmers in the future will learn from the mistakes we make designing languages today, and they&#8217;ll design better ones. For there to be a single language that persists despite future innovations, snowballing its own library support along the way, it ironically needs to be all the various languages people want it to be. It needs to be a customizable language. (And it <a href="http://rocketnia.wordpress.com/2010/12/06/a-language-should-target-moving-platforms/">needs to target platforms other than its runtime</a>.)</p>
<h4>Foreign Affairs</h4>
<p>Any two of those languages will easily target each other&#8217;s runtimes, so if things happen the way I expect, we&#8217;re likely to find a landscape full of competing languages that all abstract over each other with no clear winner.</p>
<p>To limit that effect, it&#8217;s important for those languages to <em>try</em> to have no obvious defects from the outset, so that they don&#8217;t build up audiences that feel they need to spin off into various camps to pursue slightly better languages.</p>
<p>For this reason, I think it&#8217;s a mistake for any language that takes itself half-seriously to impose an arbitrary limitation on its users. A limitation that makes other things easier is fine, but the point of a tool is always to make people more productive, not less. Good programmers will police themselves as necessary.</p>
<p>But for the same reason, I think the strongest position in a winnerless landscape of customizable languages is a minimalistic one. If a customizable language&#8217;s runtime has only the features it needs for convenient syntax customization, the designer has fewer opportunities to mess up and introduce flaws. In that sense, the language should be severely limited, but for a non-arbitrary cause.</p>
<h4>Civil Unrest</h4>
<p>Meanwhile, each of these languages will itself host a lot of competing syntaxes and abstraction layers. Not all of those will follow the language&#8217;s own philosophy, &#8217;cause they&#8217;ll be their own things. But many will be general-purpose tools for people to use when customizing the language&#8217;s syntax, and their presence will effectively recolor the language for people who want to take advantage of their added features. I believe the language should have a strong philosophy encouraging consistency between these libraries and the main language runtime API, so that the experience doesn&#8217;t fray into separate and competing sub-experiences.</p>
<p>But a language&#8217;s library landscape is anything but minimalistic, so it can&#8217;t share that aspect with the core. Libraries will inevitably introduce extra concepts with flawed designs and buggy implementations. Instead of trying to avoid this, library programmers should assume the programmers who use their code know better than they do, by nature of those programmers being in the future. Thus, when in doubt, they should leave their implementation details exposed rather than hiding them. They should maximize their users&#8217; freedom, just like the language itself does.</p>
<p>A naive take on this would be challenging for libraries in active development. They tend to change their implementation details from release to release in incompatible ways, so if they feel pressured not to break others&#8217; code, that limits their freedom! To solve this, I believe library users should be capable of using unstable features, but that the language culture should encourage library writers to make it clear what&#8217;s stable and what isn&#8217;t, perhaps in such a way that even if it&#8217;s easy for library users to use the unstable parts, it&#8217;s also easy for them to refrain from doing that.</p>
<h4>Conclusion</h4>
<p>So altogether, I believe the best kind of language is a minimalistic, customizable-syntax, cross-targeting build language which has a philosophy encouraging consistently unstable library APIs, makes nothing intentionally hard, and most of all prepares for future innovation.</p>
<p>Not only is this my kind of language, I think it&#8217;s imperative to make these languages extremely well from the beginning so that it we don&#8217;t let suboptimal versions gain the advantage of entrenchment.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/123/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/123/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/123/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=123&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2010/12/10/a-language-should-support-the-future/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>A Language Should Target Moving Platforms</title>
		<link>http://rocketnia.wordpress.com/2010/12/06/a-language-should-target-moving-platforms/</link>
		<comments>http://rocketnia.wordpress.com/2010/12/06/a-language-should-target-moving-platforms/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 01:09:18 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Computer Language Design]]></category>
		<category><![CDATA[Penknife]]></category>
		<category><![CDATA[arc]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=118</guid>
		<description><![CDATA[Platforms are not languages to me. Languages don&#8217;t deal with security, file operations, threads, and so on. Languages are syntaxes people use to develop tools on platforms. Platforms stack, vaguely. The LAMP stack is a classic example: The server is Linux running Apache, content-specific sub-platforms are developed on top of PHP or Perl for Apache [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=118&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Platforms are not languages to me. Languages don&#8217;t deal with security, file operations, threads, and so on. Languages are syntaxes people use to develop tools on platforms.</p>
<p>Platforms stack, vaguely. The LAMP stack is a classic example: The server is Linux running Apache, content-specific sub-platforms are developed on top of PHP or Perl for Apache to use, data sub-platforms are developed on top of MySQL for the PHP/Perl code to use, and the machine code programs (the OS included) rely on a hardware platform of some sort or another.</p>
<p>Platforms also target other platforms and hide them away. For instance, a PHP coder hardly cares about the instruction set in use on the machine, &#8217;cause the interpreter takes care of that. It&#8217;s easy to write a simple PHP script that doesn&#8217;t really care what the hardware, the OS, the server, etc. look like. In this case, PHP itself may be all we&#8217;re thinking about. In that case I&#8217;d say that PHP is our platform.</p>
<p>The reality today is that platforms and languages are developed symbiotically. Innovative general-purpose platform concepts spawn new languages suited for them, like Erlang. Languages which intend to support multiple platforms just end up defining their own. Most platforms can&#8217;t be perfectly translated into each other, so ports of platform-defining languages can only be sparse or imperfect, and when it comes down to it, one&#8217;s choice of platform determines one&#8217;s language options.</p>
<p>Many programmers, including myself, prefer to choose languages not based on the platforms they target but based on their smoothly adapting syntax as project-specific needs come up. Languages which support extensible syntax, like most lisps, are ideal for this purpose, since they hold an implicit <em>infinity</em> promise that they&#8217;ll eventually be every bit as beautiful and convenient as every other language, if people only bother to develop the necessary syntax extensions.</p>
<p>But customizable languages fall short today. People are used to developing programs that target just one platform—the runtime of the language they&#8217;re writing in—and that makes customizable languages only as flexible as the one runtime they&#8217;re limited to.</p>
<p>For a language to have an inflexible runtime is important for code reuse, but if we&#8217;re going to have a convenience-and-aesthetics language that&#8217;s capable of continuing to build momentum over the next, say, 100 years (Arc&#8217;s shtick), we need a language that will target 100 years of platforms we haven&#8217;t invented yet. Therefore, the platform the language code runs in and the platform it targets (usually) won&#8217;t be the same.</p>
<p>Instead, the language needs to encourage a development process that&#8217;s like writing a compiler or build script, where the code produces project artifacts like binaries and other-language scripts, and those are all that&#8217;s deployed.</p>
<h4>AST Processing</h4>
<p>If we start with a &#8220;compiler&#8221; that just outputs what it&#8217;s told to output, then writing code generators in the language will already be at least as convenient as writing the code manually, so the infinity promise will already fulfilled, albeit unimpressively. Templating languages are a step beyond this even, but flat string concatenation is an ineffective way to go forward. Instead, I believe the customizable language&#8217;s core focuses should be on AST manipulation, parsing, dependency resolution, and other compiler duties.</p>
<p>This is the direction I&#8217;ve been taking Blade and Penknife, my own programming languages. Platform innovation is well and good, but I believe truly general-purpose languages are nothing if not homes for syntax innovation.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/118/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=118&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2010/12/06/a-language-should-target-moving-platforms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>Lathe&#8217;s Arc-to-Implementation-Language FFI</title>
		<link>http://rocketnia.wordpress.com/2010/06/01/lathes-arc-to-implementation-language-ffi/</link>
		<comments>http://rocketnia.wordpress.com/2010/06/01/lathes-arc-to-implementation-language-ffi/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 10:28:41 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Lathe]]></category>
		<category><![CDATA[arc]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[technobabble]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=80</guid>
		<description><![CDATA[$ cd /path/to/jarc $ java -server -cp \ &#62; "jarc.jar;$GROOVY_HOME/embeddable/groovy-all-1.7.2.jar" jarc.Jarc Jarc&#62; (= lathe-dir* "path/to/lathe/arc/") "path/to/lathe/arc/" Jarc&#62; (load:+ lathe-dir* "loadfirst.arc") nil Jarc&#62; (use-rels-as jv (+ lathe-dir* "imp/jvm.arc")) #3(tagged mac #&#60;procedure&#62;) Jarc&#62; (jv.jvm!groovy-util-Eval-me "2 + 2") 4 It&#8217;s on now. After about a month of me submitting bugs to the Arc forum and Jarc&#8217;s creator, JD Brennan, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=80&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<pre>$ cd /path/to/jarc

$ java -server -cp \
&gt;   "jarc.jar;$GROOVY_HOME/embeddable/groovy-all-1.7.2.jar" jarc.Jarc

Jarc&gt; (= lathe-dir* "path/to/lathe/arc/")
"path/to/lathe/arc/"
Jarc&gt; (load:+ lathe-dir* "loadfirst.arc")
nil
Jarc&gt; (use-rels-as jv (+ lathe-dir* "imp/jvm.arc"))
#3(tagged mac #&lt;procedure&gt;)
Jarc&gt; (jv.jvm!groovy-util-Eval-me "2 + 2")
4</pre>
<p>It&#8217;s on now.</p>
<p>After about a month of me submitting bugs to the <a href="http://arclanguage.org/newest">Arc forum</a> and Jarc&#8217;s creator, JD Brennan, fixing them, Jarc is now compatible enough with Arc 3.1 that my <a href="http://github.com/rocketnia/lathe#readme">Lathe</a> (the library <a href="http://rocketnia.wordpress.com/2010/04/09/modules-multimethods-kinda-and-more-for-arc/">I introduced last time</a>) now wholeheartedly supports the Jarc implementation of Arc. This means it works on four Arc setups: <a href="http://jarc.sourceforge.net/">Jarc</a>, <a href="http://arclanguage.org/item?id=10254">official Arc 3.1</a> (which itself needs a <a href="http://arclanguage.com/item?id=10625">Windows fix</a>), <a href="http://github.com/nex3/arc">Anarki</a> (which needs the same fix), and <a href="http://github.com/conanite/rainbow">Rainbow</a>. Most of you reading this are probably <em>from</em> the Arc forum, in which case you knew all that already. :-p</p>
<p>Those are all the setups I want Lathe to support for now, but I might consider arc3f, arc2c, or another Arc implementation if I realize it&#8217;s actually active. Another complication is that quite a lot of Arc users modify one of the PLT Scheme versions of Arc (Arc or Anarki) to suit their needs. In those cases, I figure the burden of Lathe compatibility is on them if they need it.</p>
<p>Still, there is a bit of a need to add new features to Arc. To this end, Anarki, Jarc, and Rainbow have provided ways to call from Arc into the host platform (PLT Scheme, the JVM, and the JVM respectively).</p>
<p><span id="more-80"></span>In fact, if you know Jarc, the above example isn&#8217;t all that impressive. You can already do this:</p>
<pre>$ cd /path/to/jarc

$ java -server -cp \
&gt;   "jarc.jar;$GROOVY_HOME/embeddable/groovy-all-1.7.2.jar" jarc.Jarc

Jarc&gt; (groovy.util.Eval.me "2 + 2")
4</pre>
<p>On Rainbow, you can accomplish the same thing in a couple of ways:</p>
<pre>$ cd /path/to/rainbow/src/arc

$ java -server \
&gt;   -cp "rainbow.jar;$GROOVY_HOME/embeddable/groovy-all-1.7.2.jar" \
&gt;   rainbow.Console

arc&gt; (java-static-invoke "groovy.util.Eval" 'me "2 + 2")
4
arc&gt; (java-import groovy.util.Eval)
[Rainbow displays the source of the resulting macro.]
arc&gt; (Eval me "2 + 2")
4</pre>
<p>So what does Lathe get you here? Not much, I guess, but it actually does give you the ability to assign to JVM fields:</p>
<pre>arc&gt; (jv.jvm!height= (jv.jvm!java-awt-Rectangle-new 1 2 3 4) 5)
5</pre>
<p>That&#8217;s a feature that&#8217;s lacking in Jarc and in Rainbow. Lathe&#8217;s jvm.arc accomplishes it through reflection calls on <code>java.lang.reflect.Field</code> objects, and it has to do one of the worst kinds of JVM reflection: Branching on primitive types. I&#8217;m glad that&#8217;s behind me!</p>
<p>Lathe also gives sort of a nice syntax, in my opinion. The syntax prioritizes (my) intuition over consistency, in ways that unfortunately make for <a href="http://github.com/rocketnia/lathe/blob/master/arc/imp/jvm.arc">a monstrous implementation that takes just as long to fully explain</a>. Here&#8217;s the important part of the documentation, which assumes you&#8217;ve put <code>jv.jvm</code> into the global variable <code>jvm</code> through something like <code>(= jvm jv.jvm)</code>:</p>
<pre>; [blah, blah, blah, paragraphs and paragraphs of text]
;
; At long last, here are some examples:
;
; getting a static field
; jvm!javax-swing-JFrame-EXIT_ON_CLOSE
; jvm!EXIT_ON_CLOSE.jframe-instance
;
; setting a static field
; jvm!com-example-SomeClass-staticField=.new-value
; jvm!staticField=.someclass-instance.new-value
; (jvm!staticField= someclass-instance new-value)
;
; calling a static method
; jvm!java-util-Arrays-asList.array
;
; getting a top-level class as a Class instance
; jvm!java-lang-Object-class
;
; getting a static nested class as a Class instance
; jvm!java-util-HashMap-Entry-class
;
; calling a constructor
; (jvm!java-util-ArrayList-new)
;
; calling an instance method (same as a static one, but shortenable)
; (jvm!java-util-HashMap-get map key)
; (jvm!get map key)
;
; getting an instance field
; jvm!java-awt-Rectangle-x.rect
; jvm!x.rect
;
; setting an instance field
; (jvm!java-awt-Rectangle-x= rect newx)
; jvm!java-awt-Rectangle-x=.rect.newx
; (jvm!x= rect newx)
; jvm!x=.rect.newx
;
; accessing an inner class (a non-static nested class) as a Class
;   instance
; jvm!com-example-OuterClass-InnerClass-class
; jvm!InnerClass.outer!class
;
; constructing an instance of an inner class
; jvm!com-example-OuterClass-InnerClass-new.outer
; (jvm!InnerClass.outer!new)
;
; some makeshift importing
; (= jutil jvm!java-util
;    weakhash jutil!WeakHashMap-new)
; (def jweak (x)
;   (if (ajava x jutil!Map-class)
;     weakhash.x
;       (isa x 'table)
;     (let result (weakhash)
;       (each (k v) x
;         (jvm!put result k v))
;       result)
;     (err "A non-map was passed to 'jweak.")))</pre>
<p>But what this inconsistent interface gets us most of all is a different form of consistency: Greater consistency between Jarc and Rainbow. Now that the <code>jvm</code> function exists, if I want to add some other feature to Lathe that requires me to make JVM calls, I may be able to get away with writing the same code on both platforms.</p>
<p>It&#8217;s not quite as easy as that. Both platforms do certain things for you automatically, namely converting between Arc types and JVM types and deciding which JVM method/constructor best suits the Arc parameters you&#8217;ve given. An Arc library can&#8217;t easily overcome that; it can&#8217;t get its hands on certain kinds of JVM value, since they&#8217;re converted before Arc even sees them. Therefore, rather than putting abstraction inversion complexity on top of <code>jv.jvm</code>&#8216;s other complexity, I&#8217;ve had it go with the flow for now.</p>
<p>But if you happen to have Groovy in the classpath, you can drop to the JVM and rise back up to Groovy by calling <code>groovy.util.Eval.me()</code>, and you can use Groovy as a more Arc-agnostic basis for manipulating JVM objects. You can also do additional things like extending JVM classes (not just interfaces) at runtime, which otherwise you would probably have to do by fiddling with bytecode and <code>ClassLoader</code>s. Time will tell if Lathe will provide extra features when Groovy is available, but it&#8217;s pretty likely considering how much I like Groovy. ^_^</p>
<p>That was a lot of focus on the JVM side of Arc. What about PLT Scheme? Well, thanks to <a href="http://www.arclanguage.org/item?id=11838">a bug I discovered in Arc</a>, Anarki isn&#8217;t the only setup that can drop to PLT Scheme. So Lathe&#8217;s <a href="http://github.com/rocketnia/lathe/blob/master/arc/imp/sniff.arc">sniff.arc</a>, which is a home for platform detection flags, now includes four lines that implement a <code>plt</code> macro. It treats its argument as a PLT Scheme expression and returns its result, regardless of whether official Arc or Anarki is in use.</p>
<p>Both <code>plt</code> and <code>jvm</code> are set to <code>nil</code> when on an incompatible platform, and I expect that to allow for some nicely idiomatic cross-platform library code.</p>
<p>Well, it will once I discover a library I actually want to write with these things! My two ideas are a desktop GUI library, which I&#8217;m not sure I need, and a dynamic binding library, something I&#8217;m really interested in which seems to be a tough nut to crack on Rainbow.</p>
<p>P.S.: There&#8217;s another bit of progress on Lathe worth mentioning. In order to get multivals working on Jarc, which doesn&#8217;t support reinvokable continuations, I ported over an iteration library I had originally written in Groovy. It&#8217;s a pretty substantial library for building iterators when continuations aren&#8217;t available, and when they are, it also supports the <code>yield</code> coroutine style used in Python, C#, and so forth. It&#8217;s Artistic License 2.0 like the rest of Lathe. <a href="http://github.com/rocketnia/lathe/blob/master/arc/iter.arc">Check it out.</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/80/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=80&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2010/06/01/lathes-arc-to-implementation-language-ffi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>Modules, Multimethods (Kinda), and More for Arc</title>
		<link>http://rocketnia.wordpress.com/2010/04/09/modules-multimethods-kinda-and-more-for-arc/</link>
		<comments>http://rocketnia.wordpress.com/2010/04/09/modules-multimethods-kinda-and-more-for-arc/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 14:07:24 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Lathe]]></category>
		<category><![CDATA[arc]]></category>
		<category><![CDATA[long-winded]]></category>
		<category><![CDATA[technobabble]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=77</guid>
		<description><![CDATA[I&#8217;ve been doing things here or there in Arc without really having a specific plan in mind for sharing them. Most notably, I had the fundamentals of an untested Arc multimethod system laying around, which were made in an effort to collect my thoughts about Blade, a potential idea for an everything-is-a-multimethod language. And that&#8217;s [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=77&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing things here or there in Arc without really having a specific plan in mind for sharing them. Most notably, I had the fundamentals of an untested Arc multimethod system laying around, which were made in an effort to collect my thoughts about Blade, a potential idea for an everything-is-a-multimethod language. And that&#8217;s what I expect a large part of my projects to be: Approximations of a language I&#8217;d rather program in. So finally, last week I started up <a href="http://github.com/rocketnia/lathe">a GitHub repo, Lathe</a>, where I could submit miscellaneous utilities that smoothed out non-Blade languages according to my own aesthetic.</p>
<p><span id="more-77"></span>That Arc multimethod system is one of those utilities, but first&#8230;</p>
<h2>Modules</h2>
<p>I&#8217;m not very bold when it comes to polluting the global namespace, and that&#8217;s discouraged me from releasing any Arc code. Even if I pick names no one else does, I&#8217;m still limiting my own ability to give those same names different meanings in the future. If I use any specific global names, then multiple versions of my code will not be able to coexist in the same application, and that bugs me.</p>
<p>So that I could avoid this trouble, the first thing I contributed to Lathe was a module system. I have a few basic goals in mind for this system, which I&#8217;ve so far achieved:</p>
<ul>
<li>Hiding code is okay but not Arclike. An Arc module system should free code from accidental naming conflicts, not protect it from intentional ones.</li>
<li>One library should be able to declare a dependency on another library without specifying how to satisfy that dependency. For example, two libraries should be able to depend on a third library without that third library being loaded (or downloaded, compiled, etc.) twice.</li>
<li>Even if it isn&#8217;t possible to treat existing Arc libraries as modules, code written for the module system should be easy to rewrite in a more traditional way. I&#8217;m sharing Arc hacks, not committing people to a framework.</li>
<li>Some Arc code may rely on modifications to the Arc implementation, but the module system itself should not. For instance, none of my code currently drops to Scheme; in fact, it works just as well on Rainbow as it does on Arc and Anarki.</li>
</ul>
<p>Another basic property I&#8217;d like to fulfill in this module system is the ability for multiple libraries to depend on each other, which can be useful when a big project needs to be split up into more manageable chunks. I have a plan in mind for this, but I&#8217;m going to put off this plan until I work a bit more on multimethods, especially since multimethods and module systems might influence each other in subtle ways.</p>
<p>Here&#8217;s an example of the module system in action (which may also give you a bit of insight into the multimethod system):</p>
<pre>; multirule.arc

(packed:using-rels-as mt "multival.arc"
                      oc "order-contribs.arc"
                      ru "../rules.arc"

; A basic-rulebook-reducer multival takes contributions that are rules
; (which are extracted here from the 'val entries of contribution
; detail tables), it sorts those contributions using order-contribs,
; and it ultimately becomes a function that calls those sorted rules
; as a basic rulebook.
(def my.basic-rulebook-reducer (contribs)
  (let rulebook (map !val (apply join oc.order-contribs.contribs))
    (obj val (fn args
               (apply ru.call-basic-rulebook rulebook args))
         cares `(,oc!order-contribs))))

(mac my.rule (name parms . body)
  (zap expand name)
  (let (label . actualbody) body
    (zap expand label)
    (unless (and actualbody anormalsym.label)
      (= actualbody (cons label actualbody) label (uniq)))
    `(do (,mt!defmultifn-stub ,name)
         (,mt!contribute ',name ',label ,my!basic-rulebook-reducer
           (,ru!ru ,parms ,@actualbody)))))

)</pre>
<p>All the definitions are surrounded by a <code>(packed ...)</code> form, which does a couple of things: It defines the &#8220;<code>my</code>&#8221; namespace anaphorically, it executes its body at the top level, and it returns a package value that exposes that namespace.</p>
<p>The <code>using-rels-as</code> form here resolves the three dependencies <code>'(rel "mutlival.arc")</code>, <code>'(rel "order-contribs.arc")</code>, and <code>'(rel "../rules.arc")</code>, gets the package values for them, and binds <code>'mt</code>, <code>'ot</code>, and <code>'ru</code> to those packages&#8217; namespaces for the rest of the form, which it executes at the top level.</p>
<p>A dependency of the form <code>'(rel "relative/path/to/code.arc")</code> uses relative addressing. There&#8217;s a little bit of bookkeeping done behind the scenes to make this work. (Currently, this is actually the <em>only</em> form of dependency supported. It&#8217;s possible to extend the system to support things like installing libraries from the Web, requiring certain Arc implementations to be in use, requiring certain implementation patches to have been applied, or doing version number comparison, but I don&#8217;t yet have a plan in mind for those things.)</p>
<p>I&#8217;ve mentioned that <code>'my</code>, <code>'mt</code>, <code>'oc</code>, and <code>'ru</code> are bound to namespaces here. A namespace is just a macro that associates symbols to gensyms.</p>
<ul>
<li>If you pass it a symbol (&#8220;<code>my.foo</code>&#8220;), it expands into a gensym (&#8220;<code>gs1234-foo</code>&#8220;). This means you can use <code>my.foo</code> in most places you can use a variable name, except that it has to be a place where macros are expanded.</li>
<li>If you pass it a quoted symbol (&#8220;<code>my!foo</code>&#8220;), it expands into a quoted gensym (&#8220;<code>'gs1234-foo</code>&#8220;). This is useful for code generation, as you can see in multirule.arc above.</li>
<li>Finally, if you pass it a form other than a <code>'quote</code> form (&#8220;<code>(my:foo a b c)</code>&#8220;), if the car of that form is a symbol, then it expands into the same form except with a gensym at the car (&#8220;<code>(gs1234-foo a b c)</code>&#8220;). This is useful if <code>my.foo</code> is a macro; if instead you just say <code>(my.foo a b c)</code>, the Arc compiler will expand the <code>my.foo</code> ssyntax, then determine that <code>(my foo)</code> is not a symbol globally bound to a macro (since it&#8217;s a list), <em>then</em> macro-expand <code>(my foo)</code>, and you&#8217;ll end up getting a runtime error when the macro is invoked as a procedure.</li>
</ul>
<p>In order to facilitate the use of namespaces, the module system redefines <code>'def</code>, <code>'mac</code>, and <code>'safeset</code> so that they expand the names given to them, and Lathe code continues with this policy everywhere it makes sense to do so. You can see this effect in multirule.arc above, where <code>'rule</code> explicitly expands both its name and its label.</p>
<h2>Multivals, a generalization of multimethods</h2>
<p>For the time being, Lathe&#8217;s multimethod API is relatively abstract. In fact, the term &#8220;multimethod&#8221; itself indicates a method that dispatches based on the types of <em>multiple</em> parameters, and since Arc has no obvious and extensible type system to dispatch on, I haven&#8217;t attempted multimethods in this proper sense. But inasmuch as a multimethod is a method defined in <em>multiple</em> pieces, it&#8217;s a special case of what I&#8217;ll call a multival.</p>
<p>Conceptually, a multival is anything which can be defined in multiple pieces (its <em>contributions</em>). When a multival is needed, the accumulated contributions are sent to a single <em>reducer</em> associated with the multival, and the reducer&#8217;s result is used.</p>
<p>When something is defined in multiple places, it&#8217;s tough to say in general which of those definitions should have precedence or what order they should be combined in, especially when the definitions are far apart or in separate libraries (when code order becomes obscure or vague). This is a problem many multiple-definition systems like CSS and Inform 7 solve with complicated orders of precedence (like a notion of how specific a definition is) alongside patched-on ways to escape those conventions (like CSS&#8217;s <code>!important</code> and Inform 7&#8242;s procedural rules). For the purposes of solving this problem, Lathe&#8217;s multival system provides a single multival, <code>'order-contribs</code>, whose purpose is to sort multival contributions.</p>
<p>That&#8217;s right, <code>'order-contribs</code> is a multival. True to its intent to sort the contributions of every multival, it sorts <em>its own</em> contributions. It does this the hard way, by brute-forcing every permutation of its contributions (with quite a bit of pruning) until it finds an order that&#8217;s consistent with itself. If this order can&#8217;t be found, <code>'order-contribs</code> signals an error. This should cleanly model <a href="http://www.eblong.com/zarf/essays/rule-based-if/">the behavior desired by Andrew Plotkin for a rule-based rule precedence system</a>. And hey, if you can find a smarter way to do this order-finding, you can write that function and contribute it to <code>'order-contribs</code> as the only contribution. The built-in brute-force search won&#8217;t hurt you, since the factorial of one is one.</p>
<p>Finally, for those who really don&#8217;t care about <code>'order-contribs</code>, it&#8217;s opt-in. Most multival reducers Lathe defines will call <code>'order-contribs</code> right away, but there&#8217;s nothing preventing someone from defining a reducer that does no such thing. One reason for doing this is when you need to use a strange library that contributes things to <code>'order-contribs</code> that mess it up for everybody else. (When a rogue rule asserts its own precedence over all other rules, in principle it&#8217;s impossible to overcome that with another rule unless you get clever/lucky regarding the order in which the permutations are checked.)</p>
<h2>Multivals in practice</h2>
<p>I could go into the internals of defining your own reducers and contributions in Lathe, but there&#8217;s nothing particularly clever about it. There&#8217;s just a global store of multimethod contributions and reducers, along with an API for contributing to that store. And then there&#8217;s <code>'order-contribs</code>, which has similar idiosyncracies if you want to use it directly. So instead I&#8217;ll show you how this infrastructure looks on the surface, using some contrived examples:</p>
<pre>; multirule-demo.arc

(prn "starting multirule-demo")

(using-rels-as mr "../multival/multirule.arc"
               oc "../multival/order-contribs.arc"

wipe.fail

(mr:rule factorial (n)
  (unless (&lt; 0 n) (fail "The parameter isn't positive."))
  (* n (factorial:- n 1)))

(mr:rule factorial (n)
  (unless (is n 0) (fail "The parameter isn't zero."))
  1)

(mr:rule expbysquare (base exp) one
  (unless (is exp 1) (fail "The exponent isn't one."))
  (list base 0))

(mr:rule expbysquare (base exp)
  (unless even.exp (fail "The exponent isn't even."))
  (let (prevresult mults) (expbysquare base (/ exp 2))
    (list (* prevresult prevresult) (+ mults 1))))

(mr:rule expbysquare (base exp)
  ; This condition subsumes the condition for the 'one contribution on
  ; purpose, so that we can test 'prec. Since this contribution comes
  ; later in the code, it ends up farther toward the beginning of the
  ; contribution stack, and ultimately this rule would be tried before
  ; the 'one rule (catastrophically) if not for the presence of
  ; [iso (map _ '(name label)) '(expbysquare one)] in the 'prec line
  ; below.
  (unless odd.exp (fail "The exponent isn't odd."))
  (let (prevresult mults) (expbysquare base (- exp 1))
    (list (* base prevresult) (+ mults 1))))

(mr:rule expbysquare (base exp) diabolical
  (err:+ "Somehow the 'diabolical contribution to 'expbysquare was "
         "used."))

(oc.prec [iso (map _ '(name label)) '(expbysquare one)]
         [~iso (map _ '(name label)) '(expbysquare diabolical)])

(for i 0 10
  (prn "The factorial of " i " is " factorial.i "."))

(for i 1 10
  (let (result mults) (expbysquare 2 i)
    (prn "Two to the " i " gives " result " after "
         (plural mults "multiplication") ".")))

(prn "finishing multirule-demo")

nil

)</pre>
<p>First, note that this file is not set up a module, and it doesn&#8217;t hesitate to pollute the global namespace. But although it isn&#8217;t careful about what comes out of it, it is careful about what goes in; the &#8220;<code>wipe.fail</code>&#8221; line toward the beginning makes sure that <code>'fail</code> is not a macro and therefore doesn&#8217;t get macro-expanded in the following code.</p>
<p>There are only three new operators this code uses: <code>'rule</code>, <code>'fail</code>, and <code>'prec</code>.</p>
<p>The implementation of the <code>'rule</code> macro was shown further above. Essentially, it works like a normal function definition, except that multiple such definitions can coexist.</p>
<p>In order to make sure the appropriate rule is used for the given situation, any rule that doesn&#8217;t apply should call <code>'fail</code> right away. The <code>'fail</code> function is defined anaphorically within the context of a rule, and it exits the rule immediately, making its use very similar to that of <code>'err</code>. However, <code>'fail</code> and <code>'err</code> have different meanings; <code>'fail</code> signifies that this rule doesn&#8217;t apply but some other rule might, and <code>'err</code> signifies that something is <em>positively</em> wrong.</p>
<p>Another feature <code>'rule</code> provides is to label a particular rule with a given symbol, by writing that symbol unquoted after the argument list. As you can see, this is optional; the <code>'factorial</code> rules have no labels, but two of the <code>'expbysquare</code> rules do. Labeled rules have two advantages: One, they&#8217;re easier to refer to specifically from elsewhere in the code, and two, if you define multiple rules with the same name and the same label, the older ones are overwritten. The overwriting feature is especially useful at a REPL, and it was inspired by <a href="http://hacks.catdancer.ws/extend.html">an early version of Andrew Wilcox&#8217;s <code>'extend</code> macro</a>.</p>
<p>Finally, there&#8217;s <code>'prec</code>, a function that takes any number of tests and institutes a precedence order on contributions so that those which satisfy the tests come first. When there are multiple tests given, the earlier tests in the argument list have more powerful influence than the later ones.</p>
<p>A <code>'prec</code> call just works by registering a contribution to <code>'order-contribs</code>. It&#8217;s possible for this contribution to be given a label too, using the <code>'label-prec</code> macro like so:</p>
<pre>(oc:label-prec expbysquare-precedence
  [iso (map _ '(name label)) '(expbysquare one)]
  [~iso (map _ '(name label)) '(expbysquare diabolical)])</pre>
<p>If you label your precedence contributions like this, you can define precedences over precedences.</p>
<p>Furthermore, with the right setup, you should be able to store arbitrary metadata about rules at the same time as you define them (by associating the name and label of the rule to a metadata container via a global table or something) and then have much more expressive precedence rules based on that medatada, making it less necessary to write special-case precedence rules like these. This is the path I&#8217;m going to take, &#8217;cause there&#8217;s no point in having multiple definitions of something if the definitions are going to be manipulated individually.</p>
<h2>And much, much more (but not that much)</h2>
<p>Even if the module system and multival system are too monolithic or too specific for your needs, Lathe still has quite a few bite-size hacks worth looking at. Here are a few of them:</p>
<p>The <code>'global</code> function, defined in Lathe&#8217;s arc/modules/modulemisc.arc, takes a symbol and returns the value of that symbol in the global environment, or <code>nil</code> if the symbol is unbound. That&#8217;s nothing exciting; <code>(global x)</code> is just <code>(bound&amp;eval x)</code> with some error checking. What&#8217;s exciting is that <code>'global</code> has a <code>'setforms</code> entry, allowing deeply nested code to modify arbitrary global bindings. This is slightly harder than it sounds; to do it without using <code>'global</code> requires code similar to <code>(eval `(= ,x ,something))</code>, but that <code>'something</code> can&#8217;t refer to any part of the lexical context, since it&#8217;s being evaluated in the global one, so a single temporary global variable is needed to ferry the value over. The <code>'global</code> <code>'setforms</code> entry takes care of all of that.</p>
<p>The <code>'parse-magic-withlike</code> function, which is <em>also</em> defined in modulemisc.arc, is a utility for macros to use. It takes the body of a form that&#8217;s similar to Arc&#8217;s <code>'with</code>, and it extracts all bindings from the beginning of it and pairs them up in a list. If the first element of the body is a list, it behaves just like Arc&#8217;s <code>'with</code> and treats that list as a list of places and values to bind. However, the parentheses around those bindings can be omitted if all the places being bound are non-ssyntax symbols. Since a non-ssyntax symbol doesn&#8217;t make a lot of sense at the beginning of a <code>'do</code> body (unless it&#8217;s the only expression in that body), it shouldn&#8217;t be misinterpreted as a place to be bound. And the macro can still support destructuring or setforms for bindings, since the user can always wrap the bindings in a list the old-fashioned way when that feature is needed.</p>
<p>Somewhat randomly, I wrote an independent implementation of Andrew Wilcox&#8217;s <code>'extend</code> macro, which I put in Lathe&#8217;s arc/extend.arc. In addition to the <code>'extend</code> macro itself, this also provides <code>'label-extend</code>, which does the same thing but associates a unique label with the extension so that another extension with the same label will overwrite it. There was an interesting hurdle to overcome in this implementation to handle corner cases in the way Andrew Wilcox&#8217;s <code>'extend</code> binds <code>'it</code> in the body to the value of the test; I end up having to store the body as a function that takes <code>'it</code> and returns a function that takes the regular parameters, since <code>'it</code> is bound this way in the parameter list too. I haven&#8217;t needed this at all, but it was a nice exercise.</p>
<p>These snippets are great candidates for committing to Anarki. However, I don&#8217;t know where I should draw the line, I&#8217;m not bold enough to stomp into a community project carrying a module system, and because of its Rainbow support, Lathe needs a home apart from Anarki anyway. If my hacks do find their way into other projects, that&#8217;s fine, but I think their first stop will continue to be Lathe.</p>
<p>And all in all, With the comfortable structure the Lathe repo gives me, I&#8217;m hoping to have a outlet for my language design pursuits while at the same time making the results more available to the rest of the world.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/77/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=77&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2010/04/09/modules-multimethods-kinda-and-more-for-arc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>MVTron gets Xuggle-er with MediaTools</title>
		<link>http://rocketnia.wordpress.com/2009/11/07/mvtron-gets-xuggle-er-with-mediatools/</link>
		<comments>http://rocketnia.wordpress.com/2009/11/07/mvtron-gets-xuggle-er-with-mediatools/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 20:55:47 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[MVTron]]></category>
		<category><![CDATA[long-winded]]></category>
		<category><![CDATA[technobabble]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=71</guid>
		<description><![CDATA[It&#8217;s been a while since I did much with MVTron, but I took a brief look hack at it the other day, and it&#8217;s actually coming along, I think. That said, it isn&#8217;t something I&#8217;m actively working on, so there probably aren&#8217;t going to be any spectacular results or anything. Earlier, my approach to MVTron [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=71&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I did much with MVTron, but I took a brief <span style="text-decoration:line-through;">look</span> hack at it the other day, and it&#8217;s actually coming along, I think. That said, it isn&#8217;t something I&#8217;m actively working on, so there probably aren&#8217;t going to be any spectacular results or anything.</p>
<p>Earlier, my approach to MVTron was to wrap AviSynth in the hopes that it could take advantage of all the fast AviSynth plugins people have written in C. I managed to get a scene detector working that processed my test video in about twice the video&#8217;s duration. That struck me as a pretty poor performance, but I was still hopeful, and I was planning to get my plan in motion from there.</p>
<p>Well, it&#8217;s kind of embarrassing to say this, but I completely forgot about that AviSynth-Groovy success story until just now when I read <a href="http://rocketnia.wordpress.com/2009/04/05/more-slow-video-editing/">my own blog</a>. That said, this time around I duplicated that success in less than a day without interfacing to AviSynth at all, using Xuggle&#8217;s (relatively) new MediaTools API. And now I&#8217;m usually looking at processing times only 170% the test video&#8217;s duration. Thanks, Xuggle!</p>
<p><strong><span id="more-71"></span>Random-Access Pass</strong></p>
<p>It&#8217;s probably not worth mentioning this, but before I turned to MediaTools, I first tried to improve the Xuggler code I was already using. I have a random-access video class that wraps a Xuggler container and uses seek to go backwards. I&#8217;m well aware that video isn&#8217;t usually encoded for fast random access, so the idea of this interface is that, as long as you&#8217;re asking for frames in the right order, you get them as efficiently as usual, but when you need to back up, that&#8217;s still easy to do. It does a great job of abstracting away the usual packet-pushing Xuggler API&#8230; if you&#8217;re lucky.</p>
<p>The problem was that the first few frames after a seek weren&#8217;t necessarily the right ones, even if the rest of them were. Well, I tried to gloss over that by copying off a few frames after each keyframe the first time through the file, and then using the preserved ones in lieu of corrupt ones later on. It worked like a charm, but only if there was only one seek needed. Apparently, the first seek might corrupt a few frames, but seeking again after that just breaks the whole video.</p>
<p>I briefly considered having the random-access wrapper open a new Xuggler container object and fast-forward from the beginning every time it needed to seek backwards, but I passed on that for the time being, in favor of MediaTools.</p>
<p><strong>Pipelines</strong></p>
<p>The MediaTools library also &#8220;does a great job of abstracting away the usual packet-pushing Xuggler API.&#8221; Rather than trying to hide the serial access, though, MediaTools embraces it. Essentially, you build a bundle of objects that represents the data flow (e.g., source video to conversion routines to destination file), and then in one magical line you execute it.</p>
<p>A MediaTool pipeline is built using the concept of events. You make a listener and register it with an object that broadcasts events, and the broadcasting object keeps track of that reference and calls the listener with events as they happen. This is a familiar concept in Java GUI programming and probably a lot of other things (things I haven&#8217;t experienced yet), but this time around I find it funny, &#8217;cause seeing this use of listeners gave me the epiphany I needed to appreciate Haskell&#8217;s arrows. I&#8217;ve never used arrows, but I miss them already. I think MediaTools made an appropriate choice though; arrows may be a more natural abstraction, but I think they aren&#8217;t as easy to get the hang of as listeners, which defeats the purpose of an easier-alternative API.</p>
<p>(Incidentally, I think Marsyas uses a very similar pipeline metaphor. I haven&#8217;t looked deeply enough into Marsyas to draw a meaningful comparison, though.)</p>
<p>In my own MediaTools-powered code, I&#8217;m finding that I&#8217;m using absolutely no Groovy except in my sandbox scripts, and even my Groovy sandboxes are mostly copied-and-pasted from equivalent Java ones. Groovy still excels <em>after</em> the pipeline has done its job, when I want to do things like print out totals and histograms, but I think all the subclassing and put-this-one-in-that-one code is as brief in Java as it&#8217;ll ever be.</p>
<p>In Groovy&#8217;s favor, a network of listeners like this is naturally hierarchical. (It&#8217;s a bit of a pain to write a listener that waits for more than one event before doing something, since you have to manage state manually. As long as you&#8217;re managing to avoid that pain, your pipeline has a single input and several outputs that branch out from there. In fact, the &#8220;one magical line&#8221; that executes the pipeline depends on there being only one root input, and I think it would get pretty complicated with more than one.) When you&#8217;re taking a bunch of building blocks and putting them together hierarchically, you have a great candidate for a Groovy markup-style DSL.</p>
<p>The thing is, I&#8217;m not accustomed to making markup-style DSLs just yet, and even if I were, this is not the time. The listeners I&#8217;ve made and considered making have all sorts of different structures, so for the time being I don&#8217;t have many patterns worth abstracting away.</p>
<p><strong>The Guts</strong></p>
<p>So, what all did I accomplish in less than a day? Here are the details, in English about as clear as I can muster.</p>
<p><strong>Scene Detection, a Diabolical Transition</strong></p>
<p>As I mentioned, I implemented the scene detector. The algorithm I&#8217;m using is slightly different than the one I was using before. Before, I had an algorithm that took a tolerance and a clip as input and that output a list of booleans that indicated where the breaks were. However, giving the tolerance at the beginning like that was just a temporary kludge. I really want MVTron to detect the tolerance by default most of the time; having to explicitly tell it things about <em>every</em> video you give it ruins the fun that would come from just throwing it at a directory of music and videos and seeing what it came up with. In order for auto-detected tolerances to be practical, they need to be detected after the preprocessing is done, so that new and better tolerance detection methods can be swapped in without taking hours to re-scan all the footage.</p>
<p>As it turns out, translating my algorithm from tolerance-given-at-preprocessing-time to tolerance-given-never wasn&#8217;t very straightforward. Surprise surprise, right? It actually might not be the caveat you&#8217;d expect.</p>
<p>Under ideal circumstances, I would just take a difference between adjacent frames at preprocessing time, find outliers at composition time, and be done with it. However, I&#8217;m lucky enough that one of my test videos has an example of a pretty understandable phenomenon. There are frames A-B-C in this video where it&#8217;s obvious that frames A and C would constitute a scene break except that frame B is blurred almost exactly halfway between them. (I&#8217;m pretty sure it was telecined so that the pixel rows actually alternated between the two scenes, then scaled down so that those rows blended together.) This makes frame breaks A-B and B-C have intensity far below the other scene breaks, even getting dangerously close to the breaks between animation cels, but despite this, I&#8217;d rather have both A-B and B-C detected as scene breaks rather than neither.</p>
<p>The original algorithm worked by measuring all the A-C intensities as well (or else adding the A-B and B-C intensities, which in my tests has similar results), and then putting &#8220;unexpected&#8221; scene breaks detected that way (that is, A-C scene breaks without apparent A-B or B-C breaks) into the result as a special case.</p>
<p>The new algorithm doesn&#8217;t make a boolean stream until an intensity stream is finally analyzed to determine a threshold. Instead it works on combining intensity streams. In fact, it only uses the A-B intensity stream, so in a sense it combines that stream with itself. Here it is in Groovy:</p>
<pre>// Some product fuzzy logic operations, which operate on values between 0 and 1,
// inclusive. The or defined here will be used below.
def not = { 1 - it };
def and = { a, b -&gt; a * b };
def or = { a, b -&gt; not( and( not( a ), not( b ) ) ) };

// By now, diff has been defined such that
// diff == [ 0 ] + (frame break intensities gained from preprocessing) + [ 0 ].
// If there are 0 frames, then diff == [ 0 ] instead.

// The focusedDiff accentuates each intensity of diff in one of two ways: If an
// intensity is a local maximum, it's augmented with its greatest neighbor. If
// it isn't a local maximum, it's augmented with itself. This has the effect of
// holding back local maxima with small neighbors, which are crisp already.
def focusedDiff =
    numberOfFrames == 0 ? [ 0 ] : [ 0 ] + (1..&lt;numberOfFrames).collect { or(
        diff[ it ],
        Math.min( diff[ it ], Math.max( diff[ it - 1 ], diff[ it + 1 ] ) )
    ) } + [ 0 ];</pre>
<p>(For what it&#8217;s worth, since min( J, max( I, K ) ) = max( min( I, J ), min( J, K ) ), this sequence operation could be reasoned about without referring to the elements, calling it something like &#8220;an accentuation zip of a sequence by the pairwise maximum of the pairwise minimum of a zero-bookended version of itself.&#8221;)</p>
<p><strong>Scene Detection Grit</strong></p>
<p>To evaluate the numeric difference between two frames, I calculate the root-mean-square of the differences in R, G, and B values. This is the same as the root-mean-square of the pixel color differences, for a pixel difference calculation that&#8217;s proportional to the colors&#8217; Euclidean distance in the sRGB color space. My code makes it easy to swap in a better color metric (or a better frame metric altogether) if that turns out to help, but this is working just fine. I actually think it might be slightly less useful than the same metric without all the squaring and root-taking, which is closer to what I used in AviSynth (which was the average luma of the absolute difference of the frames).</p>
<p>To guess a tolerance for scene breaks, I just take the maximum frame break intensity and divide by two. This algorithm could definitely use some work, but I&#8217;ll have to test on some more videos or read up some more before I can figure out how to improve it.</p>
<p><strong>Audio Analysis</strong></p>
<p>I&#8217;m just barely understanding most of what I&#8217;m trying to do here. I read a lot about DFTs and DCTs, and I only learn enough to program something, and I guess if I can explain it to a computer then I must understand it perfectly, but it doesn&#8217;t feel that way. I think I&#8217;m shooting for a Mel-frequency cepstrum here at some point, and I have a pretty good idea of how to get one from the sample data, but I&#8217;ve had to work myself up to the concepts one at a time, and I stopped coding on this after I&#8217;d successfully invoked an FFT and made a histogram of the peak frequencies at each audio frame in a test video. (Yeah, I&#8217;ve only tested this with videos rather than music so far, mostly &#8217;cause the videos were handy and I knew I could load them.)</p>
<p>I didn&#8217;t try to write the FFT code myself. Instead I&#8217;m using a library, JTransforms. I don&#8217;t really care where I get my FFT, as long as it&#8217;s fast, accurate, and feature-complete. If I don&#8217;t have to maintain it, awesome.</p>
<p><strong>Conclusion</strong></p>
<p>The point I&#8217;m trying to make is, it probably took me about as long to write this summary as it took to try some stuff, fail, and start MVTron all over with MediaTools, and yet the MediaTools code was faster and tackled things I hadn&#8217;t even gotten around to attempting before. I think that says something for Xuggler/MediaTools.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/71/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/71/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/71/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=71&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2009/11/07/mvtron-gets-xuggle-er-with-mediatools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>Programming Language Mix-Up</title>
		<link>http://rocketnia.wordpress.com/2009/10/21/programming-language-mix-up/</link>
		<comments>http://rocketnia.wordpress.com/2009/10/21/programming-language-mix-up/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 19:11:31 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Computer Language Design]]></category>
		<category><![CDATA[interactive fiction]]></category>
		<category><![CDATA[long-winded]]></category>
		<category><![CDATA[mtg]]></category>
		<category><![CDATA[tads]]></category>
		<category><![CDATA[technobabble]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=57</guid>
		<description><![CDATA[Last time, I talked about TADS 3 and Groovy. I noted that TADS 3 had features especially suited for IF—undo support, a concise, declarative syntax for game content, a special syntax for defining IF-style command-line grammar—and some other features I really liked, but that for some reason I still felt like I preferred Groovy. Why? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=57&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://rocketnia.wordpress.com/2009/07/26/tads-vs-groovy/">Last time</a>, I talked about TADS 3 and Groovy. I noted that TADS 3 had features especially suited for IF—undo support, a concise, declarative syntax for game content, a special syntax for defining IF-style command-line grammar—and some other features I really liked, but that for some reason I still felt like I preferred Groovy.</p>
<p>Why? Not-invented-here syndrome, in a sense. The IF system I would like to work with is not nearly the system that the TADS 3 language and libraries help out with. Just to name a couple of cases, I dream of experimenting with undo history and parser grammar beyond what the TADS 3 system and grammar syntax support. This wouldn&#8217;t make TADS 3 a bad language for the job, but I expect this would make its domain-specific features into dead weight when they didn&#8217;t suit my needs, and when that happens I&#8217;m afraid I&#8217;ll find myself programming in a domain-<em>limited</em> equivalent of Groovy after all.</p>
<h2>Since Then</h2>
<p>Between the time I made that post and now, a few months have gone by, and I&#8217;ve done a lot of different things:<span id="more-57"></span></p>
<ul>
<li>I took a deeper look at Inform 7.</li>
<li>Reassured that neither TADS 3 nor Inform 7 sat perfectly well with me, I spent some time pondering what kind of IF system design I was really looking for.</li>
<li>I re-implemented my website as a PLT Scheme servlet, and in the process I taught myself PLT Scheme (not to mention what a servlet is). It turns out I have no excuse for continuation dispatching anywhere on my site yet—it&#8217;s entirely static, in fact—but that was the draw for me (not to mention that I&#8217;ve always wanted to use some kind of lisp on a project).</li>
<li>I taught myself enough to set up a VPS with an Ubuntu-Nginx-MzScheme stack so that my site would actually run. You can see it now at <a href="http://www.rocketnia.com/">www.rocketnia.com</a>.</li>
<li>I refactored some JavaScript code for a Mega Man IV and V password generator I wrote back in 2007. (There are two games, but it&#8217;s essentially one generator because the passwords have so much in common.) I fixed some potential memory leaks, separated the code into its own file (rather than dumping it in the same page as the HTML), and cleaned up the API considerably, not only for its own sake but also so that any future password generators I might make could have APIs consistent with it. And then I went and posted it on my website.</li>
<li>I spent some time working on a Game Boy disassembler in Groovy. It&#8217;s actually a pretty awesome disassembler right now, at least for my personal use, but it isn&#8217;t exactly an end-user product. It&#8217;s organized so as to be extremely configurable (to support SNES or GBA disassembly, for instance), so it&#8217;s more like a disassembler library/framework for programmers to use. I&#8217;m comfortable with that, too. After all, if you&#8217;re using a disassembler&#8230; you <em>miiight</em> be a programmer. ^_- Still, a product for programmers could still be packaged up nicely for programmers, and this project isn&#8217;t quite there yet.</li>
</ul>
<p>In this time, I was immersed in a heaping helping of languages (Inform 7, PLT Scheme, Nginx configuration files, XHTML, CSS, JavaScript, Groovy, and Game Boy assembly, not to mention that I lurk on the Arc forum and try to help out with rules debates on the Magic: the Gathering forum), and I had a bunch of thoughts about language design.</p>
<p>I was hoping one of these ideas might fester into meaningful blog post material, but the &#8220;next blog post&#8221; project hanging in the back of my mind never seemed near to completion. And my theme for this blog is projects I think about but which are potentially too grandiose for me to complete anytime soon. Irony. If only the irony of not having anything to write about writer&#8217;s block were worth writing about.</p>
<p>Instead of waiting any longer, I&#8217;ll just tell you my half-thought-out ideas and get it over with! ^_^ I may revisit them and flesh them out in the future, if I&#8217;m lucky enough to figure out how I want to do that, but for now this is what I&#8217;ve got.</p>
<h2>Couldn&#8217;t Be More Natural</h2>
<p>When I was studying Inform 7, the syntax was very overwhelming.</p>
<p>From the Wikipedia article:</p>
<blockquote><p>&#8220;Hello Deductible&#8221; by &#8220;I.F. Author&#8221;</p>
<p>The story headline is &#8220;An Interactive Example&#8221;.</p>
<p>The Living Room is a room. &#8220;A comfortably furnished living room.&#8221;<br />
The Kitchen is north of the Living Room.<br />
The Front Door is south of the Living Room.<br />
The Front Door is a door. The Front Door is closed and locked.</p>
<p>The insurance salesman is a man in the Living Room. &#8220;An insurance salesman in a tacky polyester suit. He seems eager to speak to you.&#8221; Understand &#8220;man&#8221; as the insurance salesman.</p>
<p>A briefcase is carried by the insurance salesman. The description is &#8220;A slightly worn, black briefcase.&#8221; Understand &#8220;case&#8221; as the briefcase.</p>
<p>The insurance paperwork is in the briefcase. The description is &#8220;Page after page of small legalese.&#8221; Understand &#8220;papers&#8221; or &#8220;documents&#8221; or &#8220;forms&#8221; as the paperwork.</p>
<p>Instead of listening to the insurance salesman for the first time:</p>
<p style="padding-left:30px;">say &#8220;The salesman bores you with a discussion of life insurance policies. From his briefcase he pulls some paperwork which he hands to you.&#8221;; move the insurance paperwork to the player.</p>
</blockquote>
<p>This language bears a striking similarity with English, as you might have noticed. When I see this, I can&#8217;t help but think that I don&#8217;t know what part does what, <em>exactly</em>, and that I&#8217;m fooled into reading the surface English meaning rather than the meaning inferred by the compiler. Fortunately, there are plenty of tutorials on the language, and I&#8217;m sure it&#8217;s quicker to be confident in this syntax than in some others.</p>
<p>While I was distracted by this new syntax, I remembered another syntax in the same sort of family, which I&#8217;m quite comfortable with: Magic: The Gathering card syntax.</p>
<p style="padding-left:30px;">When Elsewhere Flask enters the battlefield, draw a card.<br />
Sacrifice Elsewhere Flask: Choose a basic land type. Each land you control becomes that type until end of turn.<br />
(<a href="http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=142004">Elsewhere Flask</a>)</p>
<p style="padding-left:30px;">Split second <em>(As long as this spell is on the stack, players can&#8217;t cast spells or activate abilities that aren&#8217;t mana abilities.)</em><br />
Target creature gets +5/+5 and gains shroud until end of turn. <em>(It can&#8217;t be the target of spells or abilities.)<br />
<span style="font-style:normal;">(<a href="http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=118890">Stonewood Invocation</a>)</span></em></p>
<p style="padding-left:30px;">If a spell would deal damage to a creature or player, it deals that much damage minus 1 to that creature or player instead.<br />
(<a href="http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=3479">Benevolent Unicorn</a>)</p>
<p>It got me to thinking, just how much more can Inform 7 and other programming languages learn from games like Magic that have dynamically changing rules? Maybe some sort of tabletop-game-inspired module system could be cooked up, which would allow for compile units to contradict each other and modify each other, and even ride on the state of a dynamic system, with well-defined behavior&#8230; behavior even non-expert humans get the hang of executing.</p>
<p>Right now, it&#8217;s just a solution looking for a problem, but I imagine a tabletop-game-inspired programming language or framework would at least be especially well suited to the implementation of tabletop games, if nothing else. Inasmuch as systems like IF works and adventure games can be mocked up in tabletop game dressings, it might be a suitable fit for them, too.</p>
<h2>Don&#8217;t Pick on Lisps</h2>
<p>One thing I&#8217;ve noticed about homoiconic programming languages with s-expressions (Common Lisp, Scheme, Emacs Lisp, Clojure, Arc, HL, etc.) is that people lump them together a lot.</p>
<p>See? Even I&#8217;m doing it. (I spent the last section lumping legalese dialects together, too. What&#8217;s next? Curly-bracket languages?)</p>
<p>A seemingly popular topic among fans (or detractors) of lisps is to talk about why these languages aren&#8217;t more popular and what can be or should have been done about that. I&#8217;m finding this to be a less and less interesting topic.</p>
<p>Homoiconicity (having code be written in the same format as data literals are) is a great feature in a language if you want to manipulate code as data. Who wants to do that? Programmers. All programmers. Programming is the manual process of manipulating code as data.</p>
<p>That doesn&#8217;t mean every programmer benefits from a homoiconic language. It just means, for all the programmers, computer scientists, mathematicians, and philosophers in the world, there are a <em>lot</em> of ways to imagine manipulating code as data (in fact, an insurmountable amount, inasmuch as we would like a language to solve the halting problem), and so a homoiconic language&#8217;s work is never done.</p>
<p>Lisps are doing fine. There is no flaw that binds and dooms them all. But they&#8217;re not a great end-all and be-all either.</p>
<p>Yes, I&#8217;m totally a hypocrite for writing this. I&#8217;m talking about lisps without talking in-depth about features of lisps. That&#8217;s why I&#8217;ve been putting off posting this; I figured I&#8217;d come up with something better to say. And I may, but then that would do better as a post of its own rather than one polluted with this rhetoric. ^_^</p>
<h2>CSS Is a Hammer, and Keyword Parameters Look like a Nail</h2>
<p>I was refactoring my Mega Man IV and V password generator JavaScript code, just <em>mind</em>ing my <em>busi</em>ness, when suddenly I discovered the joy of keyword parameters.</p>
<p>I wanted the API to be useful in case someone wanted to put multiple copies of one or both generators on the same page, but that wouldn&#8217;t be possible under the current setup, which required every form field to have a specific <code>id</code> attribute. Not only would duplicated <code>id</code> attributes on a single page be bad XHTML, but it would also make it impossible for the two generators to distinguish those fields from each other. My solution, for the moment, was to add a parameter to the generator initializer that would specify a prefix to put on each of the <code>id</code>s it expected. This way, two generators could be initialized with different prefixes, and the fields could be labeled in a way that wasn&#8217;t ambiguous.</p>
<p>However, this is not a solution that gives complete control to the person using the API. For instance, maybe someday someone will want to use very specific <code>id</code>s on their page for some crazy-but-true reason, and it would be nice if they could specify each and every one of those <code>id</code>s for the initializer&#8230; or maybe even a callback function that accepts <code>id</code>s and returns references to page elements on the fly.</p>
<p>Now I have three ideas for how to provide this customization point, one with a quick syntax (just a single prefix string) that probably suffices for all actual cases, one (an <code>id</code>-to-<code>id</code> map) that&#8217;s nice for some offbeat cases, and one absurdly powerful option (a callback) that represents what all the other options would ultimately be used to generate anyway. Which should I choose?</p>
<p>Well, I had just come out of programming my website in Scheme, where I had gotten used to using keyword parameters to make them optional.</p>
<p>Also, I couldn&#8217;t help but notice that CSS gets away with having a whole lot of border properties that all represent various parts of the same information:</p>
<pre>border
border-top        border-right        border-bottom        border-left

border-style
border-top-style  border-right-style  border-bottom-style  border-left-style

border-color
border-top-color  border-right-color  border-bottom-color  border-left-color

border-width
border-top-width  border-right-width  border-bottom-width  border-left-width</pre>
<p>I chose to take a lesson from CSS and have the API potentially support many different keyword parameters all for the same thing, giving an error if the caller overspecifies the parameters in a way that doesn&#8217;t make sense. Having made that plan, I implemented just the prefix option (all I need so far for personal use) and moved on with my life.</p>
<p>I explained all this because it got me thinking about the relationship between keyword parameters and metadata, as exemplified by CSS. When you&#8217;re using CSS and HTML, you &#8220;tag&#8221; your HTML tags with class keywords and define what those keywords mean in the CSS. Many of these keywords, like border, were taken care of by HTML attributes before CSS came along. Those attributes are no longer necessary because CSS essentially sets them for you. (Technically, it&#8217;s more the other way around, I think—as in, style-like HTML attributes are less fundamental to the document&#8217;s style representation than CSS is—but I&#8217;m going to pretend for now.)</p>
<p>In Groovy, a common idiom is to use &#8220;markup,&#8221; declarative code that&#8217;s shaped like XML. A tag is created by calling a method (the tag&#8217;s name) with some keyword arguments (the tag&#8217;s attributes) and a closure (the tag&#8217;s body), which can contain more method calls like this one. This is done to generate XML code and to construct Swing GUIs, for instance, and it can be used for other kinds of in-language DSLs as well. Regular Groovy code fits right in with this, so it&#8217;s easy to use variables and looping constructs for templates and repeated sections.</p>
<p>(I haven&#8217;t tested any of the following Groovy, and it isn&#8217;t very beautiful code in some places, but the general syntax is all I&#8217;m trying to show anyway.)</p>
<pre>def show = myMarkupBuilder.slideShow( defaultDuration: 2000.ms ) {
    img( src: "normal-photo.jpg" )
    img( src: "crazy-photo.jpg", zoomFactor: 2, rotationDegrees: 40 )
    vectorArt {
        int r = 10;  // radius of a single circle, and margin between circles
        int n =  5;  // number of circles
        rectangle( left: 0, top: 0, width: 200, height: 4 * r, color: BLUE )
        for ( x in (0..&lt;n).collect { (it * 3 + 1) * r } )
            ellipse( left: x, top: r, width: 2 * r, height: 2 * r, color: YELLOW )
    }
}</pre>
<p>But can it do what CSS does?</p>
<p>Before I answer that, I should mention that Nginx configuration files use a syntax very similar to both this and CSS. It&#8217;s a header with a tag name and some parameters, followed by a body area within curly brackets, or in some cases followed by no body at all. (Didn&#8217;t I tell you there&#8217;d be curly-bracket languages? Only one of them is a programming language, but still.)</p>
<p>Back to the question: Can Groovy markup take advantage of CSS techniques? Actually, it can simulate parts of CSS without much effort. For instance, here&#8217;s a simple way to define parameters in one place and use them in another, achieving is the kind of abstraction CSS classes provide:</p>
<pre>def briefClass = [ duration: 200.ms ];
def subliminalClass = [ duration: 24.ms ];
def crazyClass = subliminalClass + [ center: [ 200, 200 ], src: "crazy-photo.jpg" ];

// A class maker like this can be used when the parameters you want to specify when
// defining the class aren't necessarily the parameters the markup method accepts.
def ellipseClassMaker = { Map options -&gt;
    if ( options == null || options.empty ) return [:];
    return options.collect { k, v -&gt; (
        if ( k == "radius" &amp;&amp; v in Number )
            return [ width: v * 2, height: v * 2 ];
        return [ (k): v ];
    ) }.sum();
};

def sampleCircleClass = ellipseClassMaker( radius: 200, color: PURPLE );

def show = myMarkupBuilder.slideShow( defaultDuration: 2000.ms ) {
    img( src: "normal-photo.jpg" )
    img( briefClass + [ src: "brief-photo.jpg" ] )
    for ( frame in 0..40 )
        img( crazyClass + [ zoomFactor: 1 + frame / 40.0, rotationDegrees: frame ] )
    vectorArt { ellipse( sampleCircleClass + [ left: 20, top: 20 ] ) }
}</pre>
<p>Unfortunately, this still doesn&#8217;t achieve a large part of what makes CSS great. CSS can style an HTML document without using CSS classes at all, by using selectors that apply to nodes based on those nodes&#8217; names and attributes, and by selecting nodes based on their positions relative to nodes from another selection. This sort of recursive data structure querying is a natural fit for Groovy, but if you want to do a query and apply a style, you depend the markup builder to provide enough of the XML-shaped data directly in its result for you to find and modify. And even then, you can&#8217;t get all the loop and variable information out of the plain Groovy code you used. (Actually, Groovy <em>does</em> let you manipulate Groovy code as data, but it isn&#8217;t easy yet.)</p>
<p>So part of me is wondering, just like with the tabletop-game-inspired programming system, what a stylesheet-inspired programming system would be like. What&#8217;s a superficial enough parameter in the code that it&#8217;s worthwhile to pretend it isn&#8217;t there and let a stylesheet handle it? Hmm, it seems like that would cover just the same (exc)use people find for using global variables, heh. It could also specify what namespace a part of the program uses, but then module import lines do that already. I imagine it could be used to separate the concept of a program from its optimization, in a way that may be similar to Common Lisp &#8220;declarations&#8221; (not that I&#8217;m familiar with those), but I think optimization would need more extensive program transformations than just parameter insertion, so it would just end up being a macro system at some point.</p>
<p>In the end, I don&#8217;t really have a clue what CSS-style programming would be good for. As with all these ideas, though, I guess I&#8217;ll have it at the back of my mind for when it&#8217;s ready.</p>
<div id="_mcePaste" style="overflow:hidden;position:absolute;left:-10000px;top:2170px;width:1px;height:1px;">
<pre>width</pre>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/57/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=57&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2009/10/21/programming-language-mix-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>TADS vs. Groovy</title>
		<link>http://rocketnia.wordpress.com/2009/07/26/tads-vs-groovy/</link>
		<comments>http://rocketnia.wordpress.com/2009/07/26/tads-vs-groovy/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 13:42:27 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Computer Language Design]]></category>
		<category><![CDATA[interactive fiction]]></category>
		<category><![CDATA[long-winded]]></category>
		<category><![CDATA[tads]]></category>
		<category><![CDATA[technobabble]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=50</guid>
		<description><![CDATA[After thinking a long, meandering thought process starting from Groovy Science, wandering through programming language design, and somehow following a segue into interactive stories again, a friend re-sparked my interest in IF (interactive fiction). I&#8217;ve gotten absorbed reading about IF theory and practice before, but that was about five years ago, and now I know [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=50&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After thinking a long, meandering thought process starting from Groovy Science, wandering through programming language design, and somehow following a segue into interactive stories again, a friend re-sparked my interest in IF (interactive fiction). I&#8217;ve gotten absorbed reading about IF theory and practice before, but that was about five years ago, and now I know much more about programming and a little bit more about writing. So I downloaded the TADS 3 and Inform 7 SDKs and some IF interpreters, and I got to work reading the developer reference material and actually playing some games, including <a href="http://adamcadre.ac/if.html"><em>Photopia</em></a>, <a href="http://jayisgames.com/games/ifiction/game/violet"><em>Violet</em></a>, <a href="http://parchment.googlecode.com/svn/trunk/parchment.html?story=http://parchment.toolness.com/if-archive/games/zcode/Glass.zblorb.js"><em>Glass</em></a>, and <a href="http://www.inform-fiction.org/I7Downloads/Examples/alabaster/index.html"><em>Alabaster</em></a>.</p>
<p>One of the first things I noticed about the IF languages was that superficially, TADS 3 the language is incredibly close to Groovy. It uses C-style imperative syntax, it has closures, it uses dynamic typing, it minimizes the difference between properties and methods, and it has what look like interpolated strings (which print automatically, meaning it takes a bit of output-rerouting to use them for anything else). Now, I&#8217;m not saying these are all great features, but I knew right away that if I was going to be comfortable enough in any IF language to implement the kinds of crazy things I find myself wanting to implement all the time, it was going to be TADS. I could port my general-purpose Groovy code to TADS as I needed to.</p>
<p><span id="more-50"></span>With that thought on my mind, I realized: Could I port the TADS IF libraries to Groovy? Maybe Groovy could provide the wonderful land of Java libraries and cross-platform-ness that it has, and maybe TADS could provide the wonderful parser it has, and maybe Inform could provide inspiration for some wonderful relational database approaches or something, and they could all come together in a sweet train wreck of paradigms. Sounds good to me&#8230; except that Groovy isn&#8217;t (in my typical experience) <em>capable</em> of all that TADS is as a language:</p>
<ul>
<li>Looping through every existing object is a built-in language feature of TADS, and it makes sense because a game in TADS is primarily composed of a whole lot of singleton objects that get reattached to each other in various ways over the course of a game session. (I suppose the same could be said of a lot of game engines.) It&#8217;s like having each superclass keep a list of weak references to its singleton subclass instances. Do draw another comparison, it&#8217;s like every class is an enum.</li>
<li>TADS lets you view the stack trace. You can see which functions are being called, which arguments they&#8217;re being passed, where they are in the source code, and maybe a couple of other things (but conspicuously, you can&#8217;t see local variables). I think the primary use is for printing stack traces, but I get the impression that it&#8217;s also capable of the kind of <a href="http://www.inform-fiction.org/I7/doc276.html">&#8220;rule for printing the name of the lemon sherbet while listing contents&#8221;</a> antics that Inform 7 uses (although I do suspect that usage would horribly confuse TADS programmers).</li>
<li>The syntax for declaring a bunch of simple singletons in a hierarchical is-in relationship is pretty much ideal, in my opinion. It&#8217;s about as straightforward-looking as YAML, and yet it&#8217;s the same syntax that&#8217;s used for every object in the program.</li>
<li>There&#8217;s a special syntax for specifying cross-referenced grammar rules for the purposes of parsing IF commands. I don&#8217;t think it&#8217;s enormously expressive—it&#8217;s BNF without frills like the Kleene star, and subclassing <code>GrammarProd</code> to help with the odd cases looks to be tempting but impossible—but apparently it gets the job done. And with the help of the reflective <code>getGrammarInfo()</code>, you can hijack the whole BNF-style syntax system and interpret it manually, confounding those poor traditional TADS programmers any way you see fit.</li>
<li>TADS has undo! Sheesh! What programming languages can boast that? Hmmm&#8230; okay, anything with program-wide continuations or syntax-friendly monads can, but only sometimes.</li>
</ul>
<p>With all this in TADS&#8217;s favor, is there any reason for me not to switch? Well, for my general programming purposes, there are a few that would come up every so often: lack of thread support, lack of operator overloading, lack of AST transformations, etc. But for the purposes of my IF writing, there were two excuses that nagged at me:</p>
<ul>
<li>I feel like I need namespaces. Eventually, <a href="http://rocketnia.wordpress.com/2009/04/26/dun-dun-dunnnnn/">I want to make or witness a gargantuan interactive story</a> with, say, hundreds of hand-written multilinear conversation scripts. I don&#8217;t have any actual experience making that kind of story, but I&#8217;m pretty sure it&#8217;s essential to reuse the same names in similar situations. That way you can develop banter on the side in one big brainstorming pool and gradually slip them into bigger conversations like pieces of a jigsaw puzzle without having to worry about introducing name conflicts among subtly different versions of the same basic concept.</li>
<li>I feel like I need <em>better</em> undo support. The comment on <code>undo()</code> in the TADS system file tadsgen.h says that it&#8217;ll &#8220;undo all changes to persistent objects, up to the most recent savepoint,&#8221; but then it goes on to say that some early undo data might become unavailable because &#8220;The system automatically limits the UNDO log&#8217;s total memory consumption, according to local system parameters.&#8221; If my intuition is right all the UNDO log needs to know is the game transcript plus whatever hidden information was used to determine nondeterministic branching, then the UNDO log shouldn&#8217;t be nearly big enough to warrant being recycled for the sake of memory. In fact, I consider it to be the last resort; in case of a memory crisis, if at least the transcript can be dumped, then all the live data of the player&#8217;s session, complete with undo capability, can be recovered from that. I fear that what must be happening is that the TADS UNDO log keeps several snapshots of all the game&#8217;s memory, or at best keeps tabs on events like object creation and property modification.</li>
</ul>
<p>Alas, these are only excuses. I&#8217;m pretty sure the namespaces I&#8217;m looking for can be implemented reasonably well using nested objects, and whatever undo functionality I could implement in Groovy, if it&#8217;s any improvement at all, could just be implemented in TADS in almost exactly the same way.</p>
<p>So why do I still feel like I&#8217;d be better off in Groovy? Existing Java graph theory libraries to mooch off of? Potential code reuse in story-intensive MU* servers? I don&#8217;t know. It&#8217;s just an irrational feeling, I think.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/50/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=50&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2009/07/26/tads-vs-groovy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8220;Dun, Dun, DUNNNNN&#8221;</title>
		<link>http://rocketnia.wordpress.com/2009/04/26/dun-dun-dunnnnn/</link>
		<comments>http://rocketnia.wordpress.com/2009/04/26/dun-dun-dunnnnn/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 14:19:20 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[Mikkamon]]></category>
		<category><![CDATA[long-winded]]></category>
		<category><![CDATA[the fourth wall]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=43</guid>
		<description><![CDATA[A few weeks ago, I was watching Lost, and I thought I heard the TARDIS showing up in the show. (At least, I thought it would&#8217;ve been awesome if it did. XD ) At the end of a particular scene, someone said something particularly dramatic, and then there was a &#8220;whoooooOOOSH&#8221; and the scene changed. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=43&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, I was watching Lost, and I thought I heard the TARDIS showing up in the show. (At least, I thought it would&#8217;ve been awesome if it did. XD ) At the end of a particular scene, someone said something particularly dramatic, and then there was a &#8220;whoooooOOOSH&#8221; and the scene changed. That sound happened several times more during the episode, and despite all the &#8220;It&#8217;s the TARDIS! The TARDIS is <em>everywhere</em>!&#8221; entertainment I was having, I admitted in my heart of hearts that this was just Lost&#8217;s way of making the dramatic twists sink in.</p>
<p>Pretty soon, I noticed the same kind of thing happening in all kinds of shows, including Chuck and (I think) CSI. There seems to be a tendency toward a kind of rising hum or twang. Yet, that&#8217;s not the only option; Boston Legal&#8217;s score does the same thing, but it&#8217;s composed of jazzy vocals and stuff.</p>
<p>So, you&#8217;ve got rising action, a twist, <a href="http://www.youtube.com/watch?v=a1Y73sPHKxw">an obligatory sound effect</a>, and a quick scene change. I guess it&#8217;s a formula.</p>
<p>So why do I bring it up? I&#8217;ll get to that in a second. <em>(Er, make that several seconds. -Future Me)</em></p>
<p><span id="more-43"></span>There&#8217;s a project, Mikkamon, I&#8217;ve had in mind for several years now. As a picky reader of interactive stories (picky to the point of not doing it as often as I&#8217;d like to), I want to find a work that meets the following criteria:</p>
<ul>
<li><strong>It should be a simulation.</strong> An interactive story doesn&#8217;t technically have to give me adequate evidence with which to make an informed decision&#8230; but that kind of interactive story accomplishes little more than purely spectator story does.  I might turn the page, but I can&#8217;t blame myself for what happens on the other side. In order for my involvement to make a real difference, there needs to be the sense of a real underlying formula that I&#8217;m manipulating.</li>
<li><strong>It should enable me to be myself.</strong> First of all, it shouldn&#8217;t be a contest. If there&#8217;s only one &#8220;right&#8221; way to get from here to the final act, I&#8217;m having a moral shoved down my throat. Second of all, it should really be <em>me</em> in the main character&#8217;s seat, not some everyman protagonist. I&#8217;m not really capable of being myself unless I&#8217;m capable of frankly asserting to the other characters that they&#8217;re all fictional.</li>
<li><strong>It should have meaningful characters.</strong> Video games typically dodge the issue of characters. If the point of the experience is to run and jump, then by golly, the player should be worried about running and jumping, not about how Goomba A is going to respond to seeing Goomba B dive off a cliff. As such, games can get by with having extremely shallow characters who each do one thing and do it consistently. If the game I&#8217;m playing isn&#8217;t so much a game as it is a story, then what I&#8217;m worrying about <em>is</em> character interaction in the first place, and so I need a different sort of character.</li>
<li><strong>It should support a well-crafted plot structure.</strong> If the reader&#8217;s character <em>is</em> the reader and the reader is allowed to do pretty much anything, the plot is probably going to suffer a little no matter what the author does. Despite that complication, I think it&#8217;s essential that this interactive plot compensate for that, somehow channeling the reader&#8217;s own actions into consequences that will persuade him or her to proceed to act in the fashion of an archetypical character. Just because the reader is allowed to break the fourth wall doesn&#8217;t mean the fourth wall will sit back and take it. One of the ultimate goals of this is that if a reader wants to show another reader what he or she has done, the other reader should find it interesting.</li>
<li><strong>It should focus on communicating specifically to me.</strong> What&#8217;s the point of having a story be interactive if it&#8217;s still trying to say the same things to everybody? Since I&#8217;m essentially telling it all about myself, the story should figure out who I am and guide me on a tailor-made spirit quest through some of my toughest dilemmas. This requirement goes hand in hand with requiring the plot to be well-crafted: As long as the reader and the protagonist are the same person, the protagonist&#8217;s struggle shouldn&#8217;t just be an allegory for one of the reader&#8217;s struggles. It should be <em>the</em> reader&#8217;s struggle. I don&#8217;t know if I should require this too strongly. If the story offends absolutely everybody who picks it up and the way they &#8220;fix it&#8221; is by putting it back down (i.e. refusing to assume the mantle of hero), I guess it won&#8217;t be very meaningful for anybody.</li>
<li><strong>It should allow me to micromanage my character.</strong> Significant plot interaction in video games, if it happens at all, happens only two or three times in the entire game, in my experience. Interaction in visual novels I&#8217;ve played (read: tried to play) is appalling; I&#8217;m given a choice once every five minutes, and the rest of the time the narrator drones on and on about what I&#8217;m supposedly doing. Gamebooks and the odd non-visual-novel game disc I&#8217;ve gone through usually provide interaction points once per dramatic encounter, which makes them sorta cool, but then they go and spoil it by having several of the &#8220;wrong turns&#8221; lead to instant death. The way I see it, interactive fiction (the text-based kind), with its &#8220;ASK SALLY ABOUT DEATH RAY&#8221; tech in combination with finely-branched conversation trees, has what I&#8217;m looking for here.</li>
<li><strong>Finally, it should be humongous.</strong> In particular, I want to see something with enough content and depth to fill a 26-episode 22-minute-per-episode TV cartoon show. I estimate that most video game RPGs I&#8217;ve played seem to have approximately enough for 52 such episodes, but they have very little plot branching to deal with; everybody sees the same 52 episodes every time. If I want branches to occur several times per conversation, and if I want readers to be essentially capable of doing whatever they want to do, with a medley of intimately personalized plots scrambling to keep up with them, then there&#8217;s going to be a whole lot of branching going on. Given the rest of the requirements, this one might be hastily scrapped for being ridiculous, and yet I think it&#8217;s actually intrinsically successful. I think it probably takes about 26 episodes&#8217; worth of constant input (and 26 episodes&#8217; worth of subplots) for an interactive story to comprehend a reader and produce something awesome for him or her&#8230; and besides, if I make a meaningful impact on the story in the first 10 episodes, I&#8217;m spending the next 16 in a world I really like and care about.</li>
</ul>
<p>Ooh, ooh. I just distracted myself. Maybe the 26 episodes should be divided into three general-purpose acts. In the first act, the reader does pretty much whatever he or she wants to do and has the chance to make an impact on the world. In the second act, based on what impact was made, the story has determined what the reader&#8217;s preferences are and injects something that will threaten the reader&#8217;s now-home. In the third act, based on the reader&#8217;s responses to the second act&#8217;s terrorism, either the reader or some other character has become a formidable proponent of some cause or other, so a final countdown commences and, well, stuff happens. It&#8217;s not easy to be specific about the end, lol.</p>
<p>Anyway, what does all this have to do with dramatic sound effects? At this point (if you&#8217;ve been paying attention ^_- ) it&#8217;s probably at least a little obvious. The main hurdle with writing an interactive story like the one I&#8217;m looking for is that branches too fast and for too long. If it&#8217;s 26 episodes long and it has a yes-or-no branch merely once per episode, that&#8217;s 2^25 possible game states during the final episode.</p>
<p>A simple gamebook can&#8217;t possibly handle the full complexity of that. (Imagine, &#8220;If you choose not to, turn to page 353,261,763!&#8221;) Recycling of material and some more intensive corner-cutting mechanisms are in order. Two such mechanisms I&#8217;ve thought about are as follows:</p>
<ul>
<li>The reader&#8217;s character doesn&#8217;t have to be in every scene. (Every conversation without that character is a conversation with no branching.) Plenty of stories cut from one set of characters to another, and I don&#8217;t see why this one needs to be any different. In fact, it <em>adds</em> some potential dramatic questions: Does the reader take advantage of his or her knowledge of other characters&#8217; secret conversations or not? How does the reader explain away that ESP if he or she does use it? How do the other characters react if they know the reader might be listening in at any moment?</li>
<li>Procedural generation needs to be just about everywhere. The layout of an episode needs to be procedurally generated in order to account for the author-unpredictable combinations of actions that might take place during a single episode, and character actions need to be procedurally generated in order to account for whatever that character might believe and feel at the time. Even dialogues/scenes, which the characters theoretically determine for themselves, probably need to have procedural nudging (&#8220;coaching&#8221;?) to make sure that they flow nicely and fit snugly into larger plots.</li>
</ul>
<p>The dramatic sound effect and, more specifically, the &#8220;pithy comment, beat, cut&#8221; pattern it&#8217;s used in are probably pretty useful to keep in mind when trying to implement both of these mechanisms at once.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=43&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2009/04/26/dun-dun-dunnnnn/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
		<item>
		<title>And So MVTron Discovers Marsyas</title>
		<link>http://rocketnia.wordpress.com/2009/04/05/and-so-mvtron-discovers-marsyas/</link>
		<comments>http://rocketnia.wordpress.com/2009/04/05/and-so-mvtron-discovers-marsyas/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 03:56:14 +0000</pubDate>
		<dc:creator>Ross Angle</dc:creator>
				<category><![CDATA[MVTron]]></category>

		<guid isPermaLink="false">http://rocketnia.wordpress.com/?p=41</guid>
		<description><![CDATA[I&#8217;ve been looking over audio analysis techniques, wrapping my mind around how exactly I might go about implementing (or finding someone else&#8217;s implementation of) an FFT or DWT, getting to the point where I can understand this abstract, and I notice something there. The writers of that used something called MARSYAS. What&#8217;s that? Well, Marsyas [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=41&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking over audio analysis techniques, wrapping my mind around how exactly I might go about implementing (or finding someone else&#8217;s implementation of) an FFT or DWT, getting to the point where I can understand <a href="http://soundlab.cs.princeton.edu/publications/2001_amta_aadwt.pdf">this abstract</a>, and I notice something there. The writers of that used something called MARSYAS. What&#8217;s that?</p>
<p>Well, <a href="http://marsyas.sness.net/">Marsyas</a> is an open-source C++ project that apparently is exactly as ambitious as MVTron would like to be in exactly the same ways. Although its main focus is music and other audio, apparently there&#8217;s MarsyasX, a branch or something, which is a reimagining of Marsyas to be more video-inclusive. Considering Marsyas&#8217;s seeming focus on feature extraction, similarity detection, and&#8230; well, all kinds of stuff, it seems like MVTron would be just another application in the sea over there. That takes a lot of (self-inflicted) pressure off of me as a lone programmer. :-p</p>
<p>It almost looks at this point like MVTron will end up being a project entirely submerged in Marsyas, maybe even to the point that it&#8217;s written in C++&#8230; but I guess I shouldn&#8217;t be so hasty. I&#8217;ve only just heard of Marsyas, and besides, there&#8217;s an entry on <a href="http://marsyas.sness.net/community/ideas">their ideas page</a> calling for &#8220;Porting the Marsyas dataflow architecture to Java.&#8221; ^_-</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rocketnia.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rocketnia.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rocketnia.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rocketnia.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rocketnia.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rocketnia.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rocketnia.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rocketnia.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rocketnia.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rocketnia.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rocketnia.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rocketnia.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rocketnia.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rocketnia.wordpress.com/41/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rocketnia.wordpress.com&amp;blog=3890718&amp;post=41&amp;subd=rocketnia&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rocketnia.wordpress.com/2009/04/05/and-so-mvtron-discovers-marsyas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6a20d6f3edddf6e1fdd6479b4c2a0742?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=PG" medium="image">
			<media:title type="html">rocketnia</media:title>
		</media:content>
	</item>
	</channel>
</rss>
