Sunday, December 13, 2009

Lisp C preprocessor

In my daily job I program in C++. It has been that way for 10 years and it looks like it will be that way for 10 more years.

I understand c++ quite well but there are aspects of the language I find quite tedious. Actually, look, I don't really care to justify my design decisions. I am going to attempt to write a lisp-like language that generates C.

Hopefully I can make it enough like C that the parenthesis-to-bracket compilation is cheap and fast. I would also like to take some stabs at what I believe are C's largest problems but I need help because this is really tough and I want to incorporate more ideas from other people.

So, to cut to the chase:

The point first and foremost is to allow writing C code at a higher abstraction level. I want to write:

(let [sum (reduce + 0 (int-array 1 2 3 4))]
(cout sum))


I want this to compile down to:


{
int __temp[] = { 1 2 3 4 };
int sum = 0;
for ( int __idx = 0; __idx < 4; ++__idx ) sum += temp[__idx];
cout << sum;
}


and given:


(let [sum (reduce + 0 (std-vector int 1 2 3 4))]
(cout sum))


I want to see:


{
std::vector<int> vec( 4 );
vec.push_back( 1 );
vec.push_back( 2 );
vec.push_back( 3 );
vec.push_back( 4 );
int sum = 0;
for( std::vector<int>::const_iterator __temp1 = vec.begin(),
std::vector<int>::const_iterator __temp2 = vec.end();
temp1 != temp2;
++temp1 ) sum += *__temp1;
cout << sum;
}


Furthermore I want to be able to define a reduce like function. Or a map function (with the result provided as an argument; !no malloc assumptions!). You can't do this in either c++ or in c for several reasons. The first and foremost is that in some senses you can but defining closures is incredibly painful and tedious. Or you can use boost::bind and watch your compile times go through the roof (why would you need to compile + test frequently anyway?).

So, anyway, this is my theory. The language doesn't really matter. Look at what people have done with Factor. Basically, *you* are the compiler with Factor; it is essentially a really sophisticated assembly language. As is Lisp, as is C, as are most languages that don't have true abstract datatypes or some of the other abstractions that functional languages have.

The ease of abstractions and the level of abstractions you can created are what matter.

I need to be able to abstract over types like the templating system of c++ kind of allows you to do. I need to be able to write a compiler-level foreach definition that can be extended for new types quickly. And then reduce simply works using the previous foreach definition.

Imagine c++ template language didn't suck and actually allowed you to do anything with the compiler you wanted to. C++ programs would become a *lot* more terse and probably much more correct. Its like being able to define you own dsl *very* quickly and efficiently and have it output to c++ code.

Then imagine a system that was designed from the ground up to make creating shared libs on any platform and using them from other languages really really easy.

Now imagine some CUDA and OpenCL bindings so you can do hardcore parallel computing very efficiently. Mated with a language like clojure you would be able to take advantage of several different levels of parallelism (machine,CPU,GPU) all very efficiently.