<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>ElasticDog.com</title>
	
	<link>http://elasticdog.com</link>
	<description>Imagine Something Clever</description>
	<lastBuildDate>Thu, 04 Dec 2008 07:09:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/elasticdog" /><feedburner:info uri="elasticdog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Beginning Factor – Shufflers &amp; Combinators</title>
		<link>http://feedproxy.google.com/~r/elasticdog/~3/whNJ5l21pno/</link>
		<comments>http://elasticdog.com/2008/12/beginning-factor-shufflers-and-combinators/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 05:59:35 +0000</pubDate>
		<dc:creator>Aaron Schaefer</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Factor]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://elasticdog.com/?p=160</guid>
		<description><![CDATA[In the previous installment of Beginning Factor, we discussed some of the attributes of stack-based languages and the syntax for defining words in Factor. This time around, I&#8217;d like to introduce stack shufflers, quotations &#038; combinators, and touch on some more basic data types and their properties.
Up until now, we&#8217;ve essentially been using Factor as [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://elasticdog.com/2008/11/beginning-factor-introduction/">previous installment</a> of Beginning Factor, we discussed some of the attributes of stack-based languages and the syntax for defining words in Factor. This time around, I&#8217;d like to introduce stack shufflers, quotations &#038; combinators, and touch on some more basic data types and their properties.</p>
<p>Up until now, we&#8217;ve essentially been using Factor as an overqualified <abbr title="Reverse Polish Notation">RPN</abbr> calculator. I just wanted to make sure that you don&#8217;t underestimate Factor because of these particular examples; Factor is an extremely capable and modern language that can be used for everything from web applications, to game development, to complex text parsing, and so on. I&#8217;m purposefully using over-simplified examples as a means to demonstrate specific points about the language. Stick with me, and I assure you the examples will gradually get more expressive.</p>
<h2 id="shufflers">Stack Shufflers</h2>
<p>Because of Factor&#8217;s stack-based nature, you sometimes need the ability to rearrange or copy items in the stack to ensure that they are in the correct position for future use. The way to go about this is a group of words called &#8220;stack shufflers&#8221;.</p>
<p>Much like the name implies, stack shufflers are merely words that change the order (or number) of the items on the top of the stack. It is said that shuffle words &#8220;control the flow of data between words that perform actions.&#8221; In fact, you already know one stack shuffler&#8230; <code>drop</code></p>
<p>There are three basic varieties of stack shufflers. Here they are along with the most commonly used word for each type:</p>
<ol>
<li>
		Removing Shufflers</p>
<dl>
<dt><code>drop</code> <i>( x &#45;&#45; )</i></dt>
<dd>removes the top item from the stack and discards it</dd>
</dl>
</li>
<li>
		Duplicating Shufflers</p>
<dl>
<dt><code>dup</code> <i>( x &#45;&#45; x x )</i></dt>
<dd>duplicates the top item on the stack</dd>
</dl>
</li>
<li>
		Permuting Shufflers</p>
<dl>
<dt><code>swap</code> <i>( x y &#45;&#45; y x )</i></dt>
<dd>exchanges the positions of the first and second items on the top of the stack</dd>
</dl>
</li>
</ol>
<p><img src="/images/2008/12/stack-swap.png" alt="Swapping Two Items on the Top of a Stack" width="554" height="257"></p>
<p>&#8230;and here are a couple of word definitions that use these shufflers appropriately:</p>
<pre><code>: sq ( x -- y )
    dup * ;

: neg ( x -- -x )
    0 swap - ;</code></pre>
<p></p>
<pre><code>(scratchpad) <strong>5 sq .</strong>
25
(scratchpad) <strong>1 neg .</strong>
-1</code></pre>
<p></p>
<h3 id="caveats">Caveats</h3>
<p>There are many more <a href="http://docs.factorcode.org/content/article-shuffle-words.html">shuffle words</a> that support intricate rearrangements and the duplication/removal of multiple items from differing locations within the stack. The problem is, <em>code that is full of stack shufflers can easily become confusing</em>. In general, you should try to minimize the use of stack shufflers to keep things understandable.</p>
<p>Of course there are exceptions to that rule, times when shufflers make the most sense, but the <em>preferred</em> alternative to complicated stack shufflers is the use of a &#8220;combinator&#8221; that fits your use case. That said, combinators will take a bit of explaining&#8230;</p>
<h2 id="quotations">Quotations</h2>
<p>Before we can get to the idea of combinators, we first have to discuss quotations:</p>
<pre><code>(scratchpad) <strong>5 [ "hello" print ] times</strong>
hello
hello
hello
hello
hello</code></pre>
<p></p>
<p>In this example, <code>[ "hello" print ]</code> is a quotation.</p>
<p>In layman&#8217;s terms, a quotation is a way to encapsulate a snippet of code so it doesn&#8217;t get called right away, but can be passed around on the stack and called later. The computer science term for this is an &#8220;anonymous function&#8221;. It&#8217;s referred to as &#8220;anonymous&#8221; because it is fundamentally a word that has no name.</p>
<p>If we didn&#8217;t have quotations, that same example would get ugly real fast:</p>
<pre><code>(scratchpad) <strong>"hello" dup dup dup dup print print print print print</strong>
hello
hello
hello
hello
hello</code></pre>
<p></p>
<p>Imagine if you wanted to print &#8220;hello&#8221; 1000 times!</p>
<p>To create a quotation, you just surround your code snippet with square brackets, and it will be pushed onto the stack: <code>[ ... ]</code>. In order to do anything useful with that quotation once it&#8217;s on the stack, what you need is a combinator.</p>
<h2 id="combinators">What is a Combinator?</h2>
<p>A combinator is just a fancy name for a word that takes a quotation as one of its inputs. In the example above, <code>times</code> is a combinator which takes an integer (<i>n</i>) and a quotation from the stack, and it calls that quotation <i>n</i> times.</p>
<p>Factor uses quotations &#038; combinators extensively for conditionals, sequence traversal, namespaces, closures, and more&#8230;but that&#8217;s jumping the gun a bit. Before we dive into all of that, I&#8217;d like to get back to the idea of minimizing the use of stack shufflers by replacing them with appropriate combinators instead.</p>
<h2 id="intent">Combinators That Express Intent</h2>
<p>While our code examples thus far have been easy to follow, when you start tackling more realistic problems, stack shufflers <em>will</em> begin to obfuscate your code. If we can represent our intentions consistently with a combinator instead, then code becomes cleaner and you can consequently focus more on your problem domain and less on mentally organizing your stack.</p>
<p>To illustrate this point, I&#8217;d like to introduce a couple of simple combinators:</p>
<dl>
<dt><code>dip</code> <i>( x quot &#45;&#45; x )</i></dt>
<dd>calls a quotation while temporarily hiding the top item on the stack</dd>
<dt><code>keep</code> <i>( x quot &#45;&#45; x )</i></dt>
<dd>calls a quotation with an item on the stack, restoring that item after the quotation returns</dd>
</dl>
<p>While both of these combinators have the same stack effect declaration, their usage is a bit different:</p>
<pre><code>(scratchpad) <strong>1 2 4 [ + ] dip</strong>

--- Data stack:
3
4
(scratchpad) <strong>clear</strong>
(scratchpad) <strong>1 2 4 [ + ] keep</strong>

--- Data stack:
1
6
4</code></pre>
<p></p>
<p>These two combinators alone can greatly reduce the number of stack shufflers your code will need. If you&#8217;re curious about how these combinators work, they both secretly take advantage of an auxiliary stack (called the &#8220;retain stack&#8221;) to temporarily store items while the supplied quotation is being executed. There are a few other <a href="http://docs.factorcode.org/content/article-slip-keep-combinators.html">retain stack combinators</a> that are worth exploring as well.</p>
<h3 id="cleave">Cleave, Spread, and Apply</h3>
<p>The cleave, spread, and apply combinators are your best weapons when trying to reduce the use of stack shufflers while simultaneously expressing intent. The key point being that they <em>should</em> express intent&#8230;if you find yourself writing code where these combinators don&#8217;t fit logically, then try another option.</p>
<ol>
<li><strong>Cleave Combinators</strong>
<p>These are used when you want to <em>apply multiple quotations to the same set of items</em> on the top of the stack.</p>
<p>	Let&#8217;s say that you want to find the average of a bunch of numbers in an array. The steps are straightforward, you take the sum of all the numbers and divide that sum by how many numbers you have (the length of the array):</p>
<pre><code>(scratchpad) <strong>{ 1 2 3 } dup sum swap length / .</strong>
2</code></pre>
<p></p>
<p>	We can eliminate the need for those stack shufflers and better express our intent by using a cleave combinator to achieve the same thing:</p>
<dl>
<dt><code>bi</code> <i>( x p q &#45;&#45; )</i></dt>
<dd>applies quotation <b><i>p</i></b> to <b><i>x</i></b>, then applies quotation <b><i>q</i></b> to <b><i>x</i></b></dd>
</dl>
<p>	<img src="http://elasticdog.com/images/2008/12/cleave.png" alt="Cleave Combinator Demonstration" width="510" height="222" /></p>
<pre><code>(scratchpad) <strong>{ 1 2 3 } [ sum ] [ length ] bi / .</strong>
2</code></pre>
<p></p>
<p>	The different <a href="http://docs.factorcode.org/content/article-cleave-combinators.html">cleave combinators</a> change either the number of quotations applied to your items (<code>bi</code> vs. <code>tri</code>), or the number of items used as input for your quotations (<code>bi</code> vs. <code>2bi</code>).
	</li>
<li><strong>Spread Combinators</strong>
<p>These are used when you want to <em>apply a different quotation to different items</em> on the top of the stack. The spread combinators are closely related to <code>dip</code>, but provide a bit more flexibility while also expressing intent.</p>
<p>	Let&#8217;s say that you have two coordinate positions in the form of <code>{ x y }</code>, and you&#8217;d like to extract the x-coordinate from the first position, and the y-coordinate from the second position to form a new position with those values:</p>
<pre><code>(scratchpad) <strong>{ 1 2 } { 3 4 } swap first swap second 2array .</strong>
{ 1 4 }</code></pre>
<p></p>
<p>	We can eliminate the need for those stack shufflers and better express our intent by using a spread combinator to achieve the same thing:</p>
<dl>
<dt><code>bi*</code> <i>( x y p q &#45;&#45; )</i></dt>
<dd>applies quotation <b><i>p</i></b> to <b><i>x</i></b>, then applies quotation <b><i>q</i></b> to <b><i>y</i></b></dd>
</dl>
<p>	<img src="http://elasticdog.com/images/2008/12/spread.png" alt="Spread Combinator Demonstration" width="510" height="222" /></p>
<pre><code>(scratchpad) <strong>{ 1 2 } { 3 4 } [ first ] [ second ] bi* 2array .</strong>
{ 1 4 }</code></pre>
<p></p>
<p>	When you want to do the same thing with more than two quotations/items, then using spread combinators eliminates the need for nested dips or shufflers and the added clarity becomes much more evident.</p>
<p>	The different <a href="http://docs.factorcode.org/content/article-spread-combinators.html">spread combinators</a> change the number of quotations applied to the corresponding number of items on the stack (<code>bi*</code> vs. <code>tri*</code>).
	</li>
<li><strong>Apply Combinators</strong>
<p>These are used when you want to <em>apply a single quotation to multiple items</em> on the top of the stack.</p>
<p>	Let&#8217;s say that you have two strings, each containing a name, and you want to see if those names are the same. In order to ignore case when doing the comparison, you decide to convert both strings to upper case before checking for equality:</p>
<pre><code>(scratchpad) <strong>"john" "John" swap &gt;upper swap &gt;upper = .</strong>
t</code></pre>
<p></p>
<p>	We can eliminate the need for those stack shufflers and better express our intent by using an apply combinator to achieve the same thing:</p>
<dl>
<dt><code>bi@</code> <i>( x y quot &#45;&#45; )</i></dt>
<dd>applies the quotation to <b><i>x</i></b>, then to <b><i>y</i></b></dd>
</dl>
<p>	<img src="http://elasticdog.com/images/2008/12/apply.png" alt="Apply Combinator Demonstration" width="510" height="222" /></p>
<pre><code>(scratchpad) <strong>"john" "John" [ &gt;upper ] bi@ = .</strong>
t</code></pre>
<p></p>
<p>	The different <a href="http://docs.factorcode.org/content/article-apply-combinators.html">apply combinators</a> change the number of items on the stack your quotation is applied to  (<code>bi@</code> vs. <code>tri@</code>).
	</li>
</ol>
<p>The cleave, spread, and apply combinators are all closely related; if you&#8217;re having trouble keeping them apart, try to memorize the naming convention:</p>
<ul>
<li>If there is no suffix, it is a &#8220;cleave&#8221;</li>
<li>If the suffix is *, it is a &#8220;spread&#8221;</li>
<li>If the suffix is @, it is an &#8220;apply&#8221;</li>
</ul>
<p>Once you learn these combinators, you should be able to express almost any pattern of complicated stack shufflers. Note that there are also <a href="http://docs.factorcode.org/content/article-combinators.html">generic forms</a> for all of these combinators that can take additional inputs from the stack. If you find that you resort to using the generic forms more often then not, that&#8217;s usually a good indication that you should rethink your approach or put your data into a more appropriate structure.</p>
<h2 id="data">Data Type Details</h2>
<p>Before I turn you loose, I wanted to offer a few extra details about some of Factor&#8217;s basic data types&#8230;</p>
<h3 id="sequences">Sequences</h3>
<p>In the cleave and spread examples above, I was sneaky and used sequences without explaining them formally. A sequence is a <em>finite, ordered, collection of elements</em>. Any data type that implements the sequence mixin class (meaning a data type that knows its length and will let you set/get an element at a specific index) gains the ability to use the powerful built-in <a href="http://docs.factorcode.org/content/article-sequences.html">sequence operators</a>. Read through that documentation to get an idea on how to manipulate sequences and their elements.</p>
<p>Factor has many sequence types that you may already be familiar with, such as <a href="http://docs.factorcode.org/content/article-arrays.html">arrays</a> (fixed-size mutable sequences) and <a href="http://docs.factorcode.org/content/article-vectors.html">vectors</a> (resizable mutable sequences), but there are also other data types that you might not expect to be sequences, such as strings. In Factor, a string is merely an array of Unicode 5.0 code points.</p>
<p>Using the sequence operators and combinators together, you can create all sorts of powerful abstractions that I&#8217;ll talk more about next time. Here are a couple of examples to whet your appetite:</p>
<pre><code>(scratchpad) <strong>{ 1 2 3 4 5 } [ even? ] filter .</strong>
{ 2 4 }
(scratchpad) <strong>{ 1 2 3 } [ . ] each</strong>
1
2
3
(scratchpad) <strong>"Hello" [ alpha? ] all? .</strong>
t
(scratchpad) <strong>"Hello!!!" [ alpha? ] all? .</strong>
f</code></pre>
<p></p>
<p>Keep in mind that in Factor, <strong>sequences are zero-based</strong>.</p>
<h3 id="numbers">Numbers</h3>
<p>The last topic for the day is numbers. So far, we have only used integers, but Factor also supports <a href="http://docs.factorcode.org/content/article-rationals.html">rational numbers</a> (fractions), <a href="http://docs.factorcode.org/content/article-floats.html">floats</a> (decimal approximations of a number), and <a href="http://docs.factorcode.org/content/article-complex-numbers.html">complex numbers</a> (imaginary numbers).</p>
<pre><code>(scratchpad) <strong>100 330 / .</strong>
10/33
(scratchpad) <strong>5/4 1/2 + .</strong>
1+3/4
(scratchpad) <strong>5/4 0.5 + .</strong>
1.75
(scratchpad) <strong>2 5 rect&gt; .</strong>
C{ 2 5 }</code></pre>
<p></p>
<p>Integers have one additional property that makes them special&#8230;<strong>non-negative integers are sequences</strong>. A positive integer (<i>n</i>) is a sequence of length <i>n</i>, whose elements are its non-negative predecessors (i.e. 0 to <i>n</i>-1 inclusive). This property can be very helpful when performing counted loops or other control flow statements.</p>
<p>Because of this property, the following two lines are equivalent:</p>
<pre><code>{ 0 1 2 3 4 5 6 7 8 9 } [ . ] each
10 [ . ] each</code></pre>
<p></p>
<h2 id="next">Next Time</h2>
<p>Next time weâ€™ll stick with a theme of &#8220;flow&#8221; and discuss control flow for your words and also the typical work flow when developing code with Factor. Hope you enjoyed this installment!</p>
---<br />Related Posts at ElasticDog:<ul><li><a href="http://elasticdog.com/2008/11/beginning-factor-introduction/" rel="bookmark" title="November 29th, 2008">Beginning Factor &#8211; Introduction</a></li>
</ul><!-- Similar Posts took 15.806 ms --><img src="http://feeds.feedburner.com/~r/elasticdog/~4/whNJ5l21pno" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elasticdog.com/2008/12/beginning-factor-shufflers-and-combinators/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		<feedburner:origLink>http://elasticdog.com/2008/12/beginning-factor-shufflers-and-combinators/</feedburner:origLink></item>
		<item>
		<title>Beginning Factor – Introduction</title>
		<link>http://feedproxy.google.com/~r/elasticdog/~3/z9-eajaCukk/</link>
		<comments>http://elasticdog.com/2008/11/beginning-factor-introduction/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 17:55:20 +0000</pubDate>
		<dc:creator>Aaron Schaefer</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Factor]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://elasticdog.com/?p=29</guid>
		<description><![CDATA[The <a href="http://factorcode.org/">Factor programming language</a> is a huge departure from the norm for most developers and it can be overwhelming to someone just getting started. I would like to help ease that transition by posting on various topics that I know have been confusing to me over the past year...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been involved in the <a href="http://factorcode.org/">Factor programming language</a> community for about a year now, and am constantly amazed with how productive its contributors are. Large improvements to the language and its libraries are made on a weekly (if not daily) basis, and it&#8217;s finally starting to attract some much-deserved attention from the programming community.</p>
<p>The problem is, the language is a huge departure from the norm for most developers and it can be overwhelming to someone just getting started. I would like to help ease that transition by posting on various topics that I know have been confusing to me over the past year.</p>
<p>Note that many topics are covered in <a href="http://factorcode.org/faq.fhtml">the official FAQ</a> &#8212; which is well worth a read &#8212; and I won&#8217;t spend time covering how to install Factor on the 14 or so platforms it supports, but beyond that, I&#8217;ll try to give enough information (from basic to advanced) to get you going.</p>
<h2 id="basics">The Basics of the Basics</h2>
<p>First of all, Factor is a stack-based language, which means that it uses a <a href="http://en.wikipedia.org/wiki/Stack_(data_structure)">stack</a> to store all arguments and returned values from functions (called &#8220;words&#8221; in Factor). To put that another way, Factor words don&#8217;t receive arguments in the traditional manner; all input values that your word needs are expected to already exist on the top of the stack.</p>
<h3 id="what-stack">What is a Stack?</h3>
<p>If you&#8217;re unfamiliar with the data structure called a stack, the concept is fairly simple. It centers around the idea of &#8220;Last In First Out&#8221; (LIFO), meaning the last item placed onto the stack is the first item that will you will get when you remove an item from the stack. You cannot get to the lower items until the all of the items above it have been removed.</p>
<p>I like to picture a stack like a tower of LEGOs. The only thing you can do with it are add another brick to the top (&#8220;push&#8221; an item onto the stack), or take the top brick off to use it for something else (&#8220;pop&#8221; an item off the stack). That&#8217;s all there is to stacks!</p>
<p><img src="/images/2008/11/stack-push.png" alt="Pushing an Item onto a Stack" width="554" height="257" /></p>
<h3 id="use-stack">How to Use the Stack</h3>
<p>So, now we know that Factor manages its input and output with a stack, but how do we actually use it? Well, when entering data into Factor&#8217;s listener, one of two things is happening:</p>
<ol>
<li>You are pushing a literal onto the stack<br /><strong>OR</strong></li>
<li>You are calling a word which will consume literals from the stack</li>
</ol>
<p>Things do get slightly more complicated than that, but for the most part those two rules hold true. The most simple example of this behavior is the ubiquitous hello world program, shown entered directly into Factor&#8217;s interactive listener environment:</p>
<pre><code>(scratchpad) <strong>"Hello world!" print</strong>
Hello world!</code></pre>
<p></p>
<p>To understand what is happening, you can just type the string first, and then execute the <code>print</code> word later:</p>
<pre><code>(scratchpad) <strong>"Hello world!"</strong>

--- Data stack:
"Hello world!"
(scratchpad) <strong>print</strong>
Hello world!</code></pre>
<p></p>
<p>In this particular case, typing the literal string <code>"Hello world!"</code> will push that value onto the stack; then the word <code>print</code>, takes a single string off the stack and writes it to the output stream.</p>
<p>The same idea can be applied to simple arithmetic. Like strings, numbers are also literals, so you just have to type them in (separated by spaces) for them to be pushed onto the stack:</p>
<pre><code>(scratchpad) <strong>2 3</strong>

--- Data stack:
2
3</code></pre>
<p></p>
<p><i>NOTE: the stack is displayed in the listener upside-down from the way you&#8217;d think, so the bottom number is actually the top of the stack.</i></p>
<p>&#8230; and if you want to add the top two numbers together, the <code>+</code> word will simply pop two numbers off the stack, add them together, and push the result back onto the stack:</p>
<pre><code>--- Data stack:
2
3
(scratchpad) <strong>+</strong>

--- Data stack:
5</code></pre>
<p></p>
<h3 id="words">A Few More Words</h3>
<p>If you start messing around in the listener, odds are your stack is going to grow pretty quickly and become unmanageable. There are a few words that are essential to know in order to keep things under control:</p>
<dl>
<dt><code>drop</code> <i>( x &#45;&#45; )</i></dt>
<dd>removes the top item from the stack and discards it</dd>
<dt><code>.</code> <i>( obj &#45;&#45; )</i></dt>
<dd>takes the top item from the stack and prettyprints it</dd>
<dt><code>clear</code> <i>( &#45;&#45; )</i></dt>
<dd>removes all items from the stack</dd>
</dl>
<pre><code>(scratchpad) <strong>2 3 -</strong>

--- Data stack:
-1
(scratchpad) <strong>drop</strong>
(scratchpad) <strong>20 5 / .</strong>
4
(scratchpad) <strong>2 3 + 6 7</strong>

--- Data stack:
5
6
7
(scratchpad) <strong>clear</strong>
(scratchpad)</code></pre>
<p></p>
<h3 id="stack-ramifications">Ramifications of Stack-Based Design</h3>
<p>From these simple examples, we can observe a couple of important things about Factor:</p>
<ol>
<li><strong>Postfix Notation</strong>
<p>When using a stack, passing data becomes implicit and we can assume that all input needed by words already exists on the stack. This naturally lends itself to using <a href="http://en.wikipedia.org/wiki/Reverse_Polish_notation">postfix notation</a> because you have to push your data onto the stack before you can use it.</p>
<p>This also makes words more concise and unambiguous when compared to <em>infix</em> notation and eliminates the need for copious amounts of parentheses used by <em>prefix</em> notation languages, like Lisp or Scheme.</p>
<pre><code>POSTFIX:  6 5 4 * +
INFIX:    6 + 5 * 4 =
PREFIX:   (+ (* 4 5) 6)</code></pre>
<p></p>
<p>With the infix example above, you&#8217;d have to know <a href="http://en.wikipedia.org/wiki/Order_of_operations">order of operations rules</a> in order to get the correct answer (or use parentheses to force the matter). When using postfix notation, the fact that multiplication is done first becomes explicit. Prefix notation also gets rid of that ambiguity, but becomes messier and harder to type with the more nesting you add.</li>
<li><strong>Calling Words is Implicit</strong>
<p>You don&#8217;t have to specify that you&#8217;re calling a word, you simply use the word. This, combined with postfix syntax, means that you can easily nest words or cut and paste parts of definitions into new words without disrupting the flow of data. This lends to keeping code modular, short, easily testable, and readable.</p>
</li>
</ol>
<h2 id="first-word">Your First Word</h2>
<p>If you&#8217;ve typed in the examples from above and messed around in the listener, then you might want to know how to write your own word rather than just using ones that are predefined. Drawing on what we already know, here&#8217;s how to write your first word:</p>
<pre><code>: plus-two ( x -- y )
    2 + ;</code></pre>
<p></p>
<p>If you copy and paste that into your listener, than you can use the word <code>plus-two</code> anywhere you would like to add two to a number on the top of the stack:</p>
<pre><code>(scratchpad) <strong>15 plus-two .</strong>
17</code></pre>
<p></p>
<p>Not very exciting, but it gives us a couple more things to talk about&#8230;</p>
<h3 id="syntax">Syntax Specifics</h3>
<p>If you study the word definition, you&#8217;ll see that it&#8217;s made up of a few elements:</p>
<pre><code>: plus-two ( x -- y )
    2 + ;</code></pre>
<p></p>
<ol>
<li>A <strong>colon</strong> (<code>:</code>) is used to start the definition of a word. This is required and must have a space after it.</li>
<li>Right after the opening colon is the <strong>name</strong> of your word, also required.</li>
<li>Following the name of your word is its <strong>stack effect declaration</strong>, which is a list of the word&#8217;s inputs and outputs separated by <code>--</code> and surrounded by parentheses. All words must have a stack effect declaration unless it only pushes literals on the stack. The names of elements in the stack effect declaration don&#8217;t make a difference, only the number of elements. That means that <code>( elt elt -- seq )</code> and <code>( x y -- z )</code> are the same thing. There <em>are</em> some common conventions for these names, but don&#8217;t get caught up by it as I&#8217;ll talk more about them in a later article and it won&#8217;t change how your program runs.</li>
<li>Next comes the <strong>word definition</strong> itself, in this case <code>2 +</code>.</li>
<li>And the last item is a <strong>semicolon</strong> (<code>;</code>), used to end the word definition. This is required and must have a space before it.</li>
</ol>
<p>The reason that everything must be surrounded by spaces is that there aren&#8217;t any syntax-only elements to Factor&#8230;everything is a word! The colon/semicolon, the parentheses, etc. are all just parsing words working together in order to create the syntax.</p>
<h2 id="next">Next Time</h2>
<p>Next time we&#8217;ll talk more about stack shufflers, quotations &#038; combinators, details about more datatypes, and more&#8230;</p>
<p>If something is unclear or if you&#8217;re having any trouble, let me know and I&#8217;ll try to help out!</p>
---<br />Related Posts at ElasticDog:<ul><li><a href="http://elasticdog.com/2008/12/beginning-factor-shufflers-and-combinators/" rel="bookmark" title="December 4th, 2008">Beginning Factor &#8211; Shufflers &#038; Combinators</a></li>
</ul><!-- Similar Posts took 79.878 ms --><img src="http://feeds.feedburner.com/~r/elasticdog/~4/z9-eajaCukk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elasticdog.com/2008/11/beginning-factor-introduction/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://elasticdog.com/2008/11/beginning-factor-introduction/</feedburner:origLink></item>
		<item>
		<title>Comments Missing in WordPress Dashboard After 2.5.1 Upgrade</title>
		<link>http://feedproxy.google.com/~r/elasticdog/~3/DCmSplTnoQI/</link>
		<comments>http://elasticdog.com/2008/04/comments-missing-in-wordpress-dashboard-after-251-upgrade/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 02:22:13 +0000</pubDate>
		<dc:creator>Aaron Schaefer</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://elasticdog.com/?p=28</guid>
		<description><![CDATA[I just upgraded the WordPress installation for ElasticDog to version 2.5.1 and noticed that the Manage Comments page in the administrative Dashboard was not displaying any comments.  I only noticed there was a problem when the interface kept telling me there were 9 comments awaiting moderation, yet it would not let me see them. [...]]]></description>
			<content:encoded><![CDATA[<p>I just upgraded the WordPress installation for ElasticDog to version 2.5.1 and noticed that the Manage Comments page in the administrative Dashboard was not displaying any comments.  I only noticed there was a problem when the interface kept telling me there were 9 comments awaiting moderation, yet <a href="http://elasticdog.com/images/2008/04/awaiting-moderation.png">it would not let me see them</a>.  Everything was displaying correctly on the publicly viewable blog pages, but no comments showed up when trying to access them via the Dashboard.</p>
<p>After searching for a bit and checking my sever logs, I found that the upgrade script did not add the proper index to the &#8220;comment_date_gmt&#8221; column in the comments table for my WordPress database:</p>
<pre><code>Apr 25 18:22:17 php-cgi: WordPress database error Key 'comment_date_gmt' doesn't exist in table 'wp_comment' for query...</code></pre>
<p></p>
<h3 id="solution">The Solution</h3>
<p>If you don&#8217;t want to wait until the upgrade script gets fixed in a later WordPress release, you&#8217;ll have to add the missing index to the database table yourself to get things working again.  I&#8217;ll demonstrate how to do that using the MySQL command line interface, however, if you&#8217;re more comfortable with using phpMyAdmin, see <a href="http://wordpress.org/support/topic/167450#post-737217">the steps outlined here</a>.</p>
<h4 id="privileges">Check for Proper Privileges</h4>
<p>First of all, you must have the proper privileges on your WordPress database in order to add an index.  To check that, follow these steps:</p>
<ol>
<li>Log in to MySQL with whatever account credentials you know.
<pre><code>$ <strong>mysql -u root -p</strong>
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 59202
Server version: 5.0.51a Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql&gt;</code></pre>
</li>
<li>Specify that you want to access the &#8220;mysql&#8221; database, then ensure that you do have the privileges to add indexes.
<pre><code>mysql&gt; <strong>use mysql</strong>
Database changed
mysql&gt; <strong>SELECT user, index_priv FROM user;</strong>
+------------------+-----------------+
| user       | index_priv |
+------------------+-----------------+
| root       | Y          |
| elasticdog | N          |
+------------------+-----------------+
2 rows in set (0.00 sec)</code></pre>
</li>
</ol>
<p>As long as you see a &#8216;Y&#8217; next to your username, then you should be good to go.</p>
<h4 id="cli">Add the Index to the Comments Table</h4>
<p>Once you have access to an account that can add indexes, then follow these steps to add the missing index:</p>
<ol>
<li>Specify that you want to access your WordPress database.  If you don&#8217;t know the name of your WordPress database, run <code>show databases;</code> to see a list of databases you have access to.
<pre><code>mysql&gt; <strong>use elasticdog_wordpress</strong>
Database changed</code></pre>
</li>
<li>Add the index.  The table names for WordPress are fairly standard, but if you don&#8217;t have one named &#8220;wp_comments&#8221;, run <code>show tables;</code> to see a list of contenders and it should be easy to figure out.
<pre><code>mysql&gt; <strong>CREATE INDEX comment_date_gmt ON wp_comments (comment_date_gmt);</strong>
Query OK, 458 rows affected (0.14 sec)
Records: 458  Duplicates: 0  Warnings: 0</code></pre>
</li>
<li>If want to verify that the index was created, run <br /><code>SHOW INDEX FROM wp_comments;</code> to list all indexes, and then you can exit out.</li>
</ol>
<p>If everything went as planned, all will be right in the world and your comments should be viewable through the dashboard once again!</p>
---<br />Related Posts at ElasticDog:<ul><li><a href="http://elasticdog.com/2008/02/howto-install-wordpress-on-nginx/" rel="bookmark" title="February 27th, 2008">HOWTO: Install WordPress on Nginx</a></li>

<li><a href="http://elasticdog.com/2004/10/faking-multiple-templates/" rel="bookmark" title="October 7th, 2004">Faking Multiple Templates in WordPress</a></li>

<li><a href="http://elasticdog.com/2004/09/optimal-title/" rel="bookmark" title="September 8th, 2004">WP Plugin: Optimal Title</a></li>

<li><a href="http://elasticdog.com/2008/02/optimal-title-functionality-now-in-wordpress-core/" rel="bookmark" title="February 20th, 2008">Optimal Title Functionality Now in WordPress Core</a></li>
</ul><!-- Similar Posts took 45.068 ms --><img src="http://feeds.feedburner.com/~r/elasticdog/~4/DCmSplTnoQI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elasticdog.com/2008/04/comments-missing-in-wordpress-dashboard-after-251-upgrade/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://elasticdog.com/2008/04/comments-missing-in-wordpress-dashboard-after-251-upgrade/</feedburner:origLink></item>
		<item>
		<title>HOWTO: Install WordPress on Nginx</title>
		<link>http://feedproxy.google.com/~r/elasticdog/~3/r61tc23jnK8/</link>
		<comments>http://elasticdog.com/2008/02/howto-install-wordpress-on-nginx/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 07:15:31 +0000</pubDate>
		<dc:creator>Aaron Schaefer</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://elasticdog.com/2008/02/howto-install-wordpress-on-nginx/</guid>
		<description><![CDATA[So you want to install the files for <a href="http://wordpress.org/">WordPress</a> in a subdirectory while running your blog in the root directory?  If your server is running <a href="http://httpd.apache.org/">Apache</a>, then <a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">it's pretty straight forward</a> to do.  Trouble is, what if you want to run a web server that's a little faster and lighter on resources, like <a href="http://nginx.net/">Nginx</a>?  Here's how to do it...]]></description>
			<content:encoded><![CDATA[<p>I recently moved all of my sites from a cheap shared host to a shiny new <abbr title="Virtual Private Server">VPS</abbr> at <a href="http://www.slicehost.com/">SliceHost</a>, and couldn&#8217;t be happier.  Running your own VPS means a great amount of flexibility since you have full root access to the server and get to configure everything exactly how you want it.  That said, it also means that if you want to maintain high performance, you have to keep your resource usage to a minimum.</p>
<p><a href="http://httpd.apache.org/">Apache</a> is a very well-establish web server that can handle just about any situation.  Unfortunately, that flexibility comes at the cost of size and relatively high demands on server resources.  <a href="http://nginx.net/">Nginx</a> (&#8220;engine x&#8221;) is a lightweight web server/reverse proxy that is very efficient and perfect for hosting WordPress.  Read on to see how that can be done&#8230;</p>
<h3 id="step-one">Step One: FastCGI</h3>
<p>First off, Nginx does not provide FastCGI for you (FastCGI is what your web server uses to interact with WordPress&#8217;s <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> code), so you&#8217;ve got to have a way to spawn your own FastCGI processes.  My preferred method is to use the <code>spawn-fcgi</code> program provided by the web server <a href="http://www.lighttpd.net/">lighttpd</a>. You <em>can</em> use PHP&#8217;s built-in FastCGI manager <code>php-cgi</code> to <a href="http://blog.kovyrin.net/2006/05/30/nginx-php-fastcgi-howto/">do the same thing</a>, but it&#8217;s not as straight-forward. Plus, if you learn how to use <code>spawn-fcgi</code>, you can easily adapt it for use with other web applications requiring FastCGI.</p>
<h4>Install spawn-fcgi</h4>
<p>To download and install <code>spawn-fcgi</code>, run the following commands.  Don&#8217;t worry, all of the building happens in your current directory&#8230;nothing else will be installed on your machine.</p>
<pre><code>$ wget http://www.lighttpd.net/download/lighttpd-1.4.18.tar.bz2
$ tar -xvjf lighttpd-1.4.18.tar.bz2
$ cd lighttpd-1.4.18/
$ ./configure
$ make
$ sudo cp src/spawn-fcgi /usr/bin/spawn-fcgi</code></pre>
<p></p>
<p><i>NOTE: If you&#8217;re following the steps above verbatim, you will need to have root privileges in order to copy the binary to its final location&#8230;everything else should work fine as a normal user. To gain root privileges, the program <code>sudo</code> was used in the example above; you may or may not have access to <code>sudo</code> on your machine.</i></p>
<p>After <code>spawn-fcgi</code> has been copied to the desired location, you can safely remove the build directory and original source file:</p>
<pre><code>$ cd ..
$ rm -rf lighttpd-1.4.18/
$ rm lighttpd-1.4.18.tar.bz2</code></pre>
<p></p>
<h4>Run spawn-fcgi</h4>
<p>This part will be fairly distribution-specific, but I&#8217;ll provide the basic command that you&#8217;ll need. What you want to do is find a way to run this command as part of your init scripts so the processes will be spawned automatically when you reboot your server.</p>
<pre><code>/usr/bin/spawn-fcgi -f /usr/bin/php-cgi -a 127.0.0.1 -p 53217 -P /var/run/fastcgi-php.pid</code></pre>
<p></p>
<ul>
<li><code>-f</code> &rarr; the filename of the fcgi-application; in our case we want &#8220;php-cgi&#8221;, which is provided by your distribution&#8217;s <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> package. If you don&#8217;t know where to find it, try running <code>which php-cgi</code> on the command line.</li>
<li><code>-a</code> &rarr; the IP address to bind the processes to; in our case we want the localhost</li>
<li><code>-p</code> &rarr; the port number to bind the processes to; pick whatever you want that won&#8217;t cause a conflict (technically it would be best to pick a random number between 49152 and 65535), just make sure to remember the number and use that same port for your Nginx configuration file later on</li>
<li><code>-P</code> &rarr; the location where to save the process id file; you can use this file to easily kill the processes later</li>
</ul>
<p>For better security, you can also spawn the processes as a non-privileged user by specifying the user/group with the <code>-u</code> and <code>-g</code> flags respectively. For more information on all the available options, run <code>spawn-fcgi -h</code> on the command line. </p>
<p>If you&#8217;re interested in seeing the complete init script that I wrote for use with <a href="http://www.archlinux.org/">Arch Linux</a>, you can download it here: <a href="http://elasticdog.com/code/2008/02/fastcgi-php">fastcgi-php</a></p>
<h3 id="step-two">Step Two: Complete 83.33% of the Famous 5-Minute Install</h3>
<p>Next you should download the WordPress files and extract them to their final location on your server.  Simply follow steps 1&#8211;5 of the <a href="http://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install">Famous 5-Minute Install</a> (the 6th and final step requires that your web server be up and running properly, so we&#8217;ll do it later).  This guide will assume that you extracted the WordPress core files here: <code>/srv/www/nginx/domain.com/</code></p>
<h3 id="step-three">Step Three: Nginx Configuration</h3>
<p>To get the web server up and running properly, the file you need to edit is called &#8220;nginx.conf&#8221; and is installed in different places depending on your Linux distribution. If you install Nginx from source, the default location is <code>/usr/local/nginx/conf/nginx.conf</code>, however yours may be somewhere else.</p>
<p>Once you find that file, open it with your favorite text editor and add a server declaration that looks something like this (I&#8217;ll cover what each part means after posting the code):</p>
<pre><code>server {
    listen       <em>12.34.56.78</em>:80;  <strong># your server's public IP address</strong>
    server_name  <em>domain.com</em>;      <strong># your domain name</strong>

    location / {
        root   <em>/srv/www/nginx/domain.com</em>;  <strong># absolute path to your WordPress installation</strong>
        index  index.php index.html index.htm;

        # this serves static files that exist without running other rewrite tests
        if (-f $request_filename) {
            expires 30d;
            break;
        }

        # this sends all non-existing file or directory requests to index.php
        if (!-e $request_filename) {
            rewrite ^(.+)$ /index.php?q=$1 last;
        }
    }

    location ~ \.php$ {
        fastcgi_pass   localhost:<em>53217</em>;  <strong># port where FastCGI processes were spawned</strong>
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME    <em>/srv/www/nginx/domain.com</em>$fastcgi_script_name;  <strong># same path as above</strong>

        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;

        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;

        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;

        # required if PHP was built with --enable-force-cgi-redirect
        fastcgi_param  REDIRECT_STATUS    200;
    }
}</code></pre>
<div class="sourcelink">Download Source Code: <a href="http://elasticdog.com/code/2008/02/nginx-conf.txt">nginx-conf.txt</a></div>
<p></p>
<p>You will need to edit all of the highlighted sections above using your own information.  The first part is merely the server declaration where you define what your server&#8217;s publicly available IP address is and what domain name that address is associated with.</p>
<p>Next we add to that some default settings for the root location.  The key part here is that WordPress uses the &#8220;Front Controller&#8221; design pattern, meaning that any request for a file that does not exist on the server should be handled by the main index.php file.  To do this, we need an appropriate set of rewrite rules pointing to the proper path of our installation.</p>
<p>Last, we add one more location block that tells Nginx to dynamically forward <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> requests to the FastCGI processes we <a href="#step-one">spawned earlier</a>.  That&#8217;s it!</p>
<h3 id="step-four">Step Four: Finishing Up</h3>
<p>Everything should be good to go&#8230;all you need to do now is start your Nginx server process (another distribution specific command), then complete the 6th step of the <a href="http://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install">Famous 5-Minute Install</a> and you should have WordPress up and running on Nginx!</p>
<p>If any of this needs further clarification or you&#8217;re just having trouble, leave me a comment and I&#8217;ll see what I can do to help&#8230;</p>
---<br />Related Posts at ElasticDog:<ul><li><a href="http://elasticdog.com/2008/04/comments-missing-in-wordpress-dashboard-after-251-upgrade/" rel="bookmark" title="April 25th, 2008">Comments Missing in WordPress Dashboard After 2.5.1 Upgrade</a></li>

<li><a href="http://elasticdog.com/2004/11/wp-design-sandbox/" rel="bookmark" title="November 10th, 2004">WordPress Design Sandbox</a></li>

<li><a href="http://elasticdog.com/2004/10/faking-multiple-templates/" rel="bookmark" title="October 7th, 2004">Faking Multiple Templates in WordPress</a></li>

<li><a href="http://elasticdog.com/2008/02/optimal-title-functionality-now-in-wordpress-core/" rel="bookmark" title="February 20th, 2008">Optimal Title Functionality Now in WordPress Core</a></li>
</ul><!-- Similar Posts took 8.904 ms --><img src="http://feeds.feedburner.com/~r/elasticdog/~4/r61tc23jnK8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elasticdog.com/2008/02/howto-install-wordpress-on-nginx/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://elasticdog.com/2008/02/howto-install-wordpress-on-nginx/</feedburner:origLink></item>
		<item>
		<title>Current Status of the Code Viewer WordPress Plugin</title>
		<link>http://feedproxy.google.com/~r/elasticdog/~3/nF_B9whM42Y/</link>
		<comments>http://elasticdog.com/2008/02/current-status-of-the-code-viewer-wordpress-plugin/#comments</comments>
		<pubDate>Sun, 24 Feb 2008 02:56:42 +0000</pubDate>
		<dc:creator>Aaron Schaefer</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://elasticdog.com/2008/02/current-status-of-the-code-viewer-wordpress-plugin/</guid>
		<description><![CDATA[This site has been neglected for a long time, and that negligence has carried over to the development of the Code Viewer WordPress plugin as well.  While I&#8217;ve been away, Code Viewer has been picked up/enhanced by a few other developers &#8212; namely AJ and HÃ¥kan CarlstrÃ¶m &#8212; and has gained many new features&#8230;
Code [...]]]></description>
			<content:encoded><![CDATA[<p>This site has been neglected for a long time, and that negligence has carried over to the development of the <a href="http://elasticdog.com/2004/09/code-viewer/">Code Viewer</a> WordPress plugin as well.  While I&#8217;ve been away, Code Viewer has been picked up/enhanced by a few other developers &#8212; namely <a href="http://flash.terra.ee/">AJ</a> and <a href="http://www.familjencarlstrom.se/WordPress/">HÃ¥kan CarlstrÃ¶m</a> &#8212; and has gained many new features&#8230;</p>
<p>Code Viewer now supports syntax highlighting using <a href="http://qbnz.com/highlighter/">GeSHi</a>, can display specific line numbers, and has user-configurable scrollbars (among a few other niceties).  On top of those changes, the default code path variable can now be configured directly in WordPress&#8217;s admin interface rather than editing the plugin code by hand&#8230;very nice!</p>
<h3 id="reactions">Reactions</h3>
<p>I don&#8217;t agree with all of the design choices they made with the new changes, but my qualms are minor.  Specifically, I don&#8217;t like some of the chosen defaults, nor the new format when specifying viewcode tags:<br />
<code>[viewcode ] src=/code/example.txt link=yes[/viewcode]</code><br />
&#8230;in comparison to the original:<br />
<code>&lt;viewcode src="/code/example.txt" link="yes" /&gt;</code></p>
<p>That said, it <em>is</em> a cool feeling to find out that other people appreciate your work and chose to carry on with its development in your absence.</p>
<h3 id="torch">Passing the Torch</h3>
<p>With the latest design incarnation here at ElasticDog, I decided to no longer use Code Viewer for displaying code snippets.  Instead, I went with the plugin <a href="http://www.thunderguy.com/semicolon/wordpress/code-markup-wordpress-plugin/">Code Markup</a>, which allows me to easily embed custom markup within code blocks.  It&#8217;s a completely different way of going about displaying code in blog entries when compared to Code Viewer, but it does the job well and suits my needs for the time being.</p>
<p>Although I haven&#8217;t actually worked on the development of Code Viewer since late 2004, I did register to have it hosted at the <a href="http://wordpress.org/extend/plugins/">WordPress Plugin Repository</a>.  Unfortunately, I never got around to packaging it up for general consumption.</p>
<p>Trying to not be a slacker anymore, I <em>have</em> contacted HÃ¥kan in hopes of persuading him to take the reins and officially manage the plugin at the centralized WordPress repository.  If he agrees, you should be able to download the plugin here very shortly:<br />
<a href="http://wordpress.org/extend/plugins/code-viewer/">http://wordpress.org/extend/plugins/code-viewer/</a></p>
<p>In the mean time, you can find the <a href="http://www.familjencarlstrom.se/WordPress/2006/08/17/code-viewer/">most up to date version of Code Viewer</a> at <a href="http://www.familjencarlstrom.se/WordPress/">HÃ¥kan&#8217;s site</a>.  Happy coding!</p>
---<br />Related Posts at ElasticDog:<ul><li><a href="http://elasticdog.com/2004/09/code-viewer/" rel="bookmark" title="September 26th, 2004">WP Plugin: Code Viewer</a></li>

<li><a href="http://elasticdog.com/2008/02/optimal-title-functionality-now-in-wordpress-core/" rel="bookmark" title="February 20th, 2008">Optimal Title Functionality Now in WordPress Core</a></li>

<li><a href="http://elasticdog.com/2004/09/optimal-title/" rel="bookmark" title="September 8th, 2004">WP Plugin: Optimal Title</a></li>

<li><a href="http://elasticdog.com/2008/02/howto-install-wordpress-on-nginx/" rel="bookmark" title="February 27th, 2008">HOWTO: Install WordPress on Nginx</a></li>
</ul><!-- Similar Posts took 5.511 ms --><img src="http://feeds.feedburner.com/~r/elasticdog/~4/nF_B9whM42Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elasticdog.com/2008/02/current-status-of-the-code-viewer-wordpress-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://elasticdog.com/2008/02/current-status-of-the-code-viewer-wordpress-plugin/</feedburner:origLink></item>
	</channel>
</rss>
