How I Know I Don’t Know Enough About Lisp Macros June 19th, 2009
Patrick Stein

I have a pretty good grasp on macros in Lisp, C/C++, TeX, m4, and nroff. Lisp macros are, far and away, the most powerful in that set. In fact, Lisp macros get a bad rap by sharing a name with macros in those other languages. Still, I often hit the same wall when trying to write a Lisp macro so I know that there’s more I have to learn.

A Quick Look at Macros

First, let’s review macros for a moment to make sure we’re all on the same page. The C/C++ macros are the simplest to understand so we’ll start there. The C and C++ compilers run in two stages. First, the C preprocessor runs to expand all of your macros. Then, the compiler runs to actually compile your code. In C and C++, macros are declared using the #define command to the preprocessor. For example, you might do something like the following:
Read the rest of this entry ⇒

Programming When Clarity Counts May 5th, 2009
Patrick Stein

In my previous post, I wrote some code in Perl because I wanted the code to be clear and obvious. Wait? What? Who uses Perl when they want clarity?

Perl

I admit: I was surprised myself. Seriously, I tried several other languages first. Let’s just focus on the first loop here. Here’s the Perl again for reference:

my $total = 0.0;
foreach my $item ( @list_of_items ) {
    $total += weight( $item );
}

Objective C

The actual code that I was attempting to explain was in Objective C with the NeXTStep foundation classes. I couldn’t imagine that anyone would want to try to understand it:

double total = 0.0;
NSEnumerator* ee = [itemList objectEnumerator];
Item* item;
while ( ( item = (Item*)[ee nextObject] ) != nil ) {
    total += [item weight];
}

C

My first attempt for the article was to write it in C using an array of items.

double total = 0.0;
unsigned int ii;
for ( ii = 0; ii < itemCount; ++ii ) {
    total += weight( itemArray[ ii ] );
}

That’s not too terrible. There is, however, a great deal of syntax and code devoted to handling the array including an extra variable to track its length. Beyond that, the loop counter is of little use to someone trying to understand the concept.

C++

My next go was C++. My hope was that iterators would make the looping less painful. C++ iterators, however, are the very model of pain.

double total = 0.0;
std::list< Item* >::const_iterator it;
for ( it = itemList.begin(); it != itemList.end(); ++it ) {
    total += weight( *it );
}

This requires the reader to wade through a syntactic thicket to get the iterator into the picture at all. It also requires a certain comfort with pointers that one wouldn’t have coming from another language.

Java

My next attempt was Java. I hate Java. It may not be terrible for this code with the new looping constructs that came in Java 1.5. Alas, I quit coding it before I made it through this first loop.

Lisp

Of course, I wanted to code this in Lisp:

(let ((total (reduce #'+ list-of-items :key #'weight)))
   ...)

That would be perfectly clear to someone who has used Lisp or Scheme. Alas, not everyone has.

So… Perl…

If you want to write the Perl code, you have to understand the difference between scalars and arrays. To read the code, however, you don’t have to grok that distinction to see what’s going on. I didn’t try it in Python. Maybe it would be clear to a wider audience. I may have to try it next time.

Sapir-Whorf with Programming Languages February 12th, 2009
Patrick Stein

I’ve been coding in Objective-C for a month or so now. It is interesting (in a Sapir-Whorf sort of way), how the language changes the way that I code. Switching from Objective-C to Lisp made me notice something that I hadn’t really noticed when moving from C++/Java/Perl to Lisp.

In Lisp, I will pull something out into a separate function if it makes the current function more self-contained, more one idea. In C++, I will only pull something out into a separate function if I need the same functionality in multiple places.

Actually, it’s even worse than that in C++. For stuff that is less than six or so lines, I might maintain it in several functions. Or, if I’m using some Literate Programming tool, I will just use the same chunk in multiple places. The notable exception in C++ is when I want to use something as a loop conditional, I may bother to break it out into its
own function:

while ( incrementCounter( cntr, min, max, dimensions ) ) {
    // body of loop here
}

In C++ or Objective-C, I might do something like this:

// some portion of my function

unsigned int choice = random() % length;
void* currentChoice = options[ choice ];
    // yes, I know I can memcpy(), but that's not as obvious
for ( unsigned int ii=choice+1; ii < length; ++ii ) {
    options[ ii-1 ] = options[ ii ];
}
--length;

// some code using currentChoice

In Lisp, I would never consider keeping that code inline. I would put it in another function right away.

This, this is one of the things I meant when I said Lisp is just plain fun. It’s easy to make a new function. I can just do it. I don’t have to fret too much over the name. I don’t have to fret too much over the argument
list. I don’t have to pre-declare it in this header file with the same signature as that implementation file. I
don’t have to pretend its a method when it’s really just a function. I can return multiple values if I need to do so. I don’t have to worry much about which compilation units will need to see this to compile.

Part of the maze generation code that I wrote in Objective-C needs to track walls. I don’t need the same structure during generation that I will use once it’s generated. So, I have a Wall class declared. It feels wrong to declare it right in the header file for the Maze. It feels silly to break it out into its own header file. What I should be doing is making a separate MazeFactory and have its implementation include the declaration of this Wall class. But, that is such overkill here. I just want the darn maze.

In Lisp, I would just be done with no feelings of guilt at all.

First decent images from my new raytracer September 25th, 2008
Patrick Stein

Some time ago, I wrote an n-dimensional raytracer in C++. It does a fair number of things, none of them efficiently, most of the rigidly.

There are a bunch of things that I wanted to do with it for a long time, but it’s been too slow and rigid to make any of those things fun.

Enter Lisp. As soon as it made it through my skull that Lisp is actually compiled (honest-to-goodness your-CPU instructions), I wanted to rewrite the whole thing in Lisp. I have finally gotten started on doing that. And, I just made it to the point where I’m actually tracing rays. Here is a stereo pair of a three-dimensional scene:

lrt-l lrt-r

Read the rest of this entry ⇒

rt v2.7.2007.05.17 May 17th, 2007
Patrick Stein

  • The documentation
  • The source code
  • The feature set now includes:
    • Phong shading, reflection, refraction
    • Functional textures (including textures generated by
      raytracing other scenes)
    • Cylinders (including spheres and cubes)
    • Quadratic surfaces
    • Regular polytopes
    • Halfspaces
    • Convex hulls of a sets of points
    • Extrusions of lower-dimensional objects
    • Intersections, unions, and complements
    • Different colors for k-dimensional subfacets
      of convex hulls and coxeter polytopes
  • Here are some sample images:
    • A stereo pair of slices of some 24-cells along with the input file. The vertexes (0-facets) are pink, the edges (1-facets) are dark gray, the faces (2-facets) are yellowish, and the facets (3-facets) are green.
    • Some 3-D polytopes with edges and vertexes colored differently and the input file.

 

Updates In Email

Email:

l