<?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>The Blogmatic Programmer</title>
	<atom:link href="http://anthonyf.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://anthonyf.wordpress.com</link>
	<description>Just another Wordpress.com weblog</description>
	<lastBuildDate>Fri, 30 Dec 2011 05:04:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='anthonyf.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The Blogmatic Programmer</title>
		<link>http://anthonyf.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://anthonyf.wordpress.com/osd.xml" title="The Blogmatic Programmer" />
	<atom:link rel='hub' href='http://anthonyf.wordpress.com/?pushpress=hub'/>
		<item>
		<title>A month of work on Lunula</title>
		<link>http://anthonyf.wordpress.com/2010/02/01/a-month-of-work-on-lunula/</link>
		<comments>http://anthonyf.wordpress.com/2010/02/01/a-month-of-work-on-lunula/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 04:50:56 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Lunula]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/?p=56</guid>
		<description><![CDATA[It has been exactly one month since I posted but I have a good excuse this time: I have finished a couple of major milestones for Lunula.  The first was the release of version 0.2.1, which includes an evaluator and a read-eval-print-loop (REPL). The REPL is a very important feature of any lisp system, allowing [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=56&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It has been exactly one month since I posted but I have a good excuse this time: I have finished a couple of major milestones for <a href="http://lunula.codeplex.com/" target="_blank">Lunula</a>.  The first was the release of version 0.2.1, which includes an evaluator and a read-eval-print-loop (REPL).</p>
<p>The REPL is a very important feature of any lisp system, allowing you to do incremental development by running arbitrary test code on a live system.  Lunula&#8217;s evaluator is metacircular, which means it is written in Lunula and can evaluate itself.</p>
<p>Having the REPL gave me a significant boost in productivity.  A compiler <em>and</em> an evaluator gives me a staging environment to work with.  I can test out new code with the evaluator and once it is solid, compile it and integrate it into the system.  This helps with the bootstrapping problem I had before when I only had a compiler.  Any change to the language required me to compile the change with an old compiler, then compile again/run unit tests to make sure I didn&#8217;t break anything. With the REPL I can be fairly confident that I didn&#8217;t break anything if it evaluates correctly and I can do a lot more work before having to compile the compiler again.</p>
<p>One of the cool things about the metacircular evaluator is it inherits many of the features of the host language.  For example, since Lunula&#8217;s compiler supports tail-call optimization (TCO), the evaluator written in Lunula gets support for TCO for free.   I came to this realization when I started writing the evaluator, thinking that I would have to use trampolines there too.   I even wrote a version of the evaluator with trampolines after I got a stack-overflow when running my unit tests.  Later found that it was a bug in my &#8216;let&#8217; form.  I removed the trampolines and voilà,  the unit tests run and I get TCO for free!</p>
<p>The second milestone was adding the ability for Lunula to compile loadable modules (dll&#8217;s) and stand-alone executables.   For example, you can do this to compile a lunula source file and load it into the running system:</p>
<pre>&gt; (load (compile-file "hello-world.lun")) ; compiles hello-world.lun to a dll, then loads it.</pre>
<p>-or-</p>
<pre>&gt; (load "another-module.dll") ; loads a module created at some other time</pre>
<p>Supporting modules required me to do some major reorganization of the way the compiler was outputting code.  What I ended up doing was generating a LunulaModule class which contains the compiled representation of all of the code in a single .lun source file.  A LunulaModule has an Init() method which loads the toplevel forms in the module into the running system&#8217;s toplevel.   Compiling to an EXE was easy after writing the code for DLLs.  You can do this to compile a stand-alone EXE:</p>
<pre>&gt; (compile-file-to-exe "hello-world.lun") ; creates hello-world.exe </pre>
<p> <br />
For Silverlight and XNA I still support compiling directly to C# source so you can include those in a Visual Studio project.  The module compiler wont run in Silverlight or XNA at all, so any code added at runtime has to use the evaluator.  This is kind-of cool because it gives you a way to run arbitrary code at runtime (there may be a good reason to do this), which C# does not allow you to do on these platforms.</p>
<p>I think the next step is macros for sure.  Module support was a big unknown so I thought I&#8217;d get it out of the way before finishing macros. After that, maybe dynamic variables.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/56/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=56&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2010/02/01/a-month-of-work-on-lunula/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducing Lunula</title>
		<link>http://anthonyf.wordpress.com/2009/12/31/introducing-lunula/</link>
		<comments>http://anthonyf.wordpress.com/2009/12/31/introducing-lunula/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 20:47:03 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/?p=38</guid>
		<description><![CDATA[I&#8217;ve been busy over the past year or so and haven&#8217;t updated this blog at all.   I&#8217;ve mostly been working on various coding/learning projects.  My most recent project is Lunula, which is a Lisp to C# compiler. Lunula started out as an interpreter for Common Lisp, written in C#.  I actually went through two versions of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=38&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been busy over the past year or so and haven&#8217;t updated this blog at all.   I&#8217;ve mostly been working on various coding/learning projects.  My most recent project is <a title="Lunula on Codeplex" href="http://lunula.codeplex.com/" target="_blank">Lunula</a>, which is a Lisp to C# compiler.</p>
<p>Lunula started out as an interpreter for Common Lisp, written in C#.  I actually went through two versions of the interpreter and threw them both away, taking the things I learned and using them for the next version.    Once I had a pretty good grasp of the interpreter, I decided to take a crack at a compiler.</p>
<p>One thing I learned pretty quickly is that Common Lisp is an insanely huge language.   Building it up from scratch requires a lot of complicated pieces working correctly.  For example, the packaging system, the customizable reader, some hierarchy of types, lambda lists, destructuring-bind, namespaces, macros.  It was extremely overwhelming.</p>
<p>So in order to increase my chances of actually finishing this project, I decided to implement a Scheme compiler instead.    Scheme is a minimalistic Lisp, having very few primitive forms.   My next thought was that I should write the compiler in Scheme itself, making it a self-applicable compiler.</p>
<p>Having decided what the host language would be, I had to decide what I would compile to.   There are many Scheme-to-C and Scheme-to-&lt;insert language here&gt; compilers out there. Compiling to another language instead of machine code or byte code has several advantages, one being you can take full advantage of any features of the target language.  C# has two important features that make compiling to it easy: 1) a garbage collector and 2) real lambdas.    Not having to roll my own garbage collector is a big win.   Lambdas are less important but still make the code easier to write when you have them. C# is also a fairly popular language *and* it is the language used to code on two platforms I am currently interested in, XNA and Silverlight. If I can compile to C#, my language will run on these platforms in addition to Mac/Linux via Mono.</p>
<p>One feature that C# does not have that Scheme requires is tail-call optimization (TCO). Scheme does not have loops, only recursion. Iteration is done by having a function call itself as the last thing it does (tail-call) until some terminating condition is reached.  Without TCO, iteration over large collections would blow the stack. The optimization simply reuses the stack of the calling function, as its state is no longer needed.</p>
<p>I overcame this issue by implementing TCO with trampolines. When a function makes a call in the tail position, instead of calling that function, it returns a trampoline object which holds a lambda that wraps the function call it would have made. The call logic of the compiler then checks the return value of a function after it is called. If it returns a trampoline, it calls the lambda and checks the return value again. It does this over and over until it returns a value which is not a trampoline, the actual return value the function.</p>
<p>Lunula actually works now and can successfully compile itself.  I have abandoned PLT Scheme which was what I used to write the original compiler.   Now new features are added by compiling a new version of the compiler with an older version.   This can be challenging, especially when you have a bug in the previous compiler that you have to work around in order to compile a new version without the bug.</p>
<p>There is a lot of work left to be done.  For now it is nothing more than a toy compiler.   The next features I will be adding are an evaluator, Common-Lisp style macros, and maybe even start mutating it into a full-blown Common Lisp, with dynamic variables, packages, namespaces, CLOS and generic functions, etc.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/38/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/38/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/38/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=38&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2009/12/31/introducing-lunula/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
		<item>
		<title>Lazy Streams</title>
		<link>http://anthonyf.wordpress.com/2008/01/08/lazy-streams/</link>
		<comments>http://anthonyf.wordpress.com/2008/01/08/lazy-streams/#comments</comments>
		<pubDate>Tue, 08 Jan 2008 02:55:43 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/2008/01/08/lazy-streams/</guid>
		<description><![CDATA[I&#8217;ve been watching the SICP Lectures with a group of coworkers and friends. We just finished the lectures 6a and 6b which describe how to implement lazy lists or streams. I found these stream lectures to be very enlightening, mostly because they teach a new method of solving problems that is not typical in your [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=32&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been watching the <a href="http://swiss.csail.mit.edu/classes/6.001/abelson-sussman-lectures/">SICP Lectures</a> with a group of coworkers and friends.  We just finished the lectures 6a and 6b which describe how to implement lazy lists or streams.  I found these stream lectures to be very enlightening, mostly because they teach a new method of solving problems that is not typical in your average programming job.  If you have never watched the lectures I highly recommend it!</p>
<p>Implementing streams requires two new special forms, DELAY and<br />
CONS-STREAM.  Neither the book or the video lectures go into great<br />
detail about the actual implementation of DELAY and CONS-STREAM.  I<br />
assume the reason is you need access to the compiler code or macros to<br />
implement them, and that is surely beyond the scope of the class.</p>
<p>So I decided to take a crack at implementing the code in Common Lisp,<br />
and I was surprised how simple it is.  Common lisp of course has<br />
macros, so implementing the special forms is easy:</p>
<pre style="color:#000000;background-color:#ffffff;font-size:8pt;border-style:solid;border-width:1px;padding:5px;">(<span style="color:#a020f0;">eval-when</span> (<span style="color:#da70d6;">:compile-toplevel</span> <span style="color:#da70d6;">:load-toplevel</span> <span style="color:#da70d6;">:execute</span>)
  (<span style="color:#a020f0;">defmacro</span> <span style="color:#0000ff;">delay</span> (exp)
    <span style="color:#bc8f8f;">"creates a promise to calculate exp"</span>
    `(memo-proc #'(<span style="color:#a020f0;">lambda</span> () ,exp))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">cons-stream</span> (a b)
  (cons a (delay b)))</pre>
<p>DELAY is simply a macro that wraps its arguments into a lambda<br />
expression. This causes the evaluation of the expression to be delayed<br />
until the lambda expression is executed, using FORCE.  MEMO-PROC<br />
creates a memoized version of the lambda, making multiple calls to the<br />
expression more efficient.</p>
<p>CONS-STREAM must also be a macro because it needs to pass its<br />
second argument unevaluated to DELAY. The rest of the stream code can<br />
be implemented using plain-old-procedures.</p>
<p>You can do some pretty neat things with streams, like create a<br />
lazy Sieve of Eratosthenes:</p>
<pre style="color:#000000;background-color:#ffffff;font-size:8pt;border-style:solid;border-width:1px;padding:5px;">(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">sieve</span> (stream)
  <span style="color:#bc8f8f;">"lazy sieve of eratosthenes"</span>
  (cons-stream
   (stream-car stream)
   (sieve (stream-filter
           #'(<span style="color:#a020f0;">lambda</span> (x)
               (not (= 0 (mod x (stream-car stream)))))
           (stream-cdr stream)))))</pre>
<pre style="color:#000000;background-color:#ffffff;font-size:8pt;border-style:solid;border-width:1px;padding:5px;"><span style="color:#a020f0;">SICP-STREAMS&gt; </span><span style="font-weight:bold;">(defparameter primes (sieve (integers-from 2)))</span>
<span style="color:#ff0000;">PRIMES</span>
<span style="color:#a020f0;">SICP-STREAMS&gt; </span><span style="font-weight:bold;">(stream-ref primes 100)</span>
<span style="color:#ff0000;">547</span>
<span style="color:#a020f0;">SICP-STREAMS&gt; </span><span style="font-weight:bold;">(stream-ref primes 1000)</span>
<span style="color:#ff0000;">7927</span></pre>
<p>STREAM-REF finds the Nth element in the stream, so the examples<br />
show the 100th and 1000th primes.  It turns out that the lazy sieve is<br />
horribly inefficient because it creates a new stream filter for every<br />
prime found.  Finding the 10,000th prime will create 10,000 filter<br />
procedures and execute them all to find the next prime!</p>
<p>Here&#8217;s an infinite Fibonacci stream:</p>
<pre style="color:#000000;background-color:#ffffff;font-size:8pt;border-style:solid;border-width:1px;padding:5px;"><span style="color:#a020f0;">SICP-STREAMS&gt; </span><span style="font-weight:bold;">(defparameter fibs (cons-stream
                                  0
                                  (cons-stream
                                   1
                                   (add-streams (stream-cdr fibs)
                                                fibs))))</span>
<span style="color:#ff0000;">FIBS</span>
<span style="color:#a020f0;">SICP-STREAMS&gt; </span><span style="font-weight:bold;">(stream-ref fibs 10)</span>
<span style="color:#ff0000;">55</span>
<span style="color:#a020f0;">SICP-STREAMS&gt; </span><span style="font-weight:bold;">(stream-ref fibs 50)</span>
<span style="color:#ff0000;">12586269025</span>
<span style="color:#a020f0;">SICP-STREAMS&gt; </span><span style="font-weight:bold;">(stream-ref fibs 100)</span>
<span style="color:#ff0000;">354224848179261915075</span></pre>
<p>And finally, the complete source code:</p>
<pre style="color:#000000;background-color:#ffffff;font-size:8pt;border-style:solid;border-width:1px;padding:5px;"><span style="color:#b22222;">#|

Lazy Streams in Common Lisp
Author: Anthony Fairchild

Created: 2008.01.05
Last Modified: 2008.01.07

An implementation of the lazy streams found in SICP, using Common
Lisp.

|#</span>

(<span style="color:#a020f0;">defpackage</span> <span style="color:#228b22;">sicp-streams</span>
  (<span style="color:#da70d6;">:use</span> <span style="color:#da70d6;">:common-lisp</span>))

(<span style="color:#a020f0;">in-package</span> <span style="color:#da70d6;">:sicp-streams</span>)

<span style="color:#b22222;">;; </span><span style="color:#b22222;">(declaim (optimize (debug 3)))
</span>
(<span style="color:#a020f0;">eval-when</span> (<span style="color:#da70d6;">:compile-toplevel</span> <span style="color:#da70d6;">:load-toplevel</span> <span style="color:#da70d6;">:execute</span>)
  (<span style="color:#a020f0;">defmacro</span> <span style="color:#0000ff;">delay</span> (exp)
    <span style="color:#bc8f8f;">"creates a promise to calculate exp"</span>
    `(memo-proc #'(<span style="color:#a020f0;">lambda</span> () ,exp))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">cons-stream</span> (a b)
  (cons a (delay b)))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">memo-proc</span> (proc)
    <span style="color:#bc8f8f;">"returns a memoized version of proc"</span>
    (<span style="color:#a020f0;">let</span> ((already-run-p nil)
          (result nil))
      #'(<span style="color:#a020f0;">lambda</span> ()
          (<span style="color:#a020f0;">if</span> already-run-p
              result
              (<span style="color:#a020f0;">progn</span> (setf result (funcall proc))
                     (setf already-run-p t)
                     result)))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">force</span> (exp)
    <span style="color:#bc8f8f;">"evaluates a previously created promise"</span>
    (funcall exp))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">stream-car</span> (s) (car s))
(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">stream-cdr</span> (s) (force (cdr s)))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">stream-ref</span> (s n)
  <span style="color:#bc8f8f;">"finds the Nth element of stream S"</span>
  (<span style="color:#a020f0;">if</span> (= 0 n)
      (stream-car s)
      (stream-ref (stream-cdr s) (- n 1))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">stream-map</span> (proc <span style="color:#228b22;">&amp;rest</span> streams)
  <span style="color:#bc8f8f;">"executes PROC for every element in each stream"</span>
  (<span style="color:#a020f0;">if</span> (null streams)
      nil
      (cons-stream
       (apply proc (mapcar #'stream-car streams))
       (apply #'stream-map
              proc
              (mapcar #'stream-cdr streams)))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">stream-filter</span> (pred stream)
  (<span style="color:#a020f0;">cond</span> ((not stream) nil)
        ((funcall pred (stream-car stream))
         (cons-stream (stream-car stream)
                      (stream-filter pred
                                     (stream-cdr stream))))
        (t (stream-filter pred (stream-cdr stream)))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">add-streams</span> (s1 s2)
  (stream-map #'+ s1 s2))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">stream-for-each</span> (proc stream)
  (<span style="color:#a020f0;">if</span> (not stream)
      'done
      (<span style="color:#a020f0;">progn</span> (funcall proc (stream-car stream))
             (stream-for-each proc (stream-cdr stream)))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">print-stream</span> (stream)
  (stream-for-each #'print stream))

<span style="color:#b22222;">;;;; </span><span style="color:#b22222;">Example Usage ;;;;
</span>
(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">integers-from</span> (n)`
  <span style="color:#bc8f8f;">"returns a stream of integers starting from N"</span>
  (cons-stream n (integers-from (+ n 1))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">sieve</span> (stream)
  <span style="color:#bc8f8f;">"lazy sieve of eratosthenes"</span>
  (cons-stream
   (stream-car stream)
   (sieve (stream-filter
           #'(<span style="color:#a020f0;">lambda</span> (x)
               (not (= 0 (mod x (stream-car stream)))))
           (stream-cdr stream)))))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">make-primes-stream</span> ()
  (sieve (integers-from 2)))

(<span style="color:#a020f0;">defun</span> <span style="color:#0000ff;">make-fibs-stream</span> ()
  (<span style="color:#a020f0;">let</span> ((fibs nil))
    (setf fibs (cons-stream
                0
                (cons-stream
                 1
                 (add-streams (stream-cdr fibs)
                              fibs))))
    fibs))</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/32/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/32/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/32/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=32&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2008/01/08/lazy-streams/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
		<item>
		<title>Continuo: Part 2</title>
		<link>http://anthonyf.wordpress.com/2007/02/09/continuo-part-2/</link>
		<comments>http://anthonyf.wordpress.com/2007/02/09/continuo-part-2/#comments</comments>
		<pubDate>Fri, 09 Feb 2007 06:32:13 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/2007/02/09/continuo-part-2/</guid>
		<description><![CDATA[I decided to create a more graphical view of my continuo game. I find it easier to look at compared to the ASCII version in my previous entry. The color chains are much easier to follow. I used lispbuilder-sdl to generate the graphics. Each 4&#215;4 card has a thick black border and is labelled with [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=30&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I decided to create a more graphical view of my continuo game. I find it easier to look at compared to the ASCII version in my previous entry.   The color chains are much easier to follow.</p>
<p>I used lispbuilder-sdl to generate the graphics.  Each 4&#215;4 card has a thick black border and is labelled with a number representing the play order.</p>
<p>Score: 908</p>
<p><a href="http://img524.imageshack.us/my.php?image=continuoscreenshot116qx7.png" target="_blank"><img src="http://img524.imageshack.us/img524/4026/continuoscreenshot116qx7.th.png" alt="Free Image Hosting at www.ImageShack.us" border="0" /></a></p>
<p>Score: 919</p>
<p><a href="http://img521.imageshack.us/my.php?image=continuoscreenshot253zz8.png" target="_blank"><img src="http://img521.imageshack.us/img521/2205/continuoscreenshot253zz8.th.png" alt="Free Image Hosting at www.ImageShack.us" border="0" /></a></p>
<p>Score: 799</p>
<p><a href="http://img63.imageshack.us/my.php?image=continuoscreenshot630xv9.png" target="_blank"><img src="http://img63.imageshack.us/img63/6295/continuoscreenshot630xv9.th.png" alt="Free Image Hosting at www.ImageShack.us" border="0" /></a></p>
<p>Score: 830</p>
<p><a href="http://img63.imageshack.us/my.php?image=continuoscreenshot758kv6.png" target="_blank"><img src="http://img63.imageshack.us/img63/8430/continuoscreenshot758kv6.th.png" alt="Free Image Hosting at www.ImageShack.us" border="0" /></a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/30/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/30/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/30/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/30/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/30/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=30&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2007/02/09/continuo-part-2/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>

		<media:content url="http://img524.imageshack.us/img524/4026/continuoscreenshot116qx7.th.png" medium="image">
			<media:title type="html">Free Image Hosting at www.ImageShack.us</media:title>
		</media:content>

		<media:content url="http://img521.imageshack.us/img521/2205/continuoscreenshot253zz8.th.png" medium="image">
			<media:title type="html">Free Image Hosting at www.ImageShack.us</media:title>
		</media:content>

		<media:content url="http://img63.imageshack.us/img63/6295/continuoscreenshot630xv9.th.png" medium="image">
			<media:title type="html">Free Image Hosting at www.ImageShack.us</media:title>
		</media:content>

		<media:content url="http://img63.imageshack.us/img63/8430/continuoscreenshot758kv6.th.png" medium="image">
			<media:title type="html">Free Image Hosting at www.ImageShack.us</media:title>
		</media:content>
	</item>
		<item>
		<title>Continuo: My ILC contest entry</title>
		<link>http://anthonyf.wordpress.com/2007/02/07/continuo-my-ilc-contest-entry/</link>
		<comments>http://anthonyf.wordpress.com/2007/02/07/continuo-my-ilc-contest-entry/#comments</comments>
		<pubDate>Wed, 07 Feb 2007 07:43:05 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/2007/02/07/continuo-my-ilc-contest-entry/</guid>
		<description><![CDATA[This year&#8217;s International Lisp Conference is having a programming contest for those attending. Unfortunately for me, I live in the Seattle, WA area and the conference is in Cambridge, England! I love contests like this anyway so I decided to take a crack at it. The contest is to play a solitaire version of the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=29&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This year&#8217;s <a href="http://www.international-lisp-conference.org/2007/index">International Lisp Conference</a> is having a programming <a href="http://www.international-lisp-conference.org/2007/contest">contest</a> for those attending.  Unfortunately for me, I live in the Seattle, WA area and the conference is in Cambridge, England!  I love contests like this anyway so I decided to take a crack at it.</p>
<p>The contest is to play a solitaire version of the card game <a href="http://www.blackdogaccessories.com/card_games_main24.htm">Continuo</a>.   The <a href="http://www.international-lisp-conference.org/2007/contest">contest</a> page gives a good description of how the game is played so I wont get into that here.  The game looks like a lot of fun so I ordered a copy of the real game from a local game shop.</p>
<p>My Lisp solution is very naive but appears to play a decent game.  It simply plays the next card in the highest scoring position.  I think higher overall scores could be achieved if you take into account cards that have been played already as well as the ones not yet played.  I cant really wrap my brain around that one at the moment so my naive solution works just fine for now <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>I wont post my code until the contest is over, but I will say that it is about 200 lines of highly unoptimized code, including comments and some test code.  Using SBCL on Linux it runs in about 16 seconds and conses like nobody&#8217;s business.  Here&#8217;s an example run with test data that scores 852.</p>
<pre>
CONTINUO&gt; (time (play-continuo '(:RBRB :GYGB :GYRY :BYBY :RBYR :RGRB :RGBG
                                 :BYGY :RGRY :RBRY :RYRY :RYGY :YRBY :BYRY
                                 :BRBY :GBYB :RBGB :GBGB :RYBY :RYRG :GYBY
                                 :RGYR :GBRB :RBYB :YGBY :GBGY :GRBG :BRGB
                                 :YRGY :BGBY :GYGY :RYRB :GRYG :GRGY :RBRG
                                 :RGYG :BGYB :BRYB :GBYG :RGRG :GRGB :RGBR)))
score=852
    - - - - - - - - - - - - - - - - - - - -
    2 1 1 1 1 1 1 1 1 1 1                                       1 1 1 1 1 1
    0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-22                 G R G B
-21                 R R G G G Y B G
-20                 G G R R Y Y B B
-19                 B G R G B B Y Y
-18                 Y G R G G B Y G R G Y G
-17                 G G R R Y G Y G G G Y Y
-16                 R R G G G G Y Y Y Y G G R G R G
-15                 G R G Y Y Y G G G Y G R G G R R
-14                 B Y B R G Y G Y R Y G R R R G G
-13                 Y Y B B G Y B Y Y Y G G G R G R
-12         Y G B G B B Y Y Y Y B B G G Y Y Y R G Y     B R Y B
-11         G G B B R B Y B B B Y Y R G Y R R R G G     R R Y Y
-10 B Y G B B B G G Y B Y R Y B Y G Y G Y R G G R R     Y Y R R
 -9 Y Y G G G B G Y B B Y Y Y R Y B G G Y Y Y G R Y     B Y R B
 -8 G G Y Y Y B G Y Y Y B B R R Y Y Y Y G G R Y R Y B R B G R B R G
 -7 B G Y B B B G G R Y B Y Y Y R R R Y G Y Y Y R R R R B B B B R R
 -6 G R Y G G G B B B Y B G B Y R Y B Y G Y R R Y Y B B R R R R B B
 -5 R R Y Y Y G B Y Y Y B B B Y B Y Y Y G G Y R Y R G B R B G R B R R G B R
 -4 Y Y R R B G B Y B B Y Y Y Y B B G G Y Y Y R B R Y B R Y G R B G G G B B
 -3 G Y R G G G B B G B Y B B B Y Y Y G Y B R R B B B B R R R R B B B B G G
 -2         B B G G G R Y R Y B Y B B G Y G B B R R R R B B B B R R R B G R
 -1         Y B G B R R Y Y Y R Y G G G Y Y R B R Y Y R B Y G B R G
  0                 Y Y R R R R Y Y Y Y G G R B R B B R B Y   B R G B
  1                 R Y R G Y Y R R G Y G B B B R R R R B B   R R G G
  2                 R Y R B G Y R Y R Y B R R R B B B B R R   G G R R
  3                 Y Y R R R G R Y Y Y B B B R B R Y B R B   B G R B
  4                 R R Y Y G G R R B B Y Y B R G R R B G B
  5                 B R Y R R R G G R B Y R R R G G B B G G
  6                         Y R G R G B G R G G R R G G B B
  7                         G B G B B B G G R G R B B G B R
  8                         B B G G G G B B
  9                         G G B B R G B G
 10                         B G B G
Evaluation took:
  16.28 seconds of real time
  15.820989 seconds of user run time
  0.220014 seconds of system run time
  [Run times include 1.612 seconds GC run time.]
  0 page faults and
  1,848,458,504 bytes consed.
NIL</pre>
<p><strong>EDIT:</strong> I used slime-profile-package to profile my code and was able to make a very small change that produces the same result as above in only 1.35 seconds.  I really love slime <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<pre>
Evaluation took:
  1.35 seconds of real time
  1.352084 seconds of user run time
  0.0 seconds of system run time
  [Run times include 0.048 seconds GC run time.]
  0 page faults and
  62,727,048 bytes consed.</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/29/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/29/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/29/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=29&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2007/02/07/continuo-my-ilc-contest-entry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
		<item>
		<title>Easy bookmarks in Emacs</title>
		<link>http://anthonyf.wordpress.com/2007/01/16/easy-bookmarks-in-emacs/</link>
		<comments>http://anthonyf.wordpress.com/2007/01/16/easy-bookmarks-in-emacs/#comments</comments>
		<pubDate>Tue, 16 Jan 2007 08:12:58 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Emacs]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/2007/01/16/easy-bookmarks-in-emacs/</guid>
		<description><![CDATA[Emacs is an incredibly feature rich editor. You can do just about anything you would ever want to do and much more. Unfortunately the power and flexibility of Emacs can be a bit unfriendly and cumbersome at times. I seem to rediscover this fact every 2-3 weeks and I usually customize Emacs in some way [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=28&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Emacs is an incredibly feature rich editor.   You can do just about anything you would ever want to do and much more.  Unfortunately the power and flexibility of Emacs can be a bit unfriendly and cumbersome at times.   I seem to rediscover this fact every 2-3 weeks and I usually customize Emacs in some way to make things easier for me.</p>
<p>My latest discovery is the complicated bookmarking system.  Setting a bookmark in Emacs involves moving to the line in the file you want to bookmark, typing <span style="font-weight:bold;">C-x r m</span> and then giving the bookmark a unique name.  To find the bookmark later, you type <span style="font-weight:bold;">C-x r b</span> and then type the unique name you gave the bookmark.   This bookmarking system is very flexible but can difficult to work with.</p>
<p>I&#8217;ve used Visual Studio in the past and I became quite fond of its simple bookmarking system.  You simply type <strong>Ctrl-F2</strong> to set a bookmark and <strong>F2 </strong>to cycle between bookmarks.  <strong>Shift-F2</strong> cycles bookmarks in reverse.   It is such a brain dead system.  No need to remember bookmark names.  No tiresome keystrokes to type.</p>
<p>Since Emacs is *the* programmable text editor, I was able to extend the existing bookmarking system to emulate the Visual Studio style bookmarks.   Now I have a &#8220;dumbed down&#8221; bookmarking system that is quick and easy to use.</p>
<p>Here&#8217;s the code I wrote to make it happen:</p>
<pre></pre>
<pre>
<font color="#b22222">;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; </font><font color="#b22222">
</font><font color="#b22222">;; </font><font color="#b22222">Easy bookmarks management
</font><font color="#b22222">;;</font><font color="#b22222">
</font><font color="#b22222">;; </font><font color="#b22222">Author: Anthony Fairchild
</font><font color="#b22222">;;</font><font color="#b22222">
</font>
<font color="#b22222">;;;; </font><font color="#b22222">Keymaping examples
</font><font color="#b22222">;; </font><font color="#b22222">(global-set-key [(control f2)]  'af-bookmark-toggle )
</font><font color="#b22222">;; </font><font color="#b22222">(global-set-key [f2]  'af-bookmark-cycle-forward )
</font><font color="#b22222">;; </font><font color="#b22222">(global-set-key [(shift f2)]  'af-bookmark-cycle-reverse )
</font><font color="#b22222">;; </font><font color="#b22222">(global-set-key [(control shift f2)]  'af-bookmark-clear-all )
</font>
<font color="#b22222">;; </font><font color="#b22222">Include common lisp stuff
</font>(<font color="#a020f0">require</font> '<font color="#5f9ea0">cl</font>)
(<font color="#a020f0">require</font> '<font color="#5f9ea0">bookmark</font>)
(<font color="#a020f0">defvar</font> <font color="#b8860b">af-current-bookmark</font> nil)

(<font color="#a020f0">defun</font> <font color="#0000ff">af-bookmark-make-name</font> ()
  <font color="#bc8f8f">"makes a bookmark name from the buffer name and cursor position"</font>
  (concat (buffer-name (current-buffer))
          <font color="#bc8f8f">" - "</font> (number-to-string (point))))

(<font color="#a020f0">defun</font> <font color="#0000ff">af-bookmark-toggle</font> ()
  <font color="#bc8f8f">"remove a bookmark if it exists, create one if it doesnt exist"</font>
  (interactive)
  (<font color="#a020f0">let</font> ((bm-name (af-bookmark-make-name)))
    (<font color="#a020f0">if</font> (bookmark-get-bookmark bm-name)
        (<font color="#a020f0">progn</font> (bookmark-delete bm-name)
               (message <font color="#bc8f8f">"bookmark removed"</font>))
      (<font color="#a020f0">progn</font> (bookmark-set bm-name)
             (setf af-current-bookmark bm-name)
             (message <font color="#bc8f8f">"bookmark set"</font>)))))</pre>
<pre>(<font color="#a020f0">defun</font> <font color="#0000ff">af-bookmark-cycle</font> (i)
  <font color="#bc8f8f">"Cycle through bookmarks by i.  'i' should be 1 or -1"</font>
  (<font color="#a020f0">if</font> bookmark-alist
      (<font color="#a020f0">progn</font> (<font color="#a020f0">unless</font> af-current-bookmark
               (setf af-current-bookmark (first (first bookmark-alist))))
             (<font color="#a020f0">let</font> ((cur-bm (assoc af-current-bookmark bookmark-alist)))
               (setf af-current-bookmark
                     (<font color="#a020f0">if</font> cur-bm
                         (first (nth (mod (+ i (position cur-bm bookmark-alist))
                                          (length bookmark-alist))
                                     bookmark-alist))
                       (first (first bookmark-alist))))
               (bookmark-jump af-current-bookmark)
               <font color="#b22222">;; </font><font color="#b22222">Update the position and name of the bookmark.  We
</font>               <font color="#b22222">;; </font><font color="#b22222">only need to do this when the bookmark has changed
</font>               <font color="#b22222">;; </font><font color="#b22222">position, but lets go ahead and do it all the time
</font>               <font color="#b22222">;; </font><font color="#b22222">anyway.
</font>               (bookmark-set-position af-current-bookmark (point))
               (<font color="#a020f0">let</font> ((new-name (af-bookmark-make-name)))
                 (bookmark-set-name af-current-bookmark new-name)
                 (setf af-current-bookmark new-name))))
    (message <font color="#bc8f8f">"There are no bookmarks set!"</font>)))</pre>
<pre>(<font color="#a020f0">defun</font> <font color="#0000ff">af-bookmark-cycle-forward</font> ()
  <font color="#bc8f8f">"find the next bookmark in the bookmark-alist"</font>
  (interactive)
  (af-bookmark-cycle 1))</pre>
<pre>(<font color="#a020f0">defun</font> <font color="#0000ff">af-bookmark-cycle-reverse</font> ()
  <font color="#bc8f8f">"find the next bookmark in the bookmark-alist"</font>
  (interactive)
  (af-bookmark-cycle -1))

(<font color="#a020f0">defun</font> <font color="#0000ff">af-bookmark-clear-all</font>()
  <font color="#bc8f8f">"clears all bookmarks"</font>
  (interactive)
  (setf bookmark-alist nil))</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/28/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/28/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=28&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2007/01/16/easy-bookmarks-in-emacs/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
		<item>
		<title>A Lispy Jigsaw Puzzle Game</title>
		<link>http://anthonyf.wordpress.com/2006/12/27/a-lispy-jigsaw-puzzle-game/</link>
		<comments>http://anthonyf.wordpress.com/2006/12/27/a-lispy-jigsaw-puzzle-game/#comments</comments>
		<pubDate>Wed, 27 Dec 2006 05:18:17 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/2006/12/27/a-lispy-jigsaw-puzzle-game/</guid>
		<description><![CDATA[My blog has been neglected lately, but I have a good reason. I&#8217;ve been playing around with lispbuilder-sdl, a Lisp interface to SDL, used for creating games. I decided to resurrect an old jigsaw puzzle game I wrote a few years ago using pygame. The game was never really finished, as with many of my [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=27&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>My blog has been neglected lately, but I have a good reason.   I&#8217;ve been playing around with <a href="http://lispbuilder.sourceforge.net/">lispbuilder-sdl</a>, a Lisp interface to <a href="http://www.libsdl.org">SDL</a>, used for creating games.  I decided to resurrect an old jigsaw puzzle game I wrote a few years ago using <a href="http://www.pygame.org">pygame</a>.  The game was never really finished, as with many of my other personal programming projects.</p>
<p>Converting the old Python code to Lisp was fun.  I was able to simplify a lot and performance is much better, mostly due to Lisp being a compiled language.  The python version was slow and I really had no way to optimize unless I wrote C extensions.  Now with Lisp I can profile the code and add compiler optimizations and declarations to speed things up where they need to be.  I still have the option to write C extensions but its unlikely I&#8217;ll need to for this game.</p>
<p>Creating each jigsaw puzzle piece was a little challenging and very processor intensive.  I start by chopping up an image into square pieces.  Each piece overlaps adjacent pieces by about 1/3.  These pieces are then rotated 90, 180 and 270 degrees.   Next I create a mask image where I draw the puzzle piece outline using bézier curves.  I flood fill the outside of the mask image with the mask color, then blit it onto original piece image.   Repeat for each rotation.  OK, I think I left a few steps out, but my point is, it takes a while to create a puzzle from a source image.  Using this process I can create a puzzle from any image.</p>
<p>Each puzzle piece is placed randomly on the screen.  Right clicking a piece rotates it.  Pieces that belong together can be joined by dragging one piece next to another.  They snap together and then remain joined when moving them around.  Joined pieces can also be rotated.</p>
<p>It is nowhere near done.    I plan on adding many features, at least enough to be able to call it a beta.  I would like to get a website with a downloadable binary and source code going soon.  Hopefully I can maintain my interest in this and finish something for a change <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Here are few screenshots of the game (sorry about the imageshack ads):</p>
<table>
<tr>
<td><a href="http://img245.imageshack.us/my.php?image=screenshotdq2.jpg" target="_blank"><img src="http://img245.imageshack.us/img245/467/screenshotdq2.th.jpg" border="0" /></a></td>
<td><a href="http://img187.imageshack.us/my.php?image=screenshot2bl1.jpg" target="_blank"><img src="http://img187.imageshack.us/img187/1249/screenshot2bl1.th.jpg" border="0" /></a></td>
</tr>
<tr>
<td><a href="http://img187.imageshack.us/my.php?image=screenshot3xt0.jpg" target="_blank"><img src="http://img187.imageshack.us/img187/3163/screenshot3xt0.th.jpg" border="0" /></a></td>
<td><a href="http://img187.imageshack.us/my.php?image=screenshot4tp1.jpg" target="_blank"><img src="http://img187.imageshack.us/img187/7636/screenshot4tp1.th.jpg" border="0" /></a></td>
</tr>
</table>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/27/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/27/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=27&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2006/12/27/a-lispy-jigsaw-puzzle-game/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>

		<media:content url="http://img245.imageshack.us/img245/467/screenshotdq2.th.jpg" medium="image" />

		<media:content url="http://img187.imageshack.us/img187/1249/screenshot2bl1.th.jpg" medium="image" />

		<media:content url="http://img187.imageshack.us/img187/3163/screenshot3xt0.th.jpg" medium="image" />

		<media:content url="http://img187.imageshack.us/img187/7636/screenshot4tp1.th.jpg" medium="image" />
	</item>
		<item>
		<title>Remembering Passwords with Password Grids</title>
		<link>http://anthonyf.wordpress.com/2006/10/23/remembering-passwords-with-password-grids/</link>
		<comments>http://anthonyf.wordpress.com/2006/10/23/remembering-passwords-with-password-grids/#comments</comments>
		<pubDate>Mon, 23 Oct 2006 01:34:55 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://anthonyf.wordpress.com/?p=26</guid>
		<description><![CDATA[Edit: I was contacted by *the* guy, Mike, that invented the password grids, see his comments below. He has republished his article here: http://www.vvsss.com/grid/ I recommend reading it first! If you are really paranoid like I am then you have a different password for every computer login and Internet site you subscribe to. Hopefully you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=26&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Edit: </strong> I was contacted by *the* guy, Mike, that invented the password grids, see his comments below.  He has republished his article here:  <a href="http://www.vvsss.com/grid/">http://www.vvsss.com/grid/</a>  I recommend reading it first!</p>
<p>If you are really paranoid like I am then you have a different password for every computer login and Internet site you subscribe to.   Hopefully you are not one of the many people out there that use the same password for *everything*.    That&#8217;s just begging to get your identity stolen.</p>
<p>For years I&#8217;ve struggled to come up with the perfect way to keep track of all of my 100+ passwords.   Years ago I tried various free and commercial password keeping products such as Passwords Plus, Splash! Wallet and MobiPassword and I never really felt comfortable using them.</p>
<p>Since then I&#8217;ve used a simple solution:  an encrypted OpenOffice Calc (or MS Excel) spreadsheet.  I encrypt the file with a master password and then put all of my login and password information in the file.   This system has its own set of vulnerabilities.  For example, if I put the spreadsheet on a thumb-drive and lose it, some hacker with too much free time might turn cracking the file into a hobby.  Another issue is after I decrypt the spreadsheet it is placed in RAM or a swap file as plain text.   Furthermore, when I had to enter my password on a website I would often copy the password to the clipboard and paste it into the web form.  The clipboard makes my password available to any other program to read.</p>
<p>I know this sounds like an overly paranoid PITA, but that&#8217;s what I did.  Until now.  I&#8217;ve decided to take a more low-tech approach to remembering passwords.  I found a web page about password grids years ago and thought it was a neat idea.  I wish I could find a link to the site but Google is failing me now.  The closest thing I could find was a comment about it on this <a href="http://www.schneier.com/blog/archives/2006/02/passlogix_misqu.html" target="_blank">site</a>.   I never really adopted the system before because it seemed a bit silly at the time.   After trying all of the other methods and not liking any of them, I&#8217;ve decided to give the grids a try.  And so far I like them!</p>
<p>The basic idea behind the password grids is simple.  Think of an easy to remember but hard to guess pattern on an 8&#215;8 grid.  For example, here&#8217;s a very simple pattern,  the letter F:</p>
<pre>
+-------------------------------+
|   |   |   |   |   |   |   |   |
|---+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |   |
|---+---+---+---+---+---+---+---|
|   | 1 | 6 | 7 |   |   |   |   |
|---+---+---+---+---+---+---+---|
|   | 2 |   |   |   |   |   |   |
|---+---+---+---+---+---+---+---|
|   | 3 | 8 |   |   |   |   |   |
|---+---+---+---+---+---+---+---|
|   | 4 |   |   |   |   |   |   |
|---+---+---+---+---+---+---+---|
|   | 5 |   |   |   |   |   |   |
|---+---+---+---+---+---+---+---|
|   |   |   |   |   |   |   |   |
+-------------------------------+</pre>
<p>The pattern starts with the number 1 and ends with the number 8. Now that we have a pattern, we can generate a random password grid:</p>
<pre>
+-------------------------------+
| x | ~ | d | [ | : | j | &lt; | @ |
|---+---+---+---+---+---+---+---|
| ; | , | S | K | ` | a | f | n |
|---+---+---+---+---+---+---+---|
| f | ! | D | ! | u | 7 | 1 | A |
|---+---+---+---+---+---+---+---|
| ~ | s | V | a | 5 | N | k | v |
|---+---+---+---+---+---+---+---|
| V | 9 | | | K | | | o | y | a |
|---+---+---+---+---+---+---+---|
| K | J | H | " | s | r | ] | _ |
|---+---+---+---+---+---+---+---|
| Q | = | y | : | s | # | x | m |
|---+---+---+---+---+---+---+---|
| I | k | T | t | p | ? | T | w |
+-------------------------------+</pre>
<p>With the random grid and the pattern we can derive the password. Do this by traversing the pattern on the random grid.   The password for this example would be &#8220;!s9J=D!|&#8221;.   Although the password is short, it is very secure.  It contains upper and lower case letters, numbers and symbols, like all good passwords should!  As I mentioned above, the pattern you use should be easy for you to remember, but hard for others to guess.  The patterns can start at any location, move backwards, forwards, diagonal and even skip around.  <strong>Edit:  </strong>I&#8217;m not sure I made this clear and it may be causing confusion.  You only need to remember one pattern for all of your password grids.  It would be insanely difficult to remember a different pattern for each grid.</p>
<p>The way you manage your passwords is also simple.  Print out a page of random grids, one for each login you have, cut them out into cards, and put them in your wallet.  If someone sees the password grid, they cannot derive the password easily unless they know your pattern.  If your pattern is ever discovered, then your password cannot be retrieved without having the grid for that password.  So its a double-key system, both parts are necessary to get the password.  You can also carry around blank grids in case you need to create a new login account while you are sipping coffee at the cyber-cafe.</p>
<p>I created a JavaScript program to generate the password grids.  I chose JavaScript (and not Lisp) because it can generate the grids on the client side, not requiring a server.  It also makes printing the grids easy from the browser.  Here&#8217;s a link to the <a href="http://www.purevirtual.com/~anthony/password-grids.html" target="_blank">program</a>.  It generates 9 password grids and allows you to toggle upper/lower case alpha, numbers and symbols.  When printing the page make sure you set it up to shrink to fit.</p>
<p>If you like the system and want to use it,  I recommend you save the html file to your local machine.   I also highly recommend backing up the grids you use to a text file in case your wallet is lost.</p>
<p>I&#8217;m not sure how secure this system really is.    With a complicated pattern it seems to me to be very secure.  If anyone has an opinion I&#8217;d like to hear it.</p>
<p><span style="font-weight:bold;">Edit:</span>  If you have a system that works for you, that&#8217;s great.  One person suggested grouping sites into high/medium/low and only memorizing the passwords for the high&#8217;s.  This system works good when you have a low number of high security systems.  Password grids would be ideal for those high importance passwords.  I agree the password grid may be overkill for most people, but for paranoid people like me, it helps me sleep better at night <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/26/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/26/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/26/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=26&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2006/10/23/remembering-passwords-with-password-grids/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
		<item>
		<title>Coding in !C (or using fseek to make really huge files quickly)</title>
		<link>http://anthonyf.wordpress.com/2006/08/30/coding-in-c/</link>
		<comments>http://anthonyf.wordpress.com/2006/08/30/coding-in-c/#comments</comments>
		<pubDate>Wed, 30 Aug 2006 01:03:39 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">https://anthonyf.wordpress.com/2006/08/30/coding-in-c/</guid>
		<description><![CDATA[I&#8217;ve been crazy busy at work so I&#8217;ve been slacking on my posts. Lots of cool things to write about but not enough time! On a positive note I&#8217;ve been doing more utility code in Lisp at work. At work I call Lisp !C (not C) to avoid any political issues that could arise. When [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=23&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been crazy busy at work so I&#8217;ve been slacking on my posts.  Lots of cool things to write about but not enough time!  On a positive note I&#8217;ve been doing more utility code in Lisp at work.  At work I call Lisp !C (not C) to avoid any political issues that could arise.  When asked &#8220;What&#8217;s !C?&#8221;,  I answer &#8220;Its like C, only better!  It&#8217;s all the rage!  Everyone is doing it!&#8221;.</p>
<p>This past weekend I worked on a program for work that fragments the hell out of a hard disk.  Why, you ask?  Its a tool to test the performance of our product under extreme conditions.  It fragments the disk by creating files of random size util it reaches a free space threshold, then deletes random files which it previously created.  After a few deletes, it creates more randomly sized files.  Rinse, repeat.  If you let the program run for a while on a disk it produces files with 200+ fragments.</p>
<p>The first working version of the code was horribly slow. It took an *extremely* long time to fill up a disk with files before it got to the delete stage.  The file writes were taking way to long to complete.  I got to talking to my coworker about this problem and he suggested an old hack which I have never heard of.  Instead of writing data to the files, use fseek() to seek to the position where the desired EOF should be and then write a single byte to it.   This technique can be used to create huge files in a matter of milliseconds.  He explained that this hack can be used to &#8220;see&#8221; the data in the free space on a disk.  How evil is that?</p>
<p>Changing my code to use the new technique made it orders of magnitude faster.  But it wasn&#8217;t long before we discovered a bug in the new system.  I was able to allocate huge files on the system (1GB+) but it would not decrease the amount of free space on the disk.  After a throwing out a few wild a crazy theories about it my coworker and I finally discovered what was going on.  The file system was not reserving space for blocks that were not written to.  So for a 1GB file only one block was getting reserved.  The rest of the file must be in the &#8220;free block pool&#8221; until data is written to it.</p>
<p>To fix the problem I changed the code to write out a single byte per block, thus allocating the the entire block without the overhead of filling the entire block with data.  This solution is not quite as fast but it is still way more efficient than the original one, and it works!</p>
<p>The program was written in CLISP, which is a very cool Lisp for doing shell scripting an quick one-off utilities. Here&#8217;s the code for the function that eats the disk space:</p>
<pre>(<font color="#a020f0">defun</font> <font color="#0000ff">eat-space</font> (file-name size)
  <font color="#bc8f8f">"Create a bogus file that chews up disk space.  Size is in bytes."</font>
  (<font color="#a020f0">let</font> ((file (linux:fopen file-name <font color="#bc8f8f">"w"</font>)))
    <font color="#b22222">;; write a byte every 4k so a block gets allocated
</font>    (<font color="#a020f0">loop</font> for x from 0 to (1- size) by 4096
          do (<font color="#a020f0">progn</font> (linux:fseek file x 0)
                    (linux:fputc 1 file)))
    (linux:fclose file)))</pre>
<p>One other thing to note for any lispers that may be reading this.  The code above uses the LINUX package in CLISP, not the standard CL file IO functions.  The reason I cannot use the standard functions is FILE-POSITION throws an error when attempting the seek past the end of a file.  So in other words, the seek hack does not work in standard common lisp (or at least CLISP&#8217;s version of it).</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/23/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/23/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=23&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2006/08/30/coding-in-c/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
		<item>
		<title>Reader Macros</title>
		<link>http://anthonyf.wordpress.com/2006/08/08/reader-macros/</link>
		<comments>http://anthonyf.wordpress.com/2006/08/08/reader-macros/#comments</comments>
		<pubDate>Tue, 08 Aug 2006 23:27:46 +0000</pubDate>
		<dc:creator>anthonyf</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">https://anthonyf.wordpress.com/2006/08/08/reader-macros/</guid>
		<description><![CDATA[I&#8217;m working on a Lisp program for a friend right now that will import old blog entries from a giant XML file. The file is about 60MB, mostly containing images in base64 format. I&#8217;m using CL-XMLS to parse the XML file and for some reason it takes a *long* time (15+ minutes) to parse a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=22&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a Lisp program for a friend right now that will import old blog entries from a giant XML file.  The file is about 60MB, mostly containing images in base64 format.  I&#8217;m using CL-XMLS to parse the XML file and for some reason it takes a *long* time (15+ minutes) to parse a large file.  It could be that the library was never meant to parse files that big.  So working with this data file is a real pain.</p>
<p><b>Disclaimer:</b> I&#8217;m going to have to say at this point that I&#8217;ve only been coding Lisp for a year, maybe a little more, so I may get some of this wrong.  Corrections are welcome!</p>
<p><b><span>Edit:</span></b> See Levi&#8217;s comments and corrections below as I am a bit mixed up on terminology.</p>
<p>Common Lisp has a handy feature that makes working with large amounts of external data easier:  reader macros.   A reader macro allows you to embed the results of a lisp expression into your code.  The lisp expression can be anything, like loading an image file or in my case, a very large XML file.  This pushes the time it takes to load the XML file to compile time, rather than run time.  Once I&#8217;ve compiled the source file, everything is fast binary data at that point.  As long as the XML data or the source file doesn&#8217;t change, I never have to load it again.</p>
<p>Here are the details.  I have a file called blog.lisp that contains the code to load the data from the XML file and the reader macro to embed the results into the code:</p>
<pre>(<font color="#a020f0">in-package</font> <font color="#da70d6">:erik-blog</font>)

(<font color="#a020f0">eval-when</font> (<font color="#da70d6">:compile-toplevel</font> <font color="#da70d6">:load-toplevel</font> <font color="#da70d6">:execute</font>)
  (<font color="#a020f0">defun</font> <font color="#0000ff">parse-blog</font> ()
    (<font color="#a020f0">with-open-file</font> (in (merge-pathnames #p<font color="#bc8f8f">"erik-blog.xml"</font> (util:source-file-directory)))
      (xmls:parse in))))

(<font color="#a020f0">defvar</font> <font color="#b8860b">*blog-data*</font> '#.(parse-blog))</pre>
<p>In Common Lisp the syntax for a reader macro is #.(some lisp expression).  The last line above embeds the results of the PARSE-BLOG function into the code, which then gets assigned to *BLOG-DATA*.  When blog.lisp is compiled, it produces a blog.fasl file which is like a .obj file in C except it can be dynamically loaded.  The blog.fasl file that is produced is large because it contains the entire binary representation of the blog data.  It takes about a second to load the FASL file into my running lisp image but that is nothing compared to the 15+ minutes it would take to load it from scratch.</p>
<p>This technique can be used to embed any type of data asset into an application.  I read somewhere on-line about a game company (Naughty Dog) that compiled graphics, sounds and other assets into their Lisp game.   Very cool stuff!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/anthonyf.wordpress.com/22/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/anthonyf.wordpress.com/22/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/anthonyf.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/anthonyf.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/anthonyf.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/anthonyf.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/anthonyf.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/anthonyf.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/anthonyf.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/anthonyf.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/anthonyf.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/anthonyf.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/anthonyf.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/anthonyf.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/anthonyf.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/anthonyf.wordpress.com/22/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=anthonyf.wordpress.com&amp;blog=179712&amp;post=22&amp;subd=anthonyf&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://anthonyf.wordpress.com/2006/08/08/reader-macros/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6ceed633057ef2a85c19d4e5003d8f0c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">anthonyf</media:title>
		</media:content>
	</item>
	</channel>
</rss>
