<?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>Bobbing for Kernels</title>
	<atom:link href="http://kernelbob.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://kernelbob.wordpress.com</link>
	<description>See Bob.  See Bob bob.  Bob, Bob, bob!</description>
	<lastBuildDate>Sat, 28 Jan 2012 01:50:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='kernelbob.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Bobbing for Kernels</title>
		<link>http://kernelbob.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://kernelbob.wordpress.com/osd.xml" title="Bobbing for Kernels" />
	<atom:link rel='hub' href='http://kernelbob.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Same Five Digits</title>
		<link>http://kernelbob.wordpress.com/2011/03/20/same-five-digits/</link>
		<comments>http://kernelbob.wordpress.com/2011/03/20/same-five-digits/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 02:43:30 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=632</guid>
		<description><![CDATA[Enigma is a weekly column in New Scientist.  Every week it has a new puzzle.  Some of the Enigma puzzles could be solved using a computer. This week&#8217;s puzzle, Enigma number 1638, is in that category.  Here are the facts of the problem. I am thinking of three numbers. Each number is a perfect square. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=632&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Enigma is a weekly column in New Scientist.  Every week it has a new puzzle.  Some of the Enigma puzzles could be solved using a computer.</p>
<p><a title="Enigma 1638" href="http://www.newscientist.com/article/mg20928041.300-enigma-number-1638.html" target="_blank">This week&#8217;s puzzle, Enigma number 1638</a>, is in that category.  Here are the facts of the problem.</p>
<ul>
<li>I am thinking of three numbers.</li>
<li> Each number is a perfect square.</li>
<li> Each number has five digits.</li>
<li>Five different digits occur in all three numbers.</li>
<li> Each of the five digits occurs a different number of times.</li>
<li> The five numbers of times is the same as the five digits.</li>
<li> No digit occurs its own number of times.  (E.g., 4 is not used 4 times.)</li>
<li> If you knew which digit occurs once, you could uniquely identify the numbers.</li>
</ul>
<p>Your task is to write a program that finds and prints the three perfect squares I am thinking of.</p>
<p><span id="more-632"></span>I chose to use Python 3 to solve this problem.</p>
<p>The brute force solution is to enumerate all the perfect squares with five digits.  Then try them in all combinations taken three at a time.</p>
<p><pre class="brush: python;">
from itertools import combinations, count, takewhile

squares = filter(lambda s: len(s) == 5,
                 takewhile(lambda s: len(s) &lt;= 5,
                           (str(s**2) for s in count())))

for a, b, c in combinations(squares, 3):
    # ...
</pre></p>
<p>Each trio of numbers has to meet three criteria.</p>
<p style="padding-left:30px;">C1. five different digits occur in the trio.<br />
C2. each digit occurs a different number of times (has a different frequency).<br />
C3. the five frequencies are the same as the five digits.</p>
<p>A digit frequency histogram would help with all of those.  Let&#8217;s define a function to build it.</p>
<p><pre class="brush: python;">
from collections import defaultdict

def histogram(s):
    d = defaultdict(int)
    for c in s:
        d[c] += 1
    return d
</pre></p>
<p>That returns a dictionary mapping each digit to the number of times it occurs.  For example, hist(&#8217;31415&#8242;) would return {1: 2, 3: 1, 5: 1}, meaning 1 occurs twice and 3 and 5 each occur once.</p>
<p>Now we can test for the three criteria like this.</p>
<p><pre class="brush: python;">
    hist = histogram(a + b + c)
    digits = set(hist.keys())
    frequencies = set(hist.values())
    if   (len(digits) == 5 and                     # five different digits
          digits == frequencies and                # digits == frequencies
          not any(hist[k] == k for k in hist)):    # k does not occur k times.
        # then a, b, c meet the criteria.
</pre></p>
<p>We need to find all trios that meet the criteria, then find the one whose singleton digit is unique.  So we&#8217;ll build a map from singleton digit to the set of trios with that singleton.</p>
<p><pre class="brush: python;">
matches = defaultdict(list)
for a, b, c in combinations(squares, 3):
    # ...
    if «criteria met»:
        inverse_hist = dict((hist[k], k) for k in hist)
        singleton = inverse_hist[1]
        matches[singleton].append((a, b, c))
</pre></p>
<p>Now we need to find the entry in matches that has length one.  We&#8217;ll do that by creating yet another map, this time from number of matches to the list of matches.  Then we can extract the answer directly.</p>
<p><pre class="brush: python;">
match_counts = dict((len(ls), ls) for ls in matches.values())
print(*match_counts[1][0])
</pre></p>
<p>Here is the whole program.</p>
<p><pre class="brush: python;">
#!/usr/bin/python3

from collections import defaultdict
from itertools import combinations, count, takewhile

def histogram(s):
    d = defaultdict(int)
    for c in s:
        d[int(c)] += 1
    return d

squares = filter(lambda s: len(s) == 5,
                 takewhile(lambda s: len(s) &lt;= 5,
                 (str(s**2) for s in count())))

matches = defaultdict(list)
for a, b, c in combinations(squares, 3):
    hist = histogram(a + b + c)
    digits = set(hist.keys())
    frequencies = set(hist.values())
    if    (len(digits) == 5 and
           digits == frequencies and
           not any(hist[k] == k for k in hist)):
        inverse_hist = dict((hist[k], k) for k in hist)
        singleton = inverse_hist[1]
        matches[singleton].append((a, b, c))

match_counts = dict((len(ls), ls) for ls in matches.values())
print(*match_counts[1][0])
</pre></p>
<p>A note on efficiency.  This programs runs for about 30 seconds on my computer.  You can reason about the problem and reduce the amount of work it does by a factor of 10,000 or so.  I&#8217;ll leave that as an exercise. (-:</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/632/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/632/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/632/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/632/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/632/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/632/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/632/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/632/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/632/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/632/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/632/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/632/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/632/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/632/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=632&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2011/03/20/same-five-digits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>Reading List</title>
		<link>http://kernelbob.wordpress.com/2011/01/24/reading-list/</link>
		<comments>http://kernelbob.wordpress.com/2011/01/24/reading-list/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 07:30:33 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Scheme]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Scheme macros]]></category>
		<category><![CDATA[Scheme modules]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=616</guid>
		<description><![CDATA[I&#8217;ve been doing some reading this weekend.  This post records a little of what I&#8217;ve learned. The focus has been Scheme macros and separate compilation.  I&#8217;m trying to understand how a production quality Scheme system &#8220;should&#8221; be organized.  &#8220;Should&#8221; is in scare quotes because every Scheme user has at least one opinion on the topic, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=616&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing some reading this weekend.  This post records a little of what I&#8217;ve learned.</p>
<p>The focus has been Scheme macros and separate compilation.  I&#8217;m trying to understand how a production quality Scheme system &#8220;should&#8221; be organized.  &#8220;Should&#8221; is in scare quotes because every Scheme user has at least one opinion on the topic, and no two seem to agree.</p>
<p>So here are the papers I&#8217;ve looked at in the last few days.</p>
<address><span id="more-616"></span><a title="Axis of Eval" href="http://axisofeval.blogspot.com/2011/01/more-fully-featured-modern-lisps.html">More fully-featured, modern Lisps, pulleez</a></address>
<address>Manuel Simoni</address>
<p>You have to love a &#8216;blog called Axis of Eval.  This post is a semi-rant requesting that people tackle the hard problems of Lisp language design instead of creating toy subsets.  It includes a number of good pointers to other papers on macros, and this is where I found most of these links.  I only followed the links on macros; I hope the other links are just as good.</p>
<address><a href="http://www.cs.utah.edu/plt/publications/macromod.pdf">Composable and Compilable Macros: You Want It When?</a></address>
<address>Matthew Flatt</address>
<p>This 2002 paper explains why separation of compile-time and run-time phases is a good idea.  Then it describes PLT Scheme&#8217;s macro and module system.</p>
<address><a href="http://axisofeval.blogspot.com/2010/05/understanding-hygiene-part-1.html">Understanding Hygiene (part 1)</a></address>
<address>Manuel Simoni</address>
<p>Also from the Axis of Eval.  This is the simplest explanation of hygiene I&#8217;ve ever seen.  I didn&#8217;t find Part 2; maybe it hasn&#8217;t been written yet.</p>
<address><a title="schemers.org" href="http://srfi.schemers.org/srfi-72/srfi-72.html">SRFI 72: Hygienic Macros</a></address>
<address>André van Tonder</address>
<p>SRFI is pronounced surfy, but it stands for Scheme Request For Implementation. They&#8217;re a series of mini-standards proposals for new language features.  Similar to <a title="Python Enhancement Proposals" href="http://www.python.org/dev/peps/">Python&#8217;s PEPs</a>.</p>
<p>SRFI 72 is a macro system very similar to what ended up in R6RS.  In fact, the reference implementation (see below) has been renamed &#8220;R6RS macros&#8221;.  Defines a consistent set of hygiene rules and a set of primitives that are both useful by themselves and a sufficient basis to implement <strong>syntax-case</strong>, <strong>with-syntax</strong>, and <strong>syntax-rules</strong>.</p>
<p>Further links to van Tonder&#8217;s macros:</p>
<address><a href="http://www.het.brown.edu/people/andre/macros/index.htm">Reference Implementation</a></address>
<address><a href="http://www.het.brown.edu/people/andre/macros/december-27-07/readme.txt">README from the reference implementation</a></address>
<address><a href="http://lists.r6rs.org/pipermail/r6rs-discuss/2007-October/003387.html">Informative summary on r6rs-discuss mailing list.</a></address>
<p>Those will take a long time to chew through.</p>
<address> </address>
<address> </address>
<address><a href="http://www.artima.com/weblogs/viewpost.jsp?thread=256848">The Dark Tower of Meta-levels</a></address>
<address>The Adventures of a Pythonista in Schemeland/22</address>
<address>Michele Simionato</address>
<p>If this article is any indication, I should read Simionato&#8217;s whole series.  Here, he talks about the Tower of Reflection, and he gives an example of how easy it is to write macros that fail by mixing phases.  (That is a common theme in these articles.  It&#8217;s very easy to screw up.)</p>
<p>Then he gives an example where an R6RS library needs to export names at a negative meta level.  Which is only surprising until you realize it&#8217;s a negative level relative to the library&#8217;s own level.</p>
<address><a href="http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521545668">Lisp in Small Pieces</a></address>
<address>Chapter 9: Macros, Their Use and Abuse<br />
</address>
<address>Christian Queinnec</address>
<address>ISBN 0-521-54566-8<br />
</address>
<p>Lisp in Small Pieces has been a great text, explaining difficult concepts thoroughly.  But the macro chapter was a letdown.  I think the problem is that at the time of publication (1994), macros weren&#8217;t fully understood yet.  The Scheme community certainly hadn&#8217;t reached any kind of consensus on them.</p>
<address><a href="http://www.skyfree.org/linux/references/ELF_Format.pdf">Executable and Linkable Format (ELF)</a></address>
<address>author not attributed</address>
<p>An introduction to our favorite object file format.  I&#8217;ve been wondering whether it would be a suitable container for compiled Scheme bytecode files.  I haven&#8217;t read enough of it to have an opinion yet.  I&#8217;m also not entirely sure what a compiled Scheme object file needs to contain.</p>
<address><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.114.3275">The Mystery of the Tower Revealed: A Nonreflective Description of the Reflective Tower</a></address>
<address>Mitchell Wand, Daniel P. Friedman</address>
<p>I haven&#8217;t read this one yet.  It&#8217;s old, written in 1988, but it&#8217;s cited a lot.  And the title is cool.</p>
<p>So.  What have I learned from all of this?  I believe I&#8217;ve been convinced that the separate phases model of compilation is the way to go.  I think that with careful study of SRFI 72 and its reference implementation, I can implement a useful macro expander.  I think that a bytecode object file format is attainable, though I don&#8217;t have a clear direction to follow yet.  And I&#8217;m still uncertain how to bootstrap the process.  How much of the system do you have to build in the bootstrap language, and how much can you write in Scheme?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/616/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/616/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/616/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/616/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/616/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/616/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/616/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/616/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/616/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/616/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/616/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/616/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/616/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/616/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=616&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2011/01/24/reading-list/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>A Safer Scheme Interpreter, Part 3</title>
		<link>http://kernelbob.wordpress.com/2011/01/04/a-safer-scheme-interpreter-part-3/</link>
		<comments>http://kernelbob.wordpress.com/2011/01/04/a-safer-scheme-interpreter-part-3/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 01:35:06 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Scheme]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[computers]]></category>
		<category><![CDATA[garbage collection]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[kbscheme]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=600</guid>
		<description><![CDATA[In Part 1, I explained why my Scheme interpreter, Schetoo, has the ability to fail or restart any instruction.  In Part 2, I showed how it automatically checks that instructions do all necessary checks before they have any side effects.  Those two posts described raising exceptions with longjmp, but didn&#8217;t really explain how the interpreter [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=600&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a title="Bobbing for Kernels: A Safer Scheme Interpreter" href="http://kernelbob.wordpress.com/2011/01/02/a-safer-scheme-interpreter/">Part 1</a>, I explained why my Scheme interpreter, <a title="Schetoo repository on GitHub" href="https://github.com/kbob/schetoo">Schetoo</a>, has the ability to fail or restart any instruction.  In <a title="Bobbing for Kernels: A Safer Scheme Interpreter, Part 2" href="http://kernelbob.wordpress.com/2011/01/03/a-safer-scheme-interpreter-part-2/">Part 2</a>, I showed how it automatically checks that instructions do all necessary checks before they have any side effects.  Those two posts described raising exceptions with <strong>longjmp</strong>, but didn&#8217;t really explain how the interpreter catches exceptions.</p>
<p><span id="more-600"></span>C has a poverty-stricken exception mechanism called <strong>setjmp</strong>/<strong>longjmp</strong>.  <strong>setjmp</strong> saves the current machine registers in a structure called a <strong>jmp_buf</strong>.  Then it returns 0.  When <strong>longjmp</strong> is called, it restores the registers to their saved values, and returns whatever you passed as its second argument.  Except that because it restored the stack pointer, the place it returns to is <strong>setjmp</strong>&#8216;s caller, not <strong>longjmp</strong>&#8216;s.  So <strong>setjmp</strong>&#8216;s caller can check the return value to know whether <strong>setjmp</strong> returned normally or <strong>longjmp</strong> has raised an exception.<em></em></p>
<p><em>(You see what they did there?  <strong>jmp_buf</strong> is spelled with a <strong>u</strong>.  So much for the theory that the guy who designed this stuff had no </em><strong>U</strong><em> key on his keyboard.  Hey, it was the 1970s.  Sideburns were long, and identifiers were short.  They would have needed $10,000 for an additional kilobyte of core memory if they used one vowel too many.)</em></p>
<p>Here is an example of <strong>setjmp</strong> and <strong>longjmp</strong>.</p>
<pre style="padding-left:30px;">jmp_buf foo;

void f()
{
   if (the_moon_is_full())
    longjmp(foo, 1);
}

void main()
{
    if (setjmp(foo) == 0)
        printf("I just called setjmp\n");
    else
        printf("Got here from longjmp\n");
    f();
}</pre>
<p>It doesn&#8217;t really work very well because compilers do far more optimizations than they did in 1977 when <strong>setjmp</strong>/<strong>longjmp</strong> were invented.  Here&#8217;s what the C99 standard says.</p>
<blockquote><p>An invocation of the setjmp macro shall appear only in one of the following contexts:</p>
<ul>
<li>the entire controlling expression of a selection or iteration statement;</li>
<li>one operand of a relational or equality operator with the other operand an integer constant expression, with the resulting expression being the entire controlling expression of a selection or iteration statement;</li>
<li>the operand of a unary ! operator with the resulting expression being the entire controlling expression of a selection or iteration statement; or</li>
<li>the entire expression of an expression statement (possibly cast to void).</li>
</ul>
<p>If the invocation appears in any other context, the behavior is undefined.</p></blockquote>
<p>In other words, you can use <strong>setjmp</strong> in one of these ways.  If you do anything else with it, your program may not work.</p>
<pre style="padding-left:30px;">if (setjmp(...)) ...

while (setjmp(...)) ...

switch (setjmp(...)) ...

if/while (setjmp(...) == N) ...

if/while (!setjmp(...)) ...

(void)setjmp(...);</pre>
<p>So that&#8217;s <strong>setjmp</strong>.  Now back to Schetoo.</p>
<p>Schetoo&#8217;s interpreter keeps its state in two registers between instructions: <strong>cont</strong> and <strong>values</strong>.  It&#8217;s not important to understand how the registers are used, just that each instruction modifies them, and instructions communicate primarily through these two registers.</p>
<p>We have a structure that holds the two registers, <strong>cv_t</strong>.</p>
<pre style="padding-left:30px;">typedef struct cv {    /* cont and values */
    obj_t cv_cont;
    obj_t cv_values;
} cv_t;</pre>
<p>And we have two static root pointers that contain the registers&#8217; current values.  Note that these are only valid during a garbage collection.  Most of the time they hold garbage values.</p>
<pre style="padding-left:30px;">obj_t cont_root   = UNINITIALIZED_OBJ;
obj_t values_root = UNINITIALIZED_OBJ;</pre>
<p>Here is the main loop of the interpreter.  <strong>cont_proc()</strong> returns a pointer to the C function that implements the next instruction.  That function is called with the two registers as arguments, and it returns the two registers&#8217; new values in a <strong>cv_t</strong> structure.  Then the registers are copied back, the instruction is committed (debug build only, see previous post), and we go on to the next instruction.</p>
<pre style="padding-left:30px;">while (!is_null(cont)) {
    cv_t ret = cont_proc(cont)(cont, values);
    cont   = ret.cv_cont;
    values = ret.cv_values;
    COMMIT();
}</pre>
<p>Now let&#8217;s look at the whole function that implements the main loop.  (I&#8217;ve simplified it for readability.)  It starts with handlers for two kinds of exceptions, then falls into the main loop.</p>
<p>Notice how the two registers are copied into the root pointers before GC, then copied back afterwards.</p>
<pre style="padding-left:30px;">obj_t core_eval_cont(volatile obj_t cont, volatile obj_t values)
{
    switch (setjmp(eval_restart)) {

    case 0:
        break;

    case LT_THROWN:
        {
            cv_t ret = push_exception(cont, values);
            cont     = ret.cv_cont;
            values   = ret.cv_values;
        }
        break;

    case LT_HEAP_FULL:
        cont_root   = cont;
        values_root = values;
        collect_garbage();
        cont        = cont_root;
        values      = values_root;
        cont_root   = UNINITIALIZED_OBJ;
        values_root = UNINITIALIZED_OBJ;
        break;
    }

    while (!is_null(cont)) {
        cv_t ret = cont_proc(cont)(cont, values);
        cont   = ret.cv_cont;
        values = ret.cv_values;
        COMMIT();
    }
    return CAR(values);
}</pre>
<p>So there it is.  The skeleton of an interpreter where any instruction can be failed or restarted, and the need for GC is treated as an exception.</p>
<p>What is the overhead?  Every instruction is invoked through an indirect function call.  The registers are copied three times for every instruction.  (Fortunately, there are only two registers.)  In exchange, there is no bookkeeping overhead for local root pointers, and each exception only requires a single test and branch in the case where it isn&#8217;t raised.</p>
<p>But more importantly, it&#8217;s easier to write correct code.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/600/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/600/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/600/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/600/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/600/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/600/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/600/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/600/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=600&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2011/01/04/a-safer-scheme-interpreter-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>A Safer Scheme Interpreter, Part 2</title>
		<link>http://kernelbob.wordpress.com/2011/01/03/a-safer-scheme-interpreter-part-2/</link>
		<comments>http://kernelbob.wordpress.com/2011/01/03/a-safer-scheme-interpreter-part-2/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 21:43:56 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Scheme]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[computers]]></category>
		<category><![CDATA[garbage collection]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Schetoo]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=596</guid>
		<description><![CDATA[In my last post, I promised to explain how my Scheme interpreter, Schetoo, can automatically verify that its instructions are restartable.  But first, some background. In the last post, I proposed Rules 1, 2 and 2a. Rule 1.  Any instruction of the interpreter may be abandoned and restarted. Rule 2.  Do everything that might fail [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=596&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a title="Bobbing for Kenrels: A Safer Scheme Interpreter" href="http://kernelbob.wordpress.com/2011/01/02/a-safer-scheme-interpreter/" target="_blank">my last post</a>, I promised to explain how my Scheme interpreter, <a title="Schetoo repositoy on GitHub" href="https://github.com/kbob/schetoo" target="_blank">Schetoo</a>, can automatically verify that its instructions are restartable.  But first, some background.</p>
<p><span id="more-596"></span>In the last post, I proposed Rules 1, 2 and 2a.</p>
<blockquote><p>Rule 1.  Any instruction of the interpreter may be abandoned and restarted.</p>
<p>Rule 2.  Do everything that might fail before doing anything with side effects.</p>
<p>Rule 2a.  &#8220;Side effects&#8221; only means memory that was already reachable before the current instruction (and I/O).</p></blockquote>
<p>Schetoo allocates memory sequentially.  The pointer <strong>next_alloc</strong> points to the beginning of free memory to allocate.  Here&#8217;s the allocator, somewhat simplified.</p>
<pre style="padding-left:30px;">void *next_alloc, *alloc_end;

heap_object_t *mem_alloc_obj(size_t alloc_size)
{
    if (next_alloc + alloc_size &gt; alloc_end)
        send_heap_full();      /* calls longjmp() */
    heap_object_t *fresh_object = next_alloc;
    next_alloc += alloc_size;
    return fresh_object;
}</pre>
<p>That means that memory allocated by the current instruction is contiguous.  Before each instruction starts, the interpreter calls a macro called <strong>COMMIT()</strong>, which saves a copy of <strong>next_alloc</strong> in a variable called <strong>committed</strong>.  Any object whose address is between <strong>committed</strong> and <strong>next_alloc</strong> must have been freshly allocated in the current instruction.  As the name implies, <strong>COMMIT()</strong> commits the freshly created objects after the instruction successfully completes.</p>
<p>When memory allocation fails, we raise an &#8220;exception&#8221;.  C doesn&#8217;t have real exceptions, but the <strong>setjmp</strong>/<strong>longjmp</strong> facility is good enough.</p>
<p>An instruction has two phases: Can Fail and Can&#8217;t Fail.  In the former, the instruction can check arguments and allocate memory, and any of those operations can raise an exception that fails the instruction.  As soon as the instruction has a side effect, it moves into Can&#8217;t Fail phase.</p>
<p>Schetoo has a global flag, <strong>retry_okay</strong>, that records which phase the current instruction is in.  (The name is a little misleading.  Think of it as <strong>failure_okay</strong>, since some failures don&#8217;t lead to retry.)</p>
<p>Side effects occur in a small number of places.  Each of those places sets the current phase to Can&#8217;t Fail and records the current function and line number.  This is done through a macro, <strong>SIDE_EFFECT()</strong>.</p>
<p>Object mutations use a higher-level macro, <strong>MUTATE(obj)</strong>.  <strong>MUTATE</strong> calls <strong>SIDE_EFFECT</strong>, but only if the object is committed.</p>
<p>Failures can occur in an even smaller number of places.  One is the allocator.  Another is a macro called <strong>CHECK</strong> that is used for all argument checking.  Those call a macro called <strong>COULD_RETRY()</strong>.  <strong>COULD_RETRY</strong> verifies that the instruction is in Can Fail phase, and if it isn&#8217;t, it raises an assertion error immediately, with the function and line number where the most recent side effect occurred. (Once again, the name isn&#8217;t right.  It should be called <strong>COULD_FAIL</strong>, I think.)</p>
<p>All of these checks happen in a debug build.  In a production build, the four macros, <strong>COMMIT</strong>, <strong>SIDE_EFFECT</strong>, <strong>MUTATE</strong>, and <strong>COULD_RETRY</strong>, are all redefined to do nothing, and no checking is done.  So there is no overhead at all in a production build.</p>
<p>I&#8217;ve mentioned that exceptions use <strong>longjmp()</strong>.  In my next post, I&#8217;ll explain how the interpreter&#8217;s main loop catches them.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/596/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/596/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/596/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/596/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/596/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/596/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/596/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/596/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/596/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/596/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/596/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/596/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/596/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/596/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=596&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2011/01/03/a-safer-scheme-interpreter-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>A Safer Scheme Interpreter</title>
		<link>http://kernelbob.wordpress.com/2011/01/02/a-safer-scheme-interpreter/</link>
		<comments>http://kernelbob.wordpress.com/2011/01/02/a-safer-scheme-interpreter/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 20:29:15 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Scheme]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[computers]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[kbscheme]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Schetoo]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=591</guid>
		<description><![CDATA[In the first half of 2010, I wrote a Scheme interpreter which I called Schetoo. It is a sequel to an interpreter called kbscheme, which I worked on off-and-on in 2008 and 2009. Both are written in C. You can see them both on github. https://github.com/kbob/kbscheme https://github.com/kbob/schetoo I undertook these projects to learn more about [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=591&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In the first half of 2010, I wrote a Scheme interpreter which I called Schetoo.  It is a sequel to an interpreter called kbscheme, which I worked on off-and-on in 2008 and 2009.  Both are written in C.</p>
<p>You can see them both on github.<a href="https://github.com/kbob/kbscheme"></a></p>
<p style="padding-left:30px;"><a href="https://github.com/kbob/kbscheme">https://github.com/kbob/kbscheme</a><br />
<a href="https://github.com/kbob/schetoo">https://github.com/kbob/schetoo</a></p>
<p>I undertook these projects to learn more about Scheme, interpreters, and garbage collection.  Along the way, I came up with an interesting technique to make interpreter implementation less error-prone.  That&#8217;s what I want to write about today.</p>
<p><span id="more-591"></span>Any interpreter with garbage collection needs some way to find all the live objects in the heap.  That generally means they need to keep track of all the &#8220;root pointers&#8221;, pointers that live outside the heap but point into it.  When you write C code, you generate a lot of root pointers.</p>
<p>For example, here is kbscheme&#8217;s implementation of <strong>string-&gt;list</strong>.  <strong>string-&gt;list</strong> is a primitive procedure that returns the characters in a string as a linked list.</p>
<pre style="padding-left:30px;">DEFINE_PROC(L"string-&gt;list")
{
    AUTO_ROOT(str, pair_car(F_SUBJ));
    AUTO_ROOT(list, NIL);
    AUTO_ROOT(chr, NIL);
    size_t pos;
    for (pos = string_len(str); pos; --pos) {
        chr = make_character(string_value(str)[pos - 1]);
        list = make_pair(chr, list);
    }
    RETURN(list);
}</pre>
<p><strong>AUTO_ROOT</strong> is a macro that declares and initializes a local variable, then pushes it onto a global linked list of root pointers.  <strong>RETURN</strong> pops all the roots allocated in the current function before returning.</p>
<p>That&#8217;s a lot of runtime overhead.  That&#8217;s also a lot of noise in the source code.  And root pointers were the source of several bugs where roots either were not recorded, contained invalid pointers at GC time, or were pushed onto the root stack more than once.  Each bug was a heap corruption <a title="Wikipedia" href="http://en.wikipedia.org/wiki/Unusual_software_bug#Heisenbug">Heisenbug</a>, of course, since memory is only corrupted if the garbage collector runs while the function is active, and it only shows up later when the object&#8217;s memory is reused.  That is the very worst kind of problem to debug.</p>
<p>For those reasons, one of my goals for Schetoo was to eliminate manual tracking of root pointers.  Here is the same procedure in Schetoo.</p>
<pre style="padding-left:30px;">DEFINE_PROC(L"string-&gt;list", 1)(obj_t string)
{
    const char_t *chars = string_value(string);
    obj_t list = EMPTY_LIST;
    for (size_t pos = string_len(string); pos; --pos)
        list = make_pair(make_character(chars[pos - 1]), list);
    return list;
}</pre>
<p>No root bookkeeping.  No macros, aside from the weird function name.  A whole class of bugs eliminated.  I&#8217;d like to say no runtime overhead, but that&#8217;s not quite true, as you&#8217;ll see.</p>
<p>Schetoo has a simple rule.</p>
<blockquote><p>Rule 1.  Any instruction of the interpreter may be abandoned and restarted.</p></blockquote>
<p>In this example, if <strong>make_pair()</strong> triggers a garbage collection, it signals an exception using <strong>longjmp()</strong>, and <strong>string-&gt;list</strong> is restarted after the collection.</p>
<p>Schetoo uses the same mechanism for user exceptions.  In this example, both <strong>string_value()</strong> and <strong>string_len()</strong> check that they are passed a string.  If not, they raise an exception which also <strong>longjmp</strong>s back to the interpreter&#8217;s main loop, so <strong>string-&gt;list</strong> doesn&#8217;t need any error checking logic.</p>
<p>Why is there no error checking the kbscheme example?  In kbscheme, any error at all was fatal and terminated the whole interpreter.  D&#8217;oh!</p>
<p>There&#8217;s more to it than that, of course.  Now there is a new rule that every procedure has to follow:</p>
<blockquote><p>Rule 2.  Do everything that might fail before doing anything with side effects.</p></blockquote>
<p>There are two kinds of side effects in Schetoo: modifying memory and I/O.  We won&#8217;t talk about I/O here except to mention that we have to be careful to follow Rule 2 when we do it.</p>
<p><strong>string-&gt;list</strong> doesn&#8217;t have any side effects, so it follows Rule 2 trivially.</p>
<p>What about all those calls to <strong>make_list()</strong>?  Don&#8217;t they modify the heap?  Aren&#8217;t they side effects?  Yes, but they only modify freshly allocated memory.  That doesn&#8217;t count, because with no root pointers, that memory will be instantly turned into garbage when the instruction is abandoned.</p>
<blockquote><p>Rule 2a.  &#8220;Side effects&#8221; only means memory that was already reachable before the current instruction (and I/O).</p></blockquote>
<p>Is this an improvement?  We have replaced kbscheme&#8217;s tricky rule, &#8220;Always track local variables that are root pointers&#8221;, with Rule 2, which also looks tricky.</p>
<p>Yes, this is better, because Schetoo can verify Rule 2 at runtime.  In my next post, I&#8217;ll explain how it works.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/591/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/591/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/591/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/591/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/591/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/591/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/591/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/591/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/591/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/591/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/591/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/591/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/591/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/591/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=591&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2011/01/02/a-safer-scheme-interpreter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>Variadic functions in C: a new idiom?</title>
		<link>http://kernelbob.wordpress.com/2010/04/05/variadic-functions-in-c-a-new-idiom/</link>
		<comments>http://kernelbob.wordpress.com/2010/04/05/variadic-functions-in-c-a-new-idiom/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 06:00:14 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[C99]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[macros]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=581</guid>
		<description><![CDATA[For a long time, C has let you write functions that take a variable number of arguments.  But C leaves it up to each variadic function to figure out how many arguments it&#8217;s been passed, and up to each caller to pass the right arguments. Here&#8217;s a cute hack to make variadic functions easier to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=581&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For a long time, C has let you write functions that take a variable number of arguments.  But C leaves it up to each variadic function to figure out how many arguments it&#8217;s been passed, and up to each caller to pass the right arguments.</p>
<p>Here&#8217;s a cute hack to make variadic functions easier to write and a little harder to call incorrectly.</p>
<p><span id="more-581"></span>As a contrived example, let&#8217;s write a function that copies a tag and a sequence of floating-point arguments into a linked list allocated on the heap.  The first attempt might look like this.</p>
<pre style="padding-left:30px;">#include &lt;stdarg.h&gt;

typedef struct node node;
    struct node {
    double datum;
    char   tag;
    node  *next;
};

node *link_list_A(char tag, int count, ...)
{
    node *head = NULL;
    node **patch = &amp;head;
    int i;
    va_list ap;

    va_start(ap, count);
    for (i = 0; i &lt; count; i++) {
        node *p  = malloc(sizeof *p);
        p-&gt;datum = va_arg(ap, double);
        p-&gt;tag   = tag;
        p-&gt;next  = NULL;
        *patch   = p;
        patch    = &amp;p-&gt;next;
    }
    va_end(ap);
    return head;
}
</pre>
<p>You&#8217;d call it like this.</p>
<pre style="padding-left:30px;">    node *p = link_list_A('A', 5, 1.0, 1.5, 2.0, 2.5, 3.0);
</pre>
<p>There&#8217;s just a little problem with that.  What happens if you go back later and change the arguments?  You have to remember to change the count.  Also, you might miscount and tell it it has 16 arguments when it really has 17.</p>
<p>Another approach is to use an end marker instead of a count.</p>
<pre style="padding-left:30px;">﻿# define ENDARG (-1.0)

node *link_list_B(char tag, ...)
{
    node *head = NULL, **patch = &amp;head;
    double datum;
    va_list ap;

    va_start(ap, tag);
    while ((datum = va_arg(ap, double)) != ENDARG) {
        node *p  = malloc(sizeof *p);
        p-&gt;tag   = tag;
        p-&gt;datum = datum;
        p-&gt;next  = NULL;
        *patch   = p;
        patch    = &amp;p-&gt;next;
    }
    va_end(ap);
    return head;
}
</pre>
<p>&#8230;</p>
<pre style="padding-left:30px;">    node *p = link_list_B('B', 1.0, 1.5, 2.0, 2.5, 3.0, ENDARG);
</pre>
<p>That&#8217;s better.  But wouldn&#8217;t it be even nicer if we could eliminate ENDARG in the caller?  It&#8217;s a big wart on the readability of the program.</p>
<p>C99 has variadic macros as well as variadic functions.  By wrapping the function in a macro, the macro can supply the end marker instead of sprinkling it throughout the source code.</p>
<p>(Hey, C99 has it&#8217;s been ratified for eleven years.  Don&#8217;t look so scandalized.)</p>
<pre style="padding-left:30px;">#define link_list_C(tag, ...) \
    (link_list_B(tag, __VA_ARGS__, ENDARG)) // link_list_B defined above</pre>
<p>Now you call it like this.</p>
<pre style="padding-left:30px;">    node *p = link_list_C('C', 1.0, 1.5, 2.0, 2.5, 3.0);</pre>
<p>It&#8217;s not a big deal, but it makes the code a little more readable. And it&#8217;s an idiom I haven&#8217;t seen before.</p>
<p>I use the idiom several places in my Scheme interpreter, schetoo.  For example, Schetoo has a C macro, MAKE_LIST, which is analogous to Scheme&#8217;s list procedure.</p>
<p>Scheme:</p>
<pre style="padding-left:30px;">(list 'a 'b (list 'c))
<span style="color:#993300;">=&gt; (a b (c))</span></pre>
<p>C:</p>
<pre style="padding-left:30px;">obj_t a = make_symbol_from_C_str(L"a");
obj_t b = make_symbol_from_C_str(L"b");
obj_t c = make_symbol_from_C_str(L"c");
MAKE_LIST(a, b, MAKE_LIST(c));
<span style="color:#993300;">=&gt; (a b (c))
</span></pre>
<p>It&#8217;s a pretty good analogue, I think.</p>
<p>The source for <a title="schetoo on github" href="http://github.com/kbob/schetoo" target="_blank">schetoo</a> is on github.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/581/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/581/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/581/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/581/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/581/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/581/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/581/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/581/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/581/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/581/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/581/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/581/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/581/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/581/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=581&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2010/04/05/variadic-functions-in-c-a-new-idiom/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>Son of Scheme: Introducing Schetoo</title>
		<link>http://kernelbob.wordpress.com/2010/02/13/son-of-scheme-introducing-schetoo/</link>
		<comments>http://kernelbob.wordpress.com/2010/02/13/son-of-scheme-introducing-schetoo/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 06:07:14 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Scheme]]></category>
		<category><![CDATA[call/cc]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Schetoo]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=576</guid>
		<description><![CDATA[I&#8217;ve started a new Scheme project. This one is called Schetoo. The name has connotations of &#8220;Scheme Two&#8221;, &#8220;me too&#8221;, and &#8220;Gentoo&#8221; (a hardcore Linux distribution and a breed of penguin). A &#8216;blogger named Peter Michaux started a series in January called Scheme from Scratch. His goal was to write a very quick and dirty [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=576&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve started a new Scheme project.  This one is called Schetoo.  The name has connotations of &#8220;Scheme Two&#8221;, &#8220;me too&#8221;, and &#8220;Gentoo&#8221; (a hardcore Linux distribution and a breed of penguin).</p>
<p>A &#8216;blogger named Peter Michaux started a series in January called <a href="http://peter.michaux.ca/index#Scheme%20from%20Scratch">Scheme from Scratch</a>.  His goal was to write a very quick and dirty Scheme, just enough to bootstrap a Scheme compiler.  I read his postings and decided to get started again.</p>
<p>Schetoo is similar in concept to my first Scheme, <a href="http://kernelbob.wordpress.com/tag/kbscheme/">kbscheme</a>.  In fact, I reused a fair amount of code to get Schetoo up and running faster. But at the same time, I&#8217;m applying what I learned to try to get a better design.</p>
<p>I&#8217;ve published the code on GitHub.</p>
<pre><a href="http://github.com/kbob/schetoo">http://github.com/kbob/schetoo</a>
</pre>
<h3><span id="more-576"></span>Goals</h3>
<p>The primary goal for Schetoo is pedagogical.  I want to understand the Scheme language and how to design language runtimes.  I intend to focus on performance more than last time, because kbscheme was running for many seconds just initializing itself.</p>
<p>Another goal is to have no dynamic memory outside of the heap.  No recursion so stack size is bounded.  No mallocs.  At present, it falls short of that in two ways.  My I/O subsystem uses malloc for memory buffers, and the print routine is recursive.  Both were thrown together early on to get something running, and both will eventually be rewritten.  I&#8217;ll rewrite I/O in C and rewrite print in Scheme so it can remain recursive.</p>
<p>The third goal is to integrate macro translation into Schetoo. I&#8217;m not sure how that will work.</p>
<h3>Status</h3>
<p>Right now, Schetoo is usable for toy programs.</p>
<p>It has a heap with lots of primitive data types: bindings, bytevectors, Booleans, Unicode characters, continuations, fixnums, pairs, procedures, records, record type descriptors (RTDs), strings, symbols, and vectors.  The interpreter also has a hierarchy of condition types constructed from records.  (A Scheme condition is like a Python exception object.)</p>
<p>It has an assortment of primitives for operating on and converting among those types.  I count 44 primitives at the moment.</p>
<p>The reader came from kbscheme, and just like kbscheme, it handles the whole <a title="The Revised^6 Report on the Agorithmic Language Scheme" href="http://www.r6rs.org/" target="_blank">R6RS Scheme</a> language except for non-fixnum numbers.</p>
<p>It also has an evaluator with a nice extension mechanism for adding more procedures and special forms.  Some of the more interesting forms I&#8217;ve implemented are apply, call/cc, define, eval, if, lambda, quote and set!.</p>
<p>There is an exception mechanism, and all the forms are wired to generate exceptions as needed.  There is no way to set an exception handler yet &#8212; the default handler just prints the message and pops back to the REPL.</p>
<p>Finally, there&#8217;s a clever mechanism to track stack-based heap roots with zero overhead.  That will be the subject of a future post.</p>
<p>I&#8217;m planning to implement dynamic-wind and multiple-value expressions someday.  The evaluator was designed with them in mind, but they&#8217;re not implemented yet.</p>
<h3>Design</h3>
<p>Once again, the implementation language is C.  The overall structure is a trampoline-style interpreter using explicit continuations instead of a call stack.  This time, I&#8217;m planning to write less C and more Scheme.  I&#8217;m almost at the point where the read-eval-print loop (REPL) can be written in Scheme.</p>
<p>I used the same basic heap and garbage collector design as last time. There are two significant differences, though.</p>
<p>First, small objects are stored as immediate pointers.  Those include fixnums, (Unicode) characters, Booleans, the empty list, and some other constants.  For example, the Boolean false is represented as a pointer with the binary value 0x0000000E.  There&#8217;s nothing stored at address 0x0000000E, it&#8217;s just a bit pattern.</p>
<p>Second, I&#8217;ve implemented records.  Records are Scheme&#8217;s objects.  Each record has a class (called a record type descriptor or RTD), and classes have single inheritance.  Those both went into the heap design fairly easily.</p>
<p>The evaluator is also similar at a high level, but completely different in the details.  There is a virtual machine (VM), and the VM is a little better defined than last time.  I think I&#8217;ll write a future post about the VM design, too.</p>
<p>And exceptions got designed in early.  That&#8217;s an important part of building a usable interactive environment.</p>
<p>Next Steps</p>
<p>I&#8217;d like to get the REPL into Scheme.  To do that, I need user exception handlers and I/O primitives.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/576/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=576&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2010/02/13/son-of-scheme-introducing-schetoo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>Mac Mini Video Upgrade</title>
		<link>http://kernelbob.wordpress.com/2010/01/12/mac-mini-video-upgrade/</link>
		<comments>http://kernelbob.wordpress.com/2010/01/12/mac-mini-video-upgrade/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 05:14:23 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[computers]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[HDTV]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=566</guid>
		<description><![CDATA[I recently upgraded our Mac Mini media center with a new video decoder board. Surprisingly, it worked. A couple of weeks ago, an article on Anandtech explained that the XBMC media player now supports a new Broadcom video decoder. They also mentioned that it works on a Mac Mini. We already had a Mac Mini [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=566&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently upgraded our Mac Mini media center with a new video decoder board.  Surprisingly, it worked.</p>
<p><span id="more-566"></span>A couple of weeks ago, <a href="http://www.anandtech.com/gadgets/showdoc.aspx?i=3701">an article on Anandtech</a> explained that the <a href="http://xbmc.org/">XBMC</a> media player now supports a new Broadcom video decoder.  They also mentioned that it works on a Mac Mini.</p>
<p>
We already had a Mac Mini under our TV.  And we were already using XBMC.  And we&#8217;ve got some high bitrate HD video that the Mini couldn&#8217;t decode in real time.</p>
<p>
I opened up the Mini and confirmed that it really did have a mini PCIe slot.  It does.  (This must be the age of the <a href="http://en.wikipedia.org/wiki/Minicomputer">minicomputer</a>.)  The slot was occupied by the Wi-Fi card.  So I could have either high bitrate HD or Wi-Fi.  The house is wired with Cat-5 and the Mini was already plugged in to a gigabit switch, so Wi-Fi isn&#8217;t needed.</p>
<p>
So I ordered the video decoder.  A Broadcom BCM970012 on a mini PCIe card from Logic Supply, as mentioned by Anandtech.</p>
<p>
The video card arrived.  I took the Mini apart.  Slipped the new card in.  Put it back together.  Found out the audio board had come unplugged.  Took it apart again.  Plugged in the audio board.  Put it back together again.  Launched XBMC.  Played some video.  It works.</p>
<p>
The whole thing was so easy it was quite anticlimactic.</p>
<p>
I don&#8217;t have any idea how XBMC is talking to the video card.  It&#8217;s not visible in Mac OS&#8217; System Profile.  It&#8217;s kind of weird to install hardware like this and not know how the operating system interfaces to it.  Normal people cope with this kind of ambiguity, so I guess I can too.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/566/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/566/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/566/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=566&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2010/01/12/mac-mini-video-upgrade/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>Scheme from Scratch</title>
		<link>http://kernelbob.wordpress.com/2010/01/12/scheme-from-scratch/</link>
		<comments>http://kernelbob.wordpress.com/2010/01/12/scheme-from-scratch/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 04:05:45 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Scheme]]></category>
		<category><![CDATA[geeky]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=564</guid>
		<description><![CDATA[Peter Michaux has started a &#8216;blog series called Scheme from Scratch. He&#8217;s made ten posts so far. He&#8217;s developing a Scheme system incrementally, in tiny steps, so that it&#8217;s easy to read along and understand exactly what every bit of code does. Recommended.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=564&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Peter Michaux has started a &#8216;blog series called <a href="http://peter.michaux.ca/index#Scheme%20from%20Scratch">Scheme from Scratch</a>.  He&#8217;s made ten posts so far.  He&#8217;s developing a Scheme system incrementally, in tiny steps, so that it&#8217;s easy to read along and understand exactly what every bit of code does.</p>
<p>Recommended.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/564/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=564&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2010/01/12/scheme-from-scratch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
		<item>
		<title>Scheme: Retrospective</title>
		<link>http://kernelbob.wordpress.com/2010/01/09/scheme-retrospective/</link>
		<comments>http://kernelbob.wordpress.com/2010/01/09/scheme-retrospective/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 06:03:38 +0000</pubDate>
		<dc:creator>kernelbob</dc:creator>
				<category><![CDATA[Scheme]]></category>
		<category><![CDATA[geeky]]></category>
		<category><![CDATA[kbscheme]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://kernelbob.wordpress.com/?p=555</guid>
		<description><![CDATA[The Scheme interpreter project is &#8220;on hold&#8221;. Maybe it&#8217;s &#8220;finished&#8221;. It&#8217;s time to take stock, see what I learned, what I accomplished, and what I could have done better. The Original Goals At the beginning of thie project, in September 2008, I wrote some goals. I don’t know Scheme. I took a couple of classes [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=555&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The Scheme interpreter project is &#8220;on hold&#8221;.  Maybe it&#8217;s &#8220;finished&#8221;.  It&#8217;s time to take stock, see what I learned, what I accomplished, and what I could have done better.</p>
<p><span id="more-555"></span></p>
<h2>The Original Goals</h2>
<p>At the beginning of thie project, in September 2008, <a href="/2008/09/11/not-another-scheme-interpreter/">I wrote some goals</a>.</p>
<blockquote><p>
I don’t know Scheme.  I took a couple of classes that used Lisp way back when, but don’t really know Lisp or Scheme.  There’s no better way to learn a language than to implement it. (-:
</p></blockquote>
<p>
Goal met.  I probably know more about the language&#8217;s nooks and crannies than the average practitioner.</p>
<blockquote><p>
I want to write something in C.  My C is very rusty, since I’ve been using Python exclusively for the last year, and C++ for the last fifteen years.
</p></blockquote>
<p>
Goal exceeded.  Got to write lots of C.  Also started using C at work again a few months later.  Fully fluent in C again, though I&#8217;m much less tolerant of its limitations than I was, say, 20 years ago.</p>
<blockquote><p>
I want to write a garbage collector.  They’ve always fascinated me, but I’ve never written one.
</p></blockquote>
<p>Goal met, just barely.  I wrote a simple stop-and-copy GC.  Copying collectors have always fascinated me and I wanted to see what limitations it would impose on the rest of the implementation.  (See Roots below.)</p>
<blockquote><p>
I have some research ideas about garbage collection that I want to explore.
</p></blockquote>
<p>Not met.  I wrote the simplest possible GC, and then went on to other parts of the system.  I still have some untested ideas about GC.</p>
<p>
In the 16 months since I wrote those goals, they&#8217;ve shifted somewhat.  To the list, I&#8217;d add learning about Unicode, learning about macros, and understanding R6RS&#8217;s semantics (and Scheme semantics in general) in great detail.</p>
<h2>What went well?</h2>
<h3>Memory Manager</h3>
<p>I like the design of the memory subsystem a lot.  It is easily extensible, fast enough, and it feels production quality.</p>
<h3>Evaluator</h3>
<p>The evaluator came together pretty well too.  It took a while to get it right, but then it just worked while lots of things around it changed.</p>
<h3>Reader</h3>
<p>I&#8217;m very pleased with the reader.  I should be &#8212; I rewrote it four or five times.  The final result is a handcoded LL0 parser generator that builds the parsing tables at startup time.  It exactly matches the language spec, because it uses the spec&#8217;s grammar as its input.</p>
<h3>Scanner</h3>
<p>The scanner is also very good, though it&#8217;s incomplete.  It only recognizes a limited number syntax.  I poked around a little with the idea of writing a regular expression compiler, sort of a handbuilt lex, but didn&#8217;t do much, because the existing scanner was fine.</p>
<h2>What went badly?</h2>
<h3>R6RS</h3>
<p>I started with the <a href="http://www.r6rs.org/">Revised^6 Report on Scheme, R6RS</a>.  That seemed like a good idea for several reasons: R6RS uses Unicode throughout, it has well defined exception semantics, it has a library system, it has fewer loose ends and places for the implementor to improvise (aka create incompatibility) than the other major contender, <a href="http://www.schemers.org/Documents/Standards/R5RS/">R5RS</a>.</p>
<p>
But R6RS is a very unpopular Scheme.  Very few implementations are compliant, so it was hard to find good examples to study.  I definitely would have made faster progress implementing R5RS, even with the need to improvise.</p>
<h3>Exceptions</h3>
<p>I never implemented any kind of exception handler.  Any error, no matter how minor, crashes and core-dumps the interpreter.  Now there&#8217;s a code base with several hundred error checks, with no differentiation between runtime errors, syntax errors, heap corruption, etc.  That&#8217;s made debugging harder than it should have been.  And the interpreter is much less useful than one that recovers from a missing parenthesis.</p>
<h3>Roots</h3>
<p>The way I handled root pointers in automatic C variables was error-prone and slow.</p>
<p>
A root pointer is a pointer that is stored outside the heap and points into the heap.  On garbage collection, all root pointers must be traced.  Any memory allocation can trigger a GC.  So any allocation might force a walk of all the roots, including those that are local variables in active C functions.</p>
<p>
My solution was to keep a global (per-thread, actually, if threads ever got implemented) linked list of root pointers and define some macros to push automatic variables onto that list and pop them off.  Those macros have to be called explicitly every time a root pointer goes into or out of scope.</p>
<p>
I must have debugged a hundred occasions when a root pointer was incorrectly pushed or popped.  It made me averse to writing code in C because it was so hard to keep the bookkeeping right.  And continuously updating the linked list couldn&#8217;t have been good for performance.</p>
<h3>Libraries</h3>
<p>Originally, I tried to use the R6RS library mechanism as my primitive means for linking the interpreter together.  That didn&#8217;t work so well.  Then I tried linking everything in but implementing the libraries in C.  That worked okay but was too rigid.  At the end, I started on a redesign where all the primitives are in a global namespace, and a subset namespace is created for user code.  Didn&#8217;t finish that.</p>
<h3>Macros</h3>
<p>I got bogged down in macro processing.  I need to spend more time with a working macro implementation so I understand them better, I think.</p>
<h3>Bootstrapping</h3>
<p>This is the big one.  My original ideas about how to bootstrap the interpreter were kind of naive.  I thought I&#8217;d write the memory manager, some primitives, and an evaluator in C, then start writing more procedures in Scheme.  Didn&#8217;t really know how macro expansion would fit into the process.</p>
<p>
After building a lot of low-level code and getting to the point where my interpreter would read and evaluate code, I spent a long time trying to map out a path to implement everything in terms of slightly lower-level units.  Made a lot of progress &#8212; there are over 100 primitives implemented.  But I still didn&#8217;t find a path.</p>
<p>
I probably invested a couple of hundred hours into reading and re-reading R6RS, R5RS, and Kent Dybvig&#8217;s papers on macro expansion looking for clues as to how the pieces fit together.  There&#8217;s a lot of intro material on the web about building toy interpreters with no macros at all and a lot of research papers about the hard problems of building production-quality Scheme systems, but the middle ground is not well-covered.</p>
<p>
So I&#8217;m taking a break.  Maybe a long break.</p>
<p>
I&#8217;ve pushed the current sources out to both github and gitorious.  Download using either of these commands.</p>
<pre>
git clone git://github.com/kbob/kbscheme.git
git clone git://gitorious.org/kbscheme/mainline.git
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kernelbob.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kernelbob.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kernelbob.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kernelbob.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kernelbob.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kernelbob.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kernelbob.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kernelbob.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kernelbob.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kernelbob.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kernelbob.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kernelbob.wordpress.com/555/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kernelbob.wordpress.com/555/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kernelbob.wordpress.com/555/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kernelbob.wordpress.com&amp;blog=3468363&amp;post=555&amp;subd=kernelbob&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kernelbob.wordpress.com/2010/01/09/scheme-retrospective/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0c5063e80e552802e34a0c3752acc19c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kernelbob</media:title>
		</media:content>
	</item>
	</channel>
</rss>
