All I really wanted was a wiki, maybe a wiki with a blog feature.
One of the issues that I would run into with Common Lisp was that sometimes I would get my image into an unusable state. The lisp way is incremental development, and one shouldn't need to restart their image very often, so I am told. Every now and then though, I'd fire up Emacs, Slime, and SBCL. I'd load up my files in the wrong order and blamo! My image was borked. I would get this error:
The function :USE is undefined. [Condition of type COMMON-LISP:UNDEFINED-FUNCTION]
I'd abort the compilation. A ton of errors, warnings, and style-warnings would fly by. I must have committed a grievous sin in the eyes of all that is holy in lisp because my code is marked yellow, orange and red everywhere!
The error comes from my package definition supposedly:
(defpackage :test-chain1 (:use :cl :cffi :ode :drawstuff))
The very first line of code in my file; it's totally idiomatic code. I haven't even been given a chance to upset compiler with my code below. The weird thing is
:use isn't even supposed to be interpreted as a
function. It's a keyword for the macro
defpackage to interpret. In
an edit, compile, run language, I would just make sure that I loaded
those packages first before I ran my code again, problem solved. So, I try that. I evaluate these expressions
to supply the necessary packages:
> (require 'cffi) NIL > (require 'cl-ode) NIL > (require 'cl-drawstuff) NIL
Good. They load all right, so I try reloading my code. But it still
doesn't work. When I try to reload my code, I get the same error about
:use function not being defined. WTF? That's not very nice of
this environment to screw me for one early mistake. Please, I repent,
REPL. I've loaded the packages you need, what more do you want from
There is a relatively easy work-around, and it only requires that I sacrifice my insistence on accepting the lisp way of development: I can just restart my image and load my files in the right order. But I'd merely be betraying myself by living in this new lisp world by pretending it's just like the old C world. It's like the saying, you can write FORTRAN in any language. Well, edit-compile-runners can eek out an existence in any REPL environment provided they get hold of the on/off switch. Props to Marco for sneakily not revealing the on/off switch in his video how-to for slime. Too bad I found it anyway! [Whispers:] in Slime's REPL hit comma, 'r', 'e', ... [Door swings open.] *BANG* Marco!? hi, I wasn't [perspires] no, of course, not. [Marco leaves.] Um, you'll have to find it yourselves.
I ventured into
irc.freenode.net and asked about how I
could fix this problem since I knew I was violating the lisp way. I
was a little worried about this because the lisp community kind of has
a bad reputation when it comes to dealing with newbies. However,
nobody told me to RTFM or dismissed me out of hand.
#lisp said, "Time to learn about packages." Awesome. Where can I
learn about them?
rottcodd pointed me toward this
tutorial, which is titled,
"The Complete Idiot's Guide to Common Lisp Packages." I didn't take
the title as a snub since it actually seems like a good guide. The
in Common Lisp the
gave me some tools to poke around into Common Lisp's package system.
Anyway, the guys on
#lisp were cool and helpful.
I played around to see if my package was being loaded.
> (find-package "test-chain1") NIL > (find-package "TEST-CHAIN1") ;; ah, uppercase package name #<PACKAGE> > (find-package :test-chain1) ;; also works with the symbol reference (good to know) #<PACKAGE>
I did have a package called
TEST-CHAIN1 loaded. What if I delete
it? So I ran:
> (delete-package (find-package :test-chain1)) T
I crossed my fingers and reloaded my code. Fantastic! It compiled without issue. All the yellow, orange, and red smears against my integrity vanished. So I've fixed my image, but is this really how lispers deal with dependencies? In a word, no. Here are a few solutions to the underlying issue of code dependencies. The reason I went to the trouble of writing this up is so that, hopefully, one could google "The function :USE is undefined" and come up with a useful link.
This fix is implementation dependent (I'm using SBCL), so it is something you'd only want to rely on with your own personal code. You'd never want to distribute it.
(require 'cffi) (require 'cl-ode) (require 'cl-drawstuff) (defpackage :test-chain1 (:use :cl :cffi :ode :drawstuff))
The best thing to do is get familiar with ASDF. That's how lispers
actually manage dependencies in their code. ASDF with asdf-install is like Perl's CPAN or ruby's gem.
#lisp has a
great tutorial on setting
up a small lisp project and how to use ASDF to do it. Once I have
that setup, I could do something like this:
> (require 'test-chain1)
It would load up all the required packages first (provided I set them up right in my
.asd file). then load up my
source file. And, finally, I have one less way of screwing up my image.
I added a new tag to try and round out the blogging feature for Instiki. Here's the tag:
You can see its effect on the right-hand side of the page. Its output is shown below the "Blog Archive" header. I've submitted a patch to the Instiki project.
I started using Instiki for gnufoo.org. I've used it on past projects. I really like its simplicity and aesthetic. Building out a site using a wiki, especially for my side projects, just seemed to fit with what I wanted to do. I also wanted a blog component though. I looked for some hybrid wiki/blogs out there. I didn't find anything that stood out. (I didn't do an intensive search, so let me know if there are some goods ones I missed.)
I created a blogging feature in Instiki to suit my needs. I didn't need commenting, so my task is dramatically easier than many full fledged blogs. I tried to extend Instiki in a way that was not intrusive and wouldn't add a lot of complexity. Instiki has a notion of categories already, so I added a new kind of include that will include a blog-like view of a given category. Categories can be added to your wiki pages with this tag:
Once you have all your "blog" pages marked, you can now include them in a blog-like form from any page with this tag:
You can see what it looks like on my HomePage.
Luckily for me, Chris Hecker emailed me back a copy of my Haskell port of his 2d physics example code. (I had lost my original copy in a hard drive crash.) I'm stoked. The thing that I thought impressive about the port is that it worked well in Haskell and that it was useably fast. I expected to have to do some hand coding of strict evaluations, but it never came to that even in my extended version which handles polygons of any sort or my attempt at articulated bodies. Here is the project page for physics2d.
My first project that I'm erecting from my hard drive is a modification to dynadraw. The program itself is pretty old. I first saw it on BeOS. It draws with a kind of calligraphic-style I think. I modified it to morph between various images. I call it dynamorph. I hadn't released it because the code I based this version off of didn't include a license. I tried to contact the author twice, but he never responded, so I'm releasing it now just so I don't lose it if my hard drive ever crashes.
It's incredible how useful it is to release information if only for the selfish gain of I'll know where to find it. Trying to find something on my hard drives, CDs, or DVDs is a total pain. If I post it online though, I know exactly where to look for it. I can't recall how many times I've gone to the macosx page to grab the file and set up my keybindings on Mac OS X properly.
I decided to redo my site and use a wiki in the backend to make it easier for me to publish stuff. I ceased updating gnufoo.org because it was too much of a pain. I've left the old stuff in place so the links don't rot. I had trouble trying to decide between putting up a blog or a wiki. I decided to go with the wiki for now, and maybe I'll integrate it with real blogging software later.
I have a couple projects lying around that I never released. Crap. One of my projects was a port of Chris Hecker's 2D physics example from C++ to Haskell. But I just found out I lost the clean copy when my hard drive crashed. I do have a later copy, but it has a lot of changes and isn't a straight port. I sent Chris Hecker a copy. Maybe he still has it. I did the port as an exercise to learn Haskell. It performed well despite the fact that I didn't do any performance tuning or add any strict evaluations.