<?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>It Seemed Like A Good Idea, At The Time &#187; lisp</title>
	<atom:link href="http://blog.willdonnelly.net/category/lisp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.willdonnelly.net</link>
	<description>Coding, Mostly</description>
	<lastBuildDate>Tue, 15 Dec 2009 23:33:18 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='blog.willdonnelly.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/37c251d80b031b3ae5db9ced8980cb96?s=96&#038;d=http://s2.wp.com/i/buttonw-com.png</url>
		<title>It Seemed Like A Good Idea, At The Time &#187; lisp</title>
		<link>http://blog.willdonnelly.net</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.willdonnelly.net/osd.xml" title="It Seemed Like A Good Idea, At The Time" />
	<atom:link rel='hub' href='http://blog.willdonnelly.net/?pushpress=hub'/>
		<item>
		<title>Fixing Broken Macros with Eval and Quasiquote</title>
		<link>http://blog.willdonnelly.net/2009/03/21/fixing-broken-macros-with-eval-and-quasiquote/</link>
		<comments>http://blog.willdonnelly.net/2009/03/21/fixing-broken-macros-with-eval-and-quasiquote/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 01:20:36 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[eval]]></category>
		<category><![CDATA[macro]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=210</guid>
		<description><![CDATA[Recently, I found myself needing to deal with a &#8220;convenience&#8221; macro, which quoted several of its arguments for me before passing them along to the real function.  Unfortunately, only the macro was exported from the library, and I was unable to access the base function.
(define-syntax convenient-function
  (syntax-rules ()
    ((_ arg1 arg2) [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=210&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Recently, I found myself needing to deal with a &#8220;convenience&#8221; macro, which quoted several of its arguments for me before passing them along to the real function.  Unfortunately, only the macro was exported from the library, and I was unable to access the base function.</p>
<pre>(<span style="color:#000080;">define-syntax</span> <span style="color:#008b8b;">convenient-function</span>
  (<span style="color:#000080;">syntax-rules</span> ()
    ((_ arg1 arg2) (much-harder-function 'arg1 'arg2))))</pre>
<p>How useful.  To save me a handful of quotes, I lose the ability to programmatically generate my arguments.</p>
<p>As I was loath to reimplement the entire library just to regain that ability, I looked for another solution.  Thankfully, I found one.</p>
<pre>(<span style="color:#000080;">define</span> (<span style="color:#008b8b;">much-harder-function</span> arg1 arg2)
  (eval `(convenient-function ,arg1 ,arg2)
        (environment '(convenient-lib))))</pre>
<p>As far as I can tell, this circumvents the macro&#8217;s quoting features entirely to allow me to pass in a dynamically generated symbol.  While it won&#8217;t work with functions which modify the environment, it worked well in my case, and allowed me to move on to more interesting code.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/210/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=210&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2009/03/21/fixing-broken-macros-with-eval-and-quasiquote/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
		<item>
		<title>SRFI-0 for Detecting Scheme Implementation</title>
		<link>http://blog.willdonnelly.net/2009/03/14/srfi-0-for-detecting-scheme-implementation/</link>
		<comments>http://blog.willdonnelly.net/2009/03/14/srfi-0-for-detecting-scheme-implementation/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 23:44:11 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[scheme]]></category>
		<category><![CDATA[srfi-0]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=202</guid>
		<description><![CDATA[I found out earlier today that SRFI-0 can be used to determine the host Scheme in some cases.  Here is the result of my testing, in case someone finds it useful:
No SRFI-0 by default:

mzscheme
ikarus
scheme48

Name exported for cond-expand:



Scheme Name&#160;&#160;&#160;&#160;
SRFI-0 Feature Name




CHICKEN
chicken


Guile
guile


Bigloo
bigloo


Gambit
gambit


MIT Scheme
mit


Gauche
gauche



       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=202&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I found out earlier today that SRFI-0 can be used to determine the host Scheme in some cases.  Here is the result of my testing, in case someone finds it useful:</p>
<p>No SRFI-0 by default:</p>
<ul>
<li>mzscheme</li>
<li>ikarus</li>
<li>scheme48</li>
</ul>
<p>Name exported for cond-expand:</p>
<table border="0">
<thead>
<tr>
<td><b>Scheme Name&nbsp;&nbsp;&nbsp;&nbsp;</b></td>
<td><b>SRFI-0 Feature Name</b></td>
</tr>
</thead>
<tbody>
<tr>
<td>CHICKEN</td>
<td>chicken</td>
</tr>
<tr>
<td>Guile</td>
<td>guile</td>
</tr>
<tr>
<td>Bigloo</td>
<td>bigloo</td>
</tr>
<tr>
<td>Gambit</td>
<td>gambit</td>
</tr>
<tr>
<td>MIT Scheme</td>
<td>mit</td>
</tr>
<tr>
<td>Gauche</td>
<td>gauche</td>
</tr>
</tbody>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/202/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=202&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2009/03/14/srfi-0-for-detecting-scheme-implementation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
		<item>
		<title>Runtime Scheme Detection</title>
		<link>http://blog.willdonnelly.net/2009/03/14/runtime-scheme-detection/</link>
		<comments>http://blog.willdonnelly.net/2009/03/14/runtime-scheme-detection/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 21:33:32 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[portability]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=191</guid>
		<description><![CDATA[I really want my code to be &#8220;write once, run anywhere&#8221;, at least as far as Schemes go.  R6RS library features make strides toward that goal.  Only, there&#8217;s not many R6RS Schemes.  Since there are a whole lot of R5RS ones, I&#8217;d like to include R5RS in the portability fun.
In many cases, enough functionality appears [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=191&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I really want my code to be &#8220;write once, run anywhere&#8221;, at least as far as Schemes go.  R6RS library features make strides toward that goal.  Only, there&#8217;s not many R6RS Schemes.  Since there are a whole lot of R5RS ones, I&#8217;d like to include R5RS in the portability fun.</p>
<p>In many cases, enough functionality appears in all major implementations to make some major steps toward portability.  So a while back, I decided to get a few things out of the way (you know, processes, FFI, things like that).</p>
<p>To make simple, portable libraries, we need to find out some details about the Scheme implementation the code is running under.  Unfortunately, there is no standard way to do this.  We could just call a function and see if it worked, but then we throw an error, and there&#8217;s no standard way to trap those in R5RS.  And even if a function of the given name existed, we still don&#8217;t know what arguments it takes, because that differs too.</p>
<p>So we&#8217;re left with some sort of indirect detection method,  guessing the implementation based on a bunch of unrelated tests.</p>
<p>So I gathered a list of as many nonstandardized/undefined behaviours as possible (mainly from <a title="Scheme Implementation Choices" href="http://web.mit.edu/~axch/www/scheme/choices.html">this table</a>, and grepping the R5RS spec for the word &#8220;undefined&#8221;).  Then I filtered those differences down to a bunch of tests that won&#8217;t error out.  Then I took the tests that gave meaningful results, and because I had enough of those to be picky, I took only tests which fit on a single line.</p>
<p>The resulting set of 20 tests generates a sort of &#8220;signature&#8221; &#8212; a list of twenty boolean values that identifies the host Scheme.</p>
<p>Currently the code works on:</p>
<ul>
<li>MzScheme</li>
<li>CHICKEN</li>
<li>Guile</li>
<li>Bigloo</li>
<li>Gambit</li>
<li>Ikarus</li>
<li>Scheme48</li>
<li>MIT Scheme</li>
<li>Gauche</li>
</ul>
<p>This is actually a list of all the implementations I have installed right now, and other implementations can be supported just by adding another line to the signatures list.</p>
<p>On Scheme implementations which provide a compiled and an interpreted mode, only interpreted has been tested (I don&#8217;t really know how to use a compiled Scheme, so I didn&#8217;t).  Some Schemes have different behaviour interpreted and compiled, so caution should be used there.</p>
<p>Enough talk, here&#8217;s the code:</p>
<pre><span style="color:#228b22;font-style:italic;">;;;</span><span style="color:#228b22;font-style:italic;">
</span><span style="color:#228b22;font-style:italic;">;;; </span><span style="color:#228b22;font-style:italic;">DETECT
</span><span style="color:#228b22;font-style:italic;">;;;   </span><span style="color:#228b22;font-style:italic;">A set of functions to allow an interpreted Scheme
</span><span style="color:#228b22;font-style:italic;">;;;    </span><span style="color:#228b22;font-style:italic;">program to determine the implementation it is
</span><span style="color:#228b22;font-style:italic;">;;;    </span><span style="color:#228b22;font-style:italic;">running under.
</span><span style="color:#228b22;font-style:italic;">;;;</span><span style="color:#228b22;font-style:italic;">
</span>
<span style="color:#228b22;font-style:italic;">;;</span><span style="color:#228b22;font-style:italic;">
</span><span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">DETECT:SIGNATURE
</span><span style="color:#228b22;font-style:italic;">;;   </span><span style="color:#228b22;font-style:italic;">Assemble a signature for the current
</span><span style="color:#228b22;font-style:italic;">;;   </span><span style="color:#228b22;font-style:italic;">Scheme implementation.
</span><span style="color:#228b22;font-style:italic;">;;</span><span style="color:#228b22;font-style:italic;">
</span>(<span style="color:#000080;">define</span> (<span style="color:#008b8b;">detect:signature</span>)
  (list
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: exact-sqrt
</span>    (exact? (sqrt 4))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: exact-times-zero
</span>    (exact? (* 0 3.1))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: exact-div-zero
</span>    (exact? (/ 0 4.7))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: exact-rationals
</span>    (exact? (/ 1 3))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: case-sensitive
</span>    (eq? 'a 'A)
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: promises-are-thunks
</span>    (procedure? (<span style="color:#000080;">delay</span> 3))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Do strings made from numbers less than 1 omit the 0?
</span>    (string=? <span style="color:#8b008b;">".5"</span> (number-&gt;string 0.5))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: literal-rationals
</span>    (number? (string-&gt;number <span style="color:#8b008b;">"1/2"</span>))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">AXCH: literal-complexes
</span>    (number? (string-&gt;number <span style="color:#8b008b;">"1+i"</span>))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Is the empty string eqv to itself?
</span>    (eqv? <span style="color:#8b008b;">""</span> <span style="color:#8b008b;">""</span>)
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">How about the empty vector?
</span>    (eqv? '#() '#())
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">A non-empty string?
</span>    (eqv? <span style="color:#8b008b;">"a"</span> <span style="color:#8b008b;">"a"</span>)
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Does SET! have a constant return value?
</span>    (<span style="color:#000080;">let</span> ((x 0)) (eqv? (set! x 1) (set! x 'asd)))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Is it equal to other undefined things?
</span>    (eqv? (<span style="color:#000080;">for-each</span> (<span style="color:#000080;">lambda</span> (x) #t) '(0 1 2)) (<span style="color:#000080;">let</span> ((x 123)) (set! x 321)))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Are negative and positive inexact zero the same?
</span>    (eq? +0.0 -0.0)
    (eqv? +0.0 -0.0)
    (equal? +0.0 -0.0)
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Is the default vector filled with zeroes?
</span>    (equal? (make-vector 5) '#(0 0 0 0 0))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Is the default vector filled with falses?
</span>    (equal? (make-vector 5) '#(#f #f #f #f #f))
    <span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Vector-fill returns a vector?
</span>    (vector? (vector-fill! (make-vector 1) 0))
    ))

<span style="color:#228b22;font-style:italic;">;;</span><span style="color:#228b22;font-style:italic;">
</span><span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">DETECT:KNOWN-SIGNATURES
</span><span style="color:#228b22;font-style:italic;">;;   </span><span style="color:#228b22;font-style:italic;">A precalculated list of signatures for all supported
</span><span style="color:#228b22;font-style:italic;">;;    </span><span style="color:#228b22;font-style:italic;">Scheme implementations.
</span><span style="color:#228b22;font-style:italic;">;;</span><span style="color:#228b22;font-style:italic;">
</span>(<span style="color:#000080;">define</span> <span style="color:#008b8b;">detect:known-signatures</span>
'((mzscheme   (#t #t #t #t #f #f #f #t #t #f #f #f #t #t #f #f #f #t #f #t))
  (chicken    (#f #f #f #f #f #f #f #t #f #f #f #f #t #t #f #t #t #f #f #f))
  (guile      (#f #t #f #t #f #f #f #t #t #t #f #f #t #t #f #f #t #f #f #f))
  (bigloo     (#f #f #f #f #f #t #f #f #f #f #f #f #t #t #f #t #t #f #f #f))
  (gambit     (#t #t #t #t #f #f #t #t #t #f #f #f #t #t #f #f #f #t #f #f))
  (ikarus     (#f #f #f #t #f #t #f #t #f #f #f #f #t #f #f #t #t #t #f #f))
  (scheme48   (#f #f #f #t #t #t #f #t #t #t #t #t #t #t #t #t #t #f #f #f))
  (mit-scheme (#t #t #t #t #t #f #t #t #t #f #t #f #f #f #f #t #t #f #t #f))
  (gauche     (#f #f #f #t #f #f #f #t #t #f #f #f #f #f #f #t #t #f #f #f))))

<span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">DETECT:MATCH-SIGNATURE
</span><span style="color:#228b22;font-style:italic;">;;   </span><span style="color:#228b22;font-style:italic;">Determine the name of the current Scheme implementation
</span><span style="color:#228b22;font-style:italic;">;;    </span><span style="color:#228b22;font-style:italic;">by checking the signature returned by DETECT:SIGNATURE
</span><span style="color:#228b22;font-style:italic;">;;    </span><span style="color:#228b22;font-style:italic;">against a table of known signatures.
</span>(<span style="color:#000080;">define</span> (<span style="color:#008b8b;">detect:match-signature</span>)
  (<span style="color:#000080;">let</span> ((signature (detect:signature)))
    <span style="color:#228b22;font-style:italic;">; </span><span style="color:#228b22;font-style:italic;">Loop over the DETECT:KNOWN-SIGNATURES list
</span>    (<span style="color:#000080;">let</span> <span style="color:#008b8b;">test</span> ((siglist detect:known-signatures))
      (<span style="color:#000080;">if</span> (equal? '() siglist)
        <span style="color:#228b22;font-style:italic;">; </span><span style="color:#228b22;font-style:italic;">Return 'UNKNOWN if we're stumped
</span>        'unknown
        (<span style="color:#000080;">let</span> ((testsig (car siglist)))
          (<span style="color:#000080;">if</span> (equal? (cadr testsig) signature)
            (car testsig)
            (test (cdr siglist))))))))

<span style="color:#228b22;font-style:italic;">;;</span><span style="color:#228b22;font-style:italic;">
</span><span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">DETECT:NAME
</span><span style="color:#228b22;font-style:italic;">;; </span><span style="color:#228b22;font-style:italic;">Memoized form of DETECT:MATCH-SIGNATURE
</span><span style="color:#228b22;font-style:italic;">;;</span><span style="color:#228b22;font-style:italic;">
</span>(<span style="color:#000080;">define</span> <span style="color:#008b8b;">detect:name</span>
  (<span style="color:#000080;">let</span> ((memo #f))
    (<span style="color:#000080;">lambda</span> ()
      (<span style="color:#000080;">and</span> (not memo)
           (set! memo (detect:match-signature)))
      memo)))</pre>
<p>Obviously, only the memoized DETECT:NAME is meant for general use, since a program generally won&#8217;t the see the host changing as it runs, and repeatedly calculating the name would be inefficient.  I don&#8217;t actually have much experience with Scheme, so the DETECT:MATCH-SIGNATURE function could probably be written more efficiently, but it works.</p>
<p>Anyway, I hope that someone finds this to be useful.  I have used it to write the beginnings of a portable process library.  More on that after I get around to polishing it up a bit more.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/191/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=191&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2009/03/14/runtime-scheme-detection/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
		<item>
		<title>Retraction</title>
		<link>http://blog.willdonnelly.net/2009/01/15/retraction/</link>
		<comments>http://blog.willdonnelly.net/2009/01/15/retraction/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 04:45:18 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[chicken]]></category>
		<category><![CDATA[r5rs]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=178</guid>
		<description><![CDATA[It would appear that point #4 of my earlier proposal is entirely unnecessary.   A modifiable load function, like the one found in CHICKEN Scheme, can be implemented as follows:
(define (load path . evalproc)
 (let ((eval (lambda (expr) (eval expr (interaction-environment)))))
   (if (and evalproc             [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=178&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>It would appear that point #4 of my earlier proposal is entirely unnecessary.   A modifiable load function, like the one found in CHICKEN Scheme, can be implemented as follows:</p>
<pre>(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">load</span> path . evalproc)
 (<span style="color:#a020f0;">let</span> ((eval (<span style="color:#a020f0;">lambda</span> (expr) (eval expr (interaction-environment)))))
   (<span style="color:#a020f0;">if</span> (<span style="color:#a020f0;">and</span> evalproc              ;; Do some checks on the procedure
            (list? evalproc)
            (&gt; (length evalproc) 0)
            (procedure? (car evalproc)))
        (set! eval (car evalproc)) ;; True
        #f)                        ;; False
   (<span style="color:#a020f0;">letrec</span> ((eval-datum (<span style="color:#a020f0;">lambda</span> ()
                          (<span style="color:#a020f0;">let</span> ((datum (read)))
                            (<span style="color:#a020f0;">if</span> (eof-object? datum)
                                path
                                (begin
                                  (eval datum)
                                  (eval-datum)))))))
     (with-input-from-file path eval-datum))))</pre>
<p>Some of this code is probably unnecessary, but I felt it better to err on the side of checking too much before using the optional evaluation procedure.  I could also trivially rewrite it to use the more clear DO form, rather than a tail-recursive lambda.  Also, it might be more adviseable to use the standard LOAD function if no special evaluation procedure is given.  I&#8217;m torn on that last one.  Whatever.</p>
<p>But anyway, I see now that I really should have given the matter some deeper thought before immediately writing a lengthy proposal to change fundamental language features.  Over the next few days, I intend to work on a Scheme implementation detection library.  If I am successful, the two most important points of my earlier proposal will have been fulfilled, and I will be content.</p>
<p>It&#8217;s been a learning experience.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/178/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/178/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/178/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/178/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/178/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/178/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/178/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/178/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/178/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/178/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=178&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2009/01/15/retraction/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
		<item>
		<title>Scheme Load Return Values</title>
		<link>http://blog.willdonnelly.net/2009/01/15/scheme-load-return-values/</link>
		<comments>http://blog.willdonnelly.net/2009/01/15/scheme-load-return-values/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 03:21:14 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[bigloo]]></category>
		<category><![CDATA[chicken]]></category>
		<category><![CDATA[gambit]]></category>
		<category><![CDATA[guile]]></category>
		<category><![CDATA[mit-scheme]]></category>
		<category><![CDATA[mzscheme]]></category>
		<category><![CDATA[stklos]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=172</guid>
		<description><![CDATA[Shortly after finishing my previous post, I began to wonder if maybe some of the features I had requested were available already.  I was pleasantly surprised.
Implementations tested were:

MzScheme
Bigloo
Guile
Chicken
Gambit
MIT Scheme
STklos

Bad news first.  In my hour or so of testing, I was unable to find any way to directly return values from a loaded file in Guile, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=172&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Shortly after finishing my previous post, I began to wonder if maybe some of the features I had requested were available already.  I was pleasantly surprised.</p>
<p>Implementations tested were:</p>
<ul>
<li><a href="http://www.plt-scheme.org/software/mzscheme/">MzScheme</a></li>
<li><a href="http://www-sop.inria.fr/mimosa/fp/Bigloo/">Bigloo</a></li>
<li><a href="http://www.gnu.org/software/guile/guile.html">Guile</a></li>
<li><a href="http://www.call-with-current-continuation.org/">Chicken</a></li>
<li><a href="http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Main_Page">Gambit</a></li>
<li><a href="http://groups.csail.mit.edu/mac/projects/scheme/">MIT Scheme</a></li>
<li><a href="http://www.stklos.net/">STklos</a></li>
</ul>
<p>Bad news first.  In my hour or so of testing, I was unable to find any way to directly return values from a loaded file in Guile, Gambit, and STklos.</p>
<p>On the other hand, that means that four of the seven implementations that I tested <strong>could</strong> return values.</p>
<p>MzScheme and MIT Scheme both return the last form, whatever it was.  If the last form was a DEFINE statement, MzScheme returns nothing, and MIT Scheme returns the identifier that was defined.</p>
<p>Bigloo doesn&#8217;t seem to return anything usable, but it does <strong>print</strong> the results of intermediate evaluations, and claims to return the result of the last evaluation.  This may indeed be true, but in my testing I was unable to get it to return anything other than the path of the just-loaded file.</p>
<p>Chicken, however, was an unqualified success.  Although it is true that at first it returns nothing from its LOAD function, it provides a brilliant little mechanism to fix that.  The LOAD function, in addition to taking a filename, will also take an optional argument called EVALPROC, which is called repeatedly with each form from the loaded file.  This fact, combined with a little closure magic, ends us up with this:</p>
<pre>(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">load-return</span> file)
  (<span style="color:#a020f0;">let</span> ((return '()))
    (<span style="color:#a020f0;">load</span> file
	  (<span style="color:#a020f0;">lambda</span> (exp)
	    (<span style="color:#a020f0;">if</span> (<span style="color:#a020f0;">and</span> (<span style="color:#a020f0;">list?</span> exp) (<span style="color:#a020f0;">eqv?</span> (<span style="color:#a020f0;">list-ref</span> exp 0) 'define))
	        (<span style="color:#a020f0;">begin</span>
		  (<span style="color:#a020f0;">eval</span> exp)
		  (<span style="color:#a020f0;">set!</span> return (<span style="color:#a020f0;">cons</span> (<span style="color:#a020f0;">list-ref</span> exp 1) return)))
                (<span style="color:#a020f0;">set!</span> return (<span style="color:#a020f0;">cons</span> (<span style="color:#a020f0;">eval</span> exp) return)))))
    (<span style="color:#a020f0;">reverse</span> return)))</pre>
<p>This function calls the LOAD function, but passes it its own evaluation procedure, which will assemble a list of values when called, as well as evaluating each expression.</p>
<p>After seeing the beautiful and elegant way in which Chicken Scheme allows the user to dynamically alter the behaviour of the LOAD function at runtime, I feel like I should alter my recommendation for modifying that behaviour.  Chicken has, I believe, found the best possible way to implement such functionality: have a reasonable default, but allow people to override it if they wish.  Simple, elegant, and powerful: exactly like the language itself.  Bravo, Chicken.</p>
<p>Bravo.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/172/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=172&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2009/01/15/scheme-load-return-values/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
		<item>
		<title>A Foreign Function Interface for Ikarus Using SoLoad</title>
		<link>http://blog.willdonnelly.net/2008/12/14/a-foreign-function-interface-for-ikarus-using-soload/</link>
		<comments>http://blog.willdonnelly.net/2008/12/14/a-foreign-function-interface-for-ikarus-using-soload/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 06:21:56 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[scheme]]></category>
		<category><![CDATA[soload]]></category>
		<category><![CDATA[ffi]]></category>
		<category><![CDATA[ikarus]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=117</guid>
		<description><![CDATA[A while back I wrote a foreign function server called SoLoad.  It is intended for situations where a regular FFI, for whatever reason, is not available to you, but the permissions necessary to run and communicate with programs are available.
Once this was in place, I proceeded to write some code to take advantage of my [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=117&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>A while back I wrote a foreign function <a href="http://willdonnelly.wordpress.com/2008/08/30/the-soload-foreign-function-server-part-i-an-introduction/">server</a> <a href="http://willdonnelly.wordpress.com/2008/09/12/the-soload-foreign-function-server-part-ii-basic-usage/">called</a> <a href="http://willdonnelly.wordpress.com/2008/09/15/the-soload-foreign-function-server-part-iii-intermediate-usage/">SoLoad</a>.  It is intended for situations where a regular FFI, for whatever reason, is not available to you, but the permissions necessary to run and communicate with programs are available.</p>
<p>Once this was in place, I proceeded to write some code to take advantage of my program, and provide rudimentary C function capabilities to the Ikarus scheme implementation.  I got most of the code done, implementing portable type conversion functions, an implementation-independent interface to encapsulate the initialization and communication code, and all the little macros necessary to make the FFI easy to use.  It had its bugs, but it worked pretty well.  Well enough, at least, to create a window using SDL, and then close it again.</p>
<p>And then I just sort of forgot.  Somehow, after getting it all to work and provide a basic level of C library integration to Ikarus, I just wandered off and allowed myself to get involved in other projects.</p>
<p>Today, I was looking through my projects folder, and happened to notice the code I had previously forgotten.  Working under the assumption that someone could probably find a use for it, I decided that I would clean it up and post it online.</p>
<p>It required considerably less cleaning that I had expected.</p>
<h2>Basic Structure of the Scheme-&gt;SoLoad Link</h2>
<p>A major design goal in this project was designing it in a way that would allow it to be easily ported to a variety of Scheme implementations and communication channels.  The design I ultimately settled on was as follows:</p>
<p>There is one function, SOLOAD-INIT, which handles essentially all of the necessary setup, communication, and teardown code associated with using SoLoad.  When called, it is passed the path to the SoLoad executable, and calls it.  It then returns a pair, whose CAR is a function to send data to SoLoad and return whatever data SoLoad sends back, and whose CDR is a function that will tell SoLoad to exit and perform any other teardown functions that may be necessary.</p>
<p>Its implementation for Ikarus looks like this:</p>
<pre>(import (ikarus))
<span style="color:#b22222;">;;;</span><span style="color:#b22222;">
</span><span style="color:#b22222;">;;; </span><span style="color:#b22222;">soload-init
</span><span style="color:#b22222;">;;;   </span><span style="color:#b22222;">Starts an instance of SoLoad
</span><span style="color:#b22222;">;;;   </span><span style="color:#b22222;">Returns a cons cell containing two functions:
</span><span style="color:#b22222;">;;;     </span><span style="color:#b22222;">car: Send a command to SoLoad, return the output.
</span><span style="color:#b22222;">;;;     </span><span style="color:#b22222;">cdr: Kill SoLoad and close all sockets.
</span><span style="color:#b22222;">;;;</span>
(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-init</span> soload-path)
  <span style="color:#b22222;">;; </span><span style="color:#b22222;">Start SoLoad, and bind its input, output, and error ports.
</span>  (let-values ([(pid ip op errp)
                (process soload-path <span style="color:#bc8f8f;">"stdin"</span>)])
    <span style="color:#b22222;">;; </span><span style="color:#b22222;">Transcode the ports we'll be using.
</span>    (<span style="color:#a020f0;">let</span> ([soload-in  (transcoded-port op (native-transcoder))]
          [soload-out (transcoded-port ip (native-transcoder))])
      (cons
       <span style="color:#b22222;">;; </span><span style="color:#b22222;">Send commands to SoLoad
</span>       (<span style="color:#a020f0;">lambda</span> (command)
         (unless (port-closed? soload-out)       <span style="color:#b22222;">; </span><span style="color:#b22222;">Make sure it's open
</span>                 (put-string soload-out command) <span style="color:#b22222;">; </span><span style="color:#b22222;">Send the command
</span>                 (newline soload-out)            <span style="color:#b22222;">; </span><span style="color:#b22222;">Newline
</span>                 (flush-output-port soload-out)) <span style="color:#b22222;">; </span><span style="color:#b22222;">Flush the port
</span>         (unless (port-closed? soload-in)        <span style="color:#b22222;">; </span><span style="color:#b22222;">Make sure it's open
</span>                 (get-line soload-in)))          <span style="color:#b22222;">; </span><span style="color:#b22222;">Get the output
</span>       <span style="color:#b22222;">;; </span><span style="color:#b22222;">Kill SoLoad and close the ports
</span>       (<span style="color:#a020f0;">lambda</span> ()
         (unless (port-closed? soload-out)       <span style="color:#b22222;">; </span><span style="color:#b22222;">Make sure it's open
</span>                 (put-string soload-out <span style="color:#bc8f8f;">"exit\n"</span>)<span style="color:#b22222;">; </span><span style="color:#b22222;">Tell it to close
</span>                 (flush-output-port soload-out)  <span style="color:#b22222;">; </span><span style="color:#b22222;">Flush output
</span>                 (close-port soload-out))        <span style="color:#b22222;">; </span><span style="color:#b22222;">Close the port
</span>         (unless (port-closed? soload-in)        <span style="color:#b22222;">; </span><span style="color:#b22222;">Make sure it's open
</span>                 (close-port soload-in))         <span style="color:#b22222;">; </span><span style="color:#b22222;">Close the port
</span>         (unless (port-closed? errp)             <span style="color:#b22222;">; </span><span style="color:#b22222;">Make sure it's open
</span>                 (close-port errp)))))))         <span style="color:#b22222;">; </span><span style="color:#b22222;">Close the port</span></pre>
<p>And that concludes the implementation-dependent portion of the interface.  All of the code above this level is (hopefully) completely independent of whatever particular Scheme it is running on.</p>
<h2>Type Conversion</h2>
<p>The next important part of the Ikarus/SoLoad FFI is the conversion between Scheme native types, and their text-based representation.</p>
<p>This consists of a myriad of small little functions, to escape/unescape strings, convert numbers, and flatten lists into a single string.  They are each easy to implement, and should be entirely portable Scheme code.</p>
<p>All together, they run a little long, but I may as well post them here as well:</p>
<pre><span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">soload-escape
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">Escape text so SoLoad will read it properly.
</span><span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span>(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-escape</span> text)
  (string-append <span style="color:#bc8f8f;">"\""</span> text <span style="color:#bc8f8f;">"\""</span>))

<span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">soload-unescape
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">Remove the escaping from text that SoLoad returns.
</span><span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span>(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-unescape</span> text)
  (list-&gt;string
   (reverse
    (cdr
     (reverse
      (cdr
       (string-&gt;list text))))))) <span style="color:#b22222;">; </span><span style="color:#b22222;">Remove quotation marks
</span>
<span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">native-&gt;soload
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">Converts a native type to a
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">string representation that can
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">be passed to SoLoad.
</span><span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span>(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">native-&gt;soload</span> type value)
  (<span style="color:#a020f0;">case</span> type
    [(int float double long short
          uint8 sint8 uint16 sint16
          uint32 sint32 uint64 sint64
          ushort sshort uint sint
          ulong slong char uchar
          schar) (number-&gt;string value)]
    [(string char*)  (soload-escape value)]
    [(pointer void*) value]
    [(void) <span style="color:#bc8f8f;">""</span>]
    [else <span style="color:#bc8f8f;">"0"</span>]))

<span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">soload-&gt;native
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">Converts a SoLoad string
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">into a native type.
</span><span style="color:#b22222;">;;</span><span style="color:#b22222;">
</span>(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-&gt;native</span> type value)
  (<span style="color:#a020f0;">case</span> type
    [(int float double long short
          uint8 sint8 uint16 sint16
          uint32 sint32 uint64 sint64
          ushort sshort uint sint
          ulong slong char uchar
          schar) (string-&gt;number value)]
    [(string char*)  (soload-unescape value)]
    [(pointer void*) value]
    [(void) #t]
    [else #f]))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">list:native-&gt;soload</span> types values)
  (<span style="color:#a020f0;">if</span> (&gt; (length types) 0)
      (cons
       (native-&gt;soload (car types) (car values))
       (list:native-&gt;soload (cdr types) (cdr values)))
      '()))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">list:soload-&gt;native</span> types values)
  (<span style="color:#a020f0;">if</span> (&gt; (length types) 0)
      (cons
       (soload-&gt;native (car types) (car values))
       (list:soload-&gt;native (cdr types) (cdr values)))
      '()))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-flatten</span> strings)
  (apply string-append
         (<span style="color:#a020f0;">map</span>
          (<span style="color:#a020f0;">lambda</span> (element) (string-append <span style="color:#bc8f8f;">" "</span> element))
          strings)))</pre>
<h2>Wrapping It All Up</h2>
<p>These functions technically provide all the functionality required to use SoLoad from within Ikarus, but they lack a little something.  What they need now is to be made easy.  It should be possible to declare a function such that it just works from anywhere in your program, with no need to know that it&#8217;s calling a helper behind the scenes.</p>
<p>This is possibly the most involved portion of the interface, because it requires individually wrapping every function of SoLoad, and then adding a few macros to neaten things up.  In the end, though, I think it works out well:</p>
<pre>(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">soload-process</span> #f)
(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">soload-path</span> <span style="color:#bc8f8f;">"soload"</span>)

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-set-path</span> path)
  (set! soload-path path))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-send</span> command)
  (<span style="color:#a020f0;">if</span> (equal? soload-process #f)
      (set! soload-process (soload-init soload-path)))
  ((car soload-process) command))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-kill</span>)
  (<span style="color:#a020f0;">if</span> (not (equal? soload-process #f))
      (<span style="color:#a020f0;">begin</span>
        ((cdr soload-process))
        (set! soload-process #f))))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-library</span> path)
  (soload-send (string-append <span style="color:#bc8f8f;">"open "</span> path)))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-fn-load</span> library name rtype atypes)
  (soload-send
   (string-append
    <span style="color:#bc8f8f;">"load "</span> library <span style="color:#bc8f8f;">" "</span> name <span style="color:#bc8f8f;">" "</span>
    (symbol-&gt;string rtype) <span style="color:#bc8f8f;">" "</span>
    (number-&gt;string (length atypes))
    (soload-flatten (<span style="color:#a020f0;">map</span> symbol-&gt;string atypes)))))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-fn-call</span> function rtype atypes args)
  (soload-&gt;native rtype
   (soload-send
    (string-append
     <span style="color:#bc8f8f;">"call "</span> function
     (soload-flatten
      (list:native-&gt;soload atypes args))))))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-import</span> definitions)
  (soload-send (string-append <span style="color:#bc8f8f;">"def "</span> definitions)))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-type-define</span> name . types)
  (soload-send
   (string-append <span style="color:#bc8f8f;">"type "</span> name <span style="color:#bc8f8f;">" "</span>
                  (number-&gt;string (length types))
                  (soload-flatten (<span style="color:#a020f0;">map</span> symbol-&gt;string types)))))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-type-create</span> name . args)
  (soload-send
   (string-append <span style="color:#bc8f8f;">"new "</span> name <span style="color:#bc8f8f;">" "</span>
                  (soload-flatten (list:native-&gt;soload types args)))))

(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">soload-delete</span> name pointer)
  (soload-send (string-append <span style="color:#bc8f8f;">"delete "</span> name <span style="color:#bc8f8f;">" "</span> pointer)))

(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">soload-function</span>
  (<span style="color:#a020f0;">syntax-rules</span> ()
    ((_ library name (atypes ...) rtype)
     (<span style="color:#a020f0;">let</span> ([function (soload-fn-load library name
                                     'rtype '(atypes ...))])
       (<span style="color:#a020f0;">lambda</span> arguments
         (soload-fn-call function 'rtype
                         '(atypes ...) arguments))))
    ((_ library name (atypes ...))
     (soload-function library name (atypes ...) void))
    ((_ library name rtype)
     (soload-function library name () rtype))
    ((_ library name)
     (soload-function library name () void))))

<span style="color:#b22222;">;; </span><span style="color:#b22222;">Warning! SOLOAD-TYPE does not delete the stuff
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">that it creates.  It will stick around till
</span><span style="color:#b22222;">;;   </span><span style="color:#b22222;">SoLoad is closed.
</span>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">soload-type</span>
  (<span style="color:#a020f0;">syntax-rules</span> ()
    ((_ name types ...)
     (<span style="color:#a020f0;">let</span> ([type (soload-type-define name types ...)])
       (<span style="color:#a020f0;">lambda</span> arguments
         (soload-send
          (string-append
           <span style="color:#bc8f8f;">"new "</span> name <span style="color:#bc8f8f;">" "</span>
           (soload-flatten
            (list:native-&gt;soload '(types ...) arguments)))))))))</pre>
<h2>Using It</h2>
<p>Along with a working executable of SoLoad, this code should be all that is needed to use C libraries from within Ikarus.  I tested it roughly 5 minutes ago, so I&#8217;m fairly certain it works.  A working example, assuming all the previous code is in a file called &#8220;ikarus-soload.ss&#8221;, with the soload executable (or a symlink) in the same directory, is as follows:</p>
<pre>(load <span style="color:#bc8f8f;">"ikarus-soload.ss"</span>)

(soload-set-path <span style="color:#bc8f8f;">"./soload"</span>)

<span style="color:#b22222;">;;;</span><span style="color:#b22222;">
</span><span style="color:#b22222;">;;; </span><span style="color:#b22222;">Math Check
</span><span style="color:#b22222;">;;;   </span><span style="color:#b22222;">Test the value of sin for progressively closer values of pi.
</span><span style="color:#b22222;">;;;   </span><span style="color:#b22222;">Should return numbers moving closer to 0
</span><span style="color:#b22222;">;;;</span><span style="color:#b22222;">
</span>
<span style="color:#b22222;">;; </span><span style="color:#b22222;">Import the library
</span>(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">libm</span> (soload-library <span style="color:#bc8f8f;">"/lib/libm.so.6"</span>))
<span style="color:#b22222;">;; </span><span style="color:#b22222;">Import the function
</span>(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">s-sin</span> (soload-function libm <span style="color:#bc8f8f;">"sin"</span> (double) double))
<span style="color:#b22222;">;; </span><span style="color:#b22222;">Do some tests
</span>(newline)
(pretty-print (s-sin 3))
(pretty-print (s-sin 3.1))
(pretty-print (s-sin 3.14))
(pretty-print (s-sin 3.141))

<span style="color:#b22222;">;;;</span><span style="color:#b22222;">
</span><span style="color:#b22222;">;;; </span><span style="color:#b22222;">SDL Test
</span><span style="color:#b22222;">;;;   </span><span style="color:#b22222;">Load SDL, create a window, then quit
</span><span style="color:#b22222;">;;;</span><span style="color:#b22222;">
</span>
<span style="color:#b22222;">;; </span><span style="color:#b22222;">Load the library
</span>(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">lib-sdl</span>
  (soload-library <span style="color:#bc8f8f;">"/usr/lib/libSDL.so"</span>))
<span style="color:#b22222;">;; </span><span style="color:#b22222;">Load a bunch of functions
</span>(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">sdl-init</span>
  (soload-function lib-sdl <span style="color:#bc8f8f;">"SDL_Init"</span> (uint32) int))
(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">sdl-quit</span>
  (soload-function lib-sdl <span style="color:#bc8f8f;">"SDL_Quit"</span>))
(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">sdl-set-video-mode</span>
  (soload-function lib-sdl <span style="color:#bc8f8f;">"SDL_SetVideoMode"</span> (int int int uint32) pointer))
(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">sdl-fill-rect</span>
  (soload-function lib-sdl <span style="color:#bc8f8f;">"SDL_FillRect"</span> (pointer pointer uint32) int))
(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">sdl-flip</span>
  (soload-function lib-sdl <span style="color:#bc8f8f;">"SDL_Flip"</span> (pointer) int))
(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">sdl-map-rgb</span>
  (soload-function lib-sdl <span style="color:#bc8f8f;">"SDL_MapRGB"</span> (pointer uint8 uint8 uint8) uint32))
<span style="color:#b22222;">;; </span><span style="color:#b22222;">Declare a type
</span>(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">SDL_Rect*</span>
  (soload-type <span style="color:#bc8f8f;">"SDL_Rect"</span> 'sint16 'sint16 'uint16 'uint16))

(sdl-init 0)
(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">sdl-surface</span> (sdl-set-video-mode 640 480 16 0))
(sdl-fill-rect sdl-surface (SDL_Rect* 0 0 640 480) 32535)
(sdl-flip sdl-surface)

(sdl-quit)
(soload-kill)</pre>
<p>Now that I&#8217;ve taken a break from this for a while, I can see a few areas it could be made more robust.  Next feature: an optional timeout period for SoLoad, so it can close gracefully even if the caller has crashed.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/117/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=117&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2008/12/14/a-foreign-function-interface-for-ikarus-using-soload/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
		<item>
		<title>A Scheme Syntax-Rules Primer</title>
		<link>http://blog.willdonnelly.net/2008/09/04/a-scheme-syntax-rules-primer/</link>
		<comments>http://blog.willdonnelly.net/2008/09/04/a-scheme-syntax-rules-primer/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 02:34:48 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[scheme]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[macros]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=24</guid>
		<description><![CDATA[Scheme has a wonderfully powerful hygienic macro system.  Unfortunately, explanations on how to use it are few and far between.  R5RS is utterly incomprehensible to anyone who doesn&#8217;t already have a firm grounding in hygienic macro systems, and TYSiFD&#8217;s section on macros dates from a time before syntax-rules and hygiene.
So this here is my attempt [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=24&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Scheme has a wonderfully powerful hygienic macro system.  Unfortunately, explanations on how to use it are few and far between.  <a title="Revised^5 Report on the Algorithmic Languge Scheme" href="http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_sec_4.3">R5RS </a>is utterly incomprehensible to anyone who doesn&#8217;t already have a firm grounding in hygienic macro systems, and <a title="Teach Yourself Scheme in Fixnum Days" href="http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-10.html#node_chap_8">TYSiFD</a>&#8217;s section on macros dates from a time before syntax-rules and hygiene.</p>
<p>So this here is my attempt to share what I&#8217;ve learned over the past few days with regards to syntax-rules macros.  Bear in mind that at the time of writing this, I have known how to use syntax-rules since <strong>yesterday</strong>, but my knowledge seems to be complete enough to write a working module system, so here&#8217;s my attempt to pass on what I&#8217;ve learned.</p>
<p>First things first.  You use define-syntax to create a top level binding, and let-syntax bears the same relationship to define-syntax as you&#8217;d expect.</p>
<pre><span style="color:#b22222;">;; </span><span style="color:#b22222;">define-syntax is used to create
</span><span style="color:#b22222;">;;  </span><span style="color:#b22222;">a top-level binding of a macro
</span>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">macro</span>
  &lt;syntax transformer&gt;)</pre>
<p>That much is pretty clear from reading R5RS, now we need to figure out how to write the syntax transformer.  There are a few ways to do this, but the best way for beginners is to use syntax-rules, which avoids inadvertent variable capture and other such nasties automatically, and uses a rather elegant pattern matching language.</p>
<p>We&#8217;ll start by trying to write a simple macro, <code>while</code>. This will just be a standard looping construct that keeps executing over and over until its condition becomes false.  We want its usage to look something like this:</p>
<pre><span style="color:#b22222;">;; </span><span style="color:#b22222;">A simple while loop
</span>(<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">x</span> 0)
(<span style="color:#a020f0;">while</span> (&lt; x 5)
  (set! x (+ x 1))
  (print x))</pre>
<p>So first, we need the <code>define-syntax</code> form.</p>
<pre>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">while</span>
  &lt;syntax transformer&gt;)</pre>
<p>Next, we need to write the syntax transformer itself.  This is where syntax-rules comes into play.  Syntax-rules uses pattern matching and text substitution to allow you to make some pretty advanced macros.  It looks like:</p>
<pre>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">while</span>
  (<span style="color:#a020f0;">syntax-rules</span> (<span style="color:#228b22;">&lt;keywords&gt;</span>)
    ((<span style="color:#228b22;">&lt;pattern&gt;</span>) <span style="color:#228b22;">&lt;template&gt;</span>)
    ...
    ((<span style="color:#228b22;">&lt;pattern&gt;</span>) <span style="color:#228b22;">&lt;template&gt;</span>)))</pre>
<p>I will explain keywords later.  For now, just leave that bit blank.  What we&#8217;re interested in are those ((<span style="color:#228b22;">&lt;pattern&gt;</span>) <span style="color:#228b22;">&lt;template&gt;) </span>pairs.  Each <span style="color:#228b22;">&lt;pattern&gt;</span> is just that, a pattern of code that will be matched.  In our case, we want to match the pattern:</p>
<pre>(while condition body ...)</pre>
<p>Where the &#8216;&#8230;&#8217; signifies that <code>body</code> may contain one or more forms.  Luckily for us, this is exactly the syntax that syntax-rules wants to see, so we can just plug it in, giving us:</p>
<pre>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">while</span>
  (<span style="color:#a020f0;">syntax-rules</span> ()
    ((while condition body ...) <span style="color:#228b22;">&lt;template&gt;</span>)))</pre>
<p>So far so good.  Now we just have to fill in the other half, with a suitable <span><span style="color:#228b22;">&lt;template&gt;</span></span>.</p>
<p>Before we can write the <span><span style="color:#228b22;">&lt;template&gt;</span></span>, though, we have to decide what we want the code to end up looking like.  Since this isn&#8217;t a guide to scheme code in general, I&#8217;ll just go ahead and say that we want the output to look like:</p>
<pre><span style="color:#b22222;">; </span><span style="color:#b22222;">Thanks to Alex Shinn for pointing out a mistake
</span>(<span style="color:#a020f0;">let</span> loop ()
  (<span style="color:#a020f0;">if</span> condition
      (<span style="color:#a020f0;">begin</span>
        body ...
        (loop))
      #f))</pre>
<p>Got that?  Okay, now we&#8217;ve just got to put this in our syntax-rules macro as a template.  By another startling coincidence, this is exactly what the template code is expected to look like.  We just plug in that code, and our final result is:</p>
<pre>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">while</span>
  (<span style="color:#a020f0;">syntax-rules</span> ()
    ((while condition body ...)
     (<span style="color:#a020f0;">let</span> loop ()
       (<span style="color:#a020f0;">if</span> condition
           (<span style="color:#a020f0;">begin</span>
             body ...
             (loop))
           #f)))))</pre>
<p>Just plug that into your scheme interpreter, and our <code>while</code> loop from earlier should execute perfectly.</p>
<p>Now let&#8217;s try to write something a little more complicated.  We want to write a <code>for</code> loop similar to the one that Python has.  This should be a pretty easy task, since it&#8217;s basically just syntactic sugar for scheme&#8217;s <code>map</code> function.</p>
<p>Our goal is to be able to write a piece of code taking the form:</p>
<pre>(<span style="color:#a020f0;">for</span> <span style="color:#228b22;">&lt;element&gt;</span> <span style="color:#a020f0;">in</span> <span style="color:#228b22;">&lt;list&gt;</span>
     <span style="color:#228b22;">&lt;body ...&gt;</span>)</pre>
<p>And have it expand to:</p>
<pre><span style="color:#b22222;">; </span><span style="color:#b22222;">Thanks to Alex Shinn for pointing out a mistake</span>
(<span style="color:#a020f0;">for-each</span> (<span style="color:#a020f0;">lambda</span> (<span style="color:#228b22;">&lt;element&gt;</span>)
       <span style="color:#228b22;">&lt;body ...&gt;</span>) <span style="color:#228b22;">&lt;list&gt;</span>)</pre>
<p>Our first try would probably look something like this:</p>
<pre>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">for</span>
  (<span style="color:#a020f0;">syntax-rules</span> ()
    ((for element in list body ...)
     (<span style="color:#a020f0;">map</span> (<span style="color:#a020f0;">lambda</span> (element)
            body ...)
          list))))</pre>
<p>This works, but there&#8217;s one issue with it.  All of the following are valid and work exactly the same:</p>
<pre>(for i in '(0 1 2 3 4) (print i))
(for i fnord '(0 1 2 3 4) (print i))
(for i some-other-keyword '(0 1 2 3 4) (print i))</pre>
<p>This is not so much of a problem in the case of a for loop, but what if you wanted to add another rule later, so that</p>
<pre>(for '(0 1 2 3 4) as i
     (print i))</pre>
<p>will also work?  The solution to this problem is in that <span style="color:#228b22;">&lt;keywords&gt; </span>argument that we glossed over earlier.  Change the keywords list to include &#8216;in&#8217; (and, for good measure, &#8216;as&#8217;), and it will allow those symbols, and only those symbols, in places where they are mentioned.  This change leaves us with:</p>
<pre>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">for</span>
  (<span style="color:#a020f0;">syntax-rules</span> (in as)
    ((for element in list body ...)
     (<span style="color:#a020f0;">map</span> (<span style="color:#a020f0;">lambda</span> (element)
            body ...)
          list))
    ((for list as element body ...)
     (<span style="color:#a020f0;">map</span> (<span style="color:#a020f0;">lambda</span> (element)
            body ...)
          list))</pre>
<p>Or, for simplicity (thanks to Dan Prager for pointing this out)</p>
<pre>(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">for</span>
  (<span style="color:#a020f0;">syntax-rules</span> (in as)
    ((for element in list body ...)
     (<span style="color:#a020f0;">map</span> (<span style="color:#a020f0;">lambda</span> (element)
            body ...)
          list))
    ((for list as element body ...)
     (for element in list body ...))))</pre>
<p>And if we load this code into our scheme interpreter of choice, we should have two fully functional little bits of new syntax.</p>
<p>Hopefully this guide will help shed some light on the arcane subject that is the Scheme macro system, and hopefully I will never have to learn enough about syntax-case to write a tutorial on it.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/willdonnelly.wordpress.com/24/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/willdonnelly.wordpress.com/24/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/24/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=24&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2008/09/04/a-scheme-syntax-rules-primer/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
		<item>
		<title>A Minimalistic Module System for Scheme</title>
		<link>http://blog.willdonnelly.net/2008/08/30/a-minimalistic-module-system-for-scheme/</link>
		<comments>http://blog.willdonnelly.net/2008/08/30/a-minimalistic-module-system-for-scheme/#comments</comments>
		<pubDate>Sun, 31 Aug 2008 01:59:58 +0000</pubDate>
		<dc:creator>Will Donnelly</dc:creator>
				<category><![CDATA[scheme]]></category>
		<category><![CDATA[lisp]]></category>

		<guid isPermaLink="false">http://willdonnelly.wordpress.com/?p=4</guid>
		<description><![CDATA[I like scheme.
I really, really like scheme.
Unfortunately, it seems like a lot of the time the only way to get worthwhile things done in scheme is to abandon the conceptual purity and the elegance, all of the things that make scheme as wonderful as it is.
I figure I&#8217;m as good a person as any to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=4&subd=willdonnelly&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I like <a title="scheme" href="http://en.wikipedia.org/wiki/Scheme_(programming_language)">scheme</a>.</p>
<p>I really, really like scheme.</p>
<p>Unfortunately, it seems like a lot of the time the only way to get worthwhile things done in scheme is to abandon the conceptual purity and the elegance, all of the things that make scheme as wonderful as it is.</p>
<p>I figure I&#8217;m as good a person as any to try and fix at least a little of that.</p>
<p>The first (second actually, but more about that in the next post) step toward that is some sort of cross-implementation module system.  As far as I know, the only such systems in existence so far are <a title="SLIB" href="http://people.csail.mit.edu/jaffer/SLIB.html">SLIB</a> and <a title="Snowfort" href="http://snow.iro.umontreal.ca/">Snowfort</a>.  While both of these are wonderful systems, they overshoot the mark, in my opinion.  SLIB aims to be a complete all-singing all-dancing library system, and Snowfort integrates all kinds of package management with the simple act of breaking a program up into modules.</p>
<p>Well, that&#8217;s the beauty of lisp, isn&#8217;t it?  If you need something, you can just code it yourself.</p>
<p>So I did.  The preliminary result is only 19 lines of code, 6 of which are simply a function to build an alist from a key list and a value list.  It can also double as a simple object system if you want to use it that way.</p>
<p>Its usage is simple.  There are two macros, provide and module. Provide is basically the same as module, but anonymous, so it needs no documentation other than to say that you omit the name.</p>
<pre><span style="color:#b22222;">;;; </span><span style="color:#b22222;">simple-module-example.scm
</span><span style="color:#b22222;">;;; </span><span style="color:#b22222;">Show off the usage of simple-module.scm
</span><span style="color:#b22222;">;;; </span><span style="color:#b22222;">By Will Donnelly
</span>
<span style="color:#b22222;">;; </span><span style="color:#b22222;">This program is free software. It comes without any warranty, to
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">the extent permitted by applicable law. You can redistribute it
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">and/or modify it under the terms of the Do What The Fuck You Want
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">To Public License, Version 2, as published by Sam Hocevar. See
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">http://sam.zoy.org/wtfpl/COPYING for more details.
</span>
(load <span style="color:#bc8f8f;">"simple-module.scm"</span>)

<span style="color:#b22222;">;; </span><span style="color:#b22222;">(module &lt;name&gt; (&lt;exports&gt; ...) &lt;body&gt; ...)
</span>(<span style="color:#a020f0;">module</span> <span style="color:#228b22;">mod-name</span> (foo incr)
  (<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">foo</span> 37)
  (<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">i</span> 10)       <span style="color:#b22222;">; </span><span style="color:#b22222;">i cannot be accessed directly
</span>  (<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">incr</span>)
    (set! i (+ i 1))
    i))
(mod-name 'foo) <span style="color:#b22222;">; </span><span style="color:#b22222;">=&gt; 37
</span>((mod-name 'incr)) <span style="color:#b22222;">; </span><span style="color:#b22222;">=&gt; 11
</span>((mod-name 'incr)) <span style="color:#b22222;">; </span><span style="color:#b22222;">=&gt; 12
</span>((mod-name 'incr)) <span style="color:#b22222;">; </span><span style="color:#b22222;">=&gt; 13</span></pre>
<p>That&#8217;s all you have to do to use it.  The code inside the module system is about as simple as that too.</p>
<pre><span style="color:#b22222;">;;; </span><span style="color:#b22222;">simple-module.scm
</span><span style="color:#b22222;">;;; </span><span style="color:#b22222;">A minimalistic module system for scheme
</span><span style="color:#b22222;">;;; </span><span style="color:#b22222;">By Will Donnelly
</span>
<span style="color:#b22222;">;; </span><span style="color:#b22222;">This program is free software. It comes without any warranty, to
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">the extent permitted by applicable law. You can redistribute it
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">and/or modify it under the terms of the Do What The Fuck You Want
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">To Public License, Version 2, as published by Sam Hocevar. See
</span><span style="color:#b22222;">;; </span><span style="color:#b22222;">http://sam.zoy.org/wtfpl/COPYING for more details.
</span>
(<span style="color:#a020f0;">define</span> (<span style="color:#0000ff;">make-alist</span> names values)
  (<span style="color:#a020f0;">if</span> (equal? (length names) (length values))
      (<span style="color:#a020f0;">if</span> (&gt; (length names) 0)
          (cons (cons (car names) (car values)) (make-alist (cdr names) (cdr values)))
          '())
      #f))

(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">provide</span>
  (<span style="color:#a020f0;">syntax-rules</span> ()
    ((_ (exports ...) body ...)
     ((<span style="color:#a020f0;">lambda</span> ()
        body ...
        (<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">export-alist</span>
          (make-alist '(exports ...) (list exports ...)))
        (<span style="color:#a020f0;">lambda</span> (symbol)
          (cdr (<span style="color:#a020f0;">or</span> (assoc symbol export-alist) '(#f . #f)))))))))

(<span style="color:#a020f0;">define-syntax</span> <span style="color:#b8860b;">module</span>
  (<span style="color:#a020f0;">syntax-rules</span> ()
    ((_ name (exports ...) body ...)
     (<span style="color:#a020f0;">define</span> <span style="color:#0000ff;">name</span> (<span style="color:#a020f0;">provide</span> (exports ...) body ...)))))</pre>
<p>Just load that code into your scheme interpreter, and you have a simple module system.  That&#8217;s all there is to it.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/willdonnelly.wordpress.com/4/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/willdonnelly.wordpress.com/4/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/willdonnelly.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/willdonnelly.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/willdonnelly.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/willdonnelly.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/willdonnelly.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/willdonnelly.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/willdonnelly.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/willdonnelly.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/willdonnelly.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/willdonnelly.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.willdonnelly.net&blog=4676114&post=4&subd=willdonnelly&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://blog.willdonnelly.net/2008/08/30/a-minimalistic-module-system-for-scheme/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7a273a4628e287a480462eb09844efeb?s=96&#38;d=identicon" medium="image">
			<media:title type="html">Will Donnelly</media:title>
		</media:content>
	</item>
	</channel>
</rss>