I’ve recently gone back to learning Lisp. I used it a little bit in graduate school to do some homework assignments in one of my algorithms class and learned some of the basics there, but since I started my professional career, I haven’t gone back to it at all until now. I got Paul Graham’s book On Lisp and have made my way through several chapters, and it’s quite enjoyable.
One thing I keep noticing is how similar Lisp and C++ are. Many Lispers, of course, would regard this as heresy, but to me it makes perfect sense. For example, take this passage from the book:
Many languages offer some form of macro, but Lisp macros are singularly powerful. When a file of Lisp is compiled, a parser reads the source code and sends its output to the compiler. Here’s the stroke of genius: the output of the parser consists of lists of Lisp objects. With macros, we can manipulate the program while it’s in this intermediate form between parser and compiler. If necessary, these manipulations can be very extensive.
Of course, the two languages aren’t exactly the same in this regard. C++ templates can’t be manipulated in the same way first-class C++ expressions can be; they are powerful, but really only give you full control over the type system. Being able to say lots of things about types in C++ will get you a long way, but not as far as Lisp macros will get you. Still, the similarities I think are striking, especially considering some of the newer techniques that have been discovered with C++ templates that let you go a bit beyond just the type system by doing some really obscure things with types.
A number of other similarities I think are significant; Lisp and C++ are the two languages with the best multi-paradigm support to which I’ve been exposed. Lisp tends to tilt functional, while C++ tilts procedural, but they both support all the major programming paradigms to practical degrees (although, to be fair, it would be easier to write an entirely procedural and/or object-oriented program in Lisp than it would be to write and entirely functional program in C++).
Anyway, just blurting some thoughts out loud while reading On Lisp.
Sutter just announced that C++0x will have support for lambdas and closures.
It looks from the N2550 report that these things are motivated by a desire for some syntactic sugar to make using STL algorithms easier (which is understandable), but I hope this will lead to more first-class support for the functional programming paradigm. It has long had support for function objects, but it would be difficult to write predominantly functional programs in C++. I hope it just got a little bit easier.
My question(s): will these lambdas be serializable? In Lisp, there are a couple of ways you could ship around a closure. Ultimately, if you really wanted to, you could express the lambda as a regular list, transmit it, and then call “compile” on it. Since C++ doesn’t have a built-in way to write and compile code from within the language itself, it will have to be somewhat different (or maybe it’s time to start writing a functor serializer for the boost library).
I am a huge C++ aficionado, and this news excites me. A comment over on news.yc captures my sentiments pretty well:
Lambda functions and closures in C++. E-gads man! Wasn’t the language complex enough already!
I have to say: I love it. C++ has always been my favorite language that I don’t program in. It’s like kung-fu for programmers. You can attack any problem. But most times we don’t need kung-fu.
There’s nothing like “getting in the zone” with a good C++ program. It’s a thing of beauty. And if you’re doing stuff that you have to use the tool, like writing drivers, low-level stuff, doing some “break the rules” programming, it’s the best there is. I wrote a shell extender for windows many years ago in C++. I got to change the desktop and file system to work the way I wanted it to. Very neat stuff.
The sad fact is that most of the time you can make more money writing something with a much higher level language. And you can make it faster and adapt to the market faster. So C++ is a tougher language to use for startups, in my opinion (although it is still my favorite)
Can you imagine the trouble you can get into with macros, lambda functions, and unsafe pointers? How about throwing i some operator overloading? It’s like a playground for nuclear weapons.
Tags: C++, programming
In my last post, I kinda whined about the awkwardness of the Gtkmm API. At least, it seemed that way at the time. I toyed with libglade and Gtk+ for a while first and everything seemed very straightforward and easy.
Gtkmm and libglademm are different. They seemed awkward at first, but after further investigation, I like their designs much better, and the advantages presented by C++ seem obvious. One of my primary objections was that it didn’t seem that I could hook up the default signal handlers because they were made protected members of the widget classes. At the time, it seemed to me that the only way that the default signal handlers could be used at all was by deriving classes and overriding the handlers (which are virtual, by the way). I have since discovered that the default handlers are connected by default. Also, the “slotting” mechanism used for signals — whereby signal handlers can be chained together and all executed on a single event — is pretty nifty.
Speaking strictly of Gtkmm, this doesn’t seem so bad, but I was using glade to put my UI skeleton together, and I very much liked the idea of dynamically building your UI from an XML file at program startup, rather than coding all the tedium that goes along with UI development. I also prefer C++ to C whenever possible (actually, I prefer C++ to any other language whenever remotely appropriate), which is how I got here in the first place. Anyway, glade-2 — in my opinion — isn’t very good at dealing with “custom widgets”, which includes widgets that are derived from and substantially the same as the stock widgets. One caveat I should include here is that I haven’t really gone through this whole process with glade-3 yet. Maybe it’s better. I don’t know.
Offhand, I’d say one thing that could be better in glade-2 is if, once you placed some stock widget, you could edit the classname and let glade-2 assume that the user-entered classname is the name of a class that derives from the stock widget you originally placed. Then, maybe it could support all the properties of the original widget, but actually use your derived widget at runtime when the UI is built. This would be pretty much what I want, because thus far, the only use I have for writing custom widgets is to override the default signal handlers.
Tags: C++, glade, gtk, programming
Ever need to set up a quick and simple debug/logging stream for your application without having to deal with large frameworks like log4cpp or *shudder* log4cxx? There’s also libcwd, which seems really neat, but also very large.
I didn’t want to use all that. I just needed a simple way to filter my output using streams without having if(…) blocks scattered all over the place. Here was my solution (I can’t remember if I came up with this on my own, or pawned it from someone else…if nothing else, I at least used the reference documentation for the boost Iostreams library). Read on to see what I did.
(more…)
Tags: C++, programming
I just discovered the POCO library. It’s pretty neat-looking: it has a number of components that provide functionality that goes beyond the standard C++ library, such as threading support, networking, XML reading/writing, etc. The cherry on top is that not only is it similar to boost in terms of functionality, it seems smaller, more portable, and more easily targeted for embedded systems. Great, right? Read on…
However (begin rant), the style of the library really turns me off. Hugely. I haven’t even read all of the style guide (which is somewhat oppresive), but two big things I discovered right away:
I suppose tabs being used in the sources is pretty inconsequential for normal users of the library – although its annoying just to know that they exist.
The naming conventions though, are another animal altogether. Some of you reading this might be thinking to yourself “Holy cow! Who cares? Don’t sweat the small stuff!”. With most things, I am inclined to agree, but not on this.
Conventional style for a particular programming language is usually either defined or employed by its standards and standard libraries. This is true of Java, C, C++, C#, PHP, Scheme – you name it (there may be exceptions), and it also goes for indentation, brace placement, spacing, etc, etc, although I’m mostly concerned with naming here (everything else can be fixed by indent scripts if necessary). Take C for example. The standard C library uses almost all lowercase names, and those names tend to be brief (abbreviated if necessary), like ’strncpy’ or ‘memset’. Structures tend to be named similarly: ‘pthread’ and ‘fileattr’, which sometimes get typedef’d to ‘pthread_t’ or ‘fileattr_t’ so that it’s clear you’re using a data structure. Most systems’ libc uses this style as do other POSIX-related libraries. Products like WindRiver’s VxWorks that deviate drastically from this convention (WindRiver in particular basically just made up their own style – to heck with convention; Microsoft was almost as bad) are an abomination to code consistency and elegance.
C++ also has its own style – the standard library (also – incorrectly – known as the stl) exhibits this. Names are typically longer than in C and multiple words are typically separated by the underscore character rather than abbreviated, although abbreviations are appropriate sometimes to keep lines from getting too long. class names are not capitalized except in the rarest circumstances. Namespaces should be used and follow the same guidelines for naming.
Why is this important to me? It’s important because you want your code to have a consistent visual style. Much of the style can be pretty arbitrary, and that’s fine. Brace placement and the width of your indent are less important to me. Even if you don’t like the way someone else chooses those elements of style, they can be changed pretty easily. Naming is not like that, and choosing non-standard (or non-conventional, if you prever) naming makes code harder to read and maintain. When I write C++ code, I want it to all look as much like the standard library as possible, with few exceptions. Then, when I want to use a library like POCO, my coding style is all blown to heck because somebody over there decided to make their own rules. Microsoft is probably the primary guilty party in this respect because of the style they chose for MFC and the ATL, as well as the Win32 API.
POCO is even internally inconsistent. On their website, they state that they have goals to:
Choosing to not reinvent implementations that work but also to ignore the conventional style (like Microsoft did) are contradictory.
Anyway, this isn’t to say that POCO shouldn’t be used. I’ll probably use it sometimes. I was just *very* annoyed by C++ code that uses the camel-case naming style.
Tags: C++, programming
This article is a really great way to start understanding STL containers. It discusses the differences between a vector and a deque (a double-ended queue) (you’ll often see C++ rookies as “what’s the difference between vector and queue” or something like that, and the answer is usually “if you have to ask, just use vector”. That is an insufficient answer for a lot of people, and this article addresses it nicely).
The long and short of it is that a vector represents a sequence of elements that are accessed in “random” fashion; not meaning that you access the elements randomly, but merely that you need to be able to access an element at any position in the list. This type of usage lends itself to a different storage structure and allocation strategy than does a queue, which is a sequence from which only the ends are accessed.
A good read.
Tags: C++, programming
I’m sure I’ve blogged about this before. I just don’t know where.
It drives me nuts. In what other languages, other than C and C++, is it acceptable to totally ignore the style that the standard uses? In Java, the “standard” is the Java API written by Sun. Everyone, and I mean everyone who writes Java uses that style or they are a laughingstock.
The same goes for lisp. The same goes for PHP. The list could go on and on.
But C++? Well, what the hey! Microsoft writes its code a certain way, so that must be an acceptable style, no? Arrrgggghh. The style used by K&R, Stroustrup, and the standards committee is nothing like what Microsoft (and consequently, thousands of programmers) use on a regular basis, and it drives me batty.
In C, names should be brief and descriptive, generally one word or multiple, abbrieviated words. Everything should be lower cased, except for preprocessor macros, which should generally be capitalized.
In C++, names should generally be more descriptive, and words should be separated by an underscore character (i.e., ’special_vector’ or ‘address_table’). This includes classes, which people sometimes use the Microsoft style, which is *wrong*. Of course, style is arbitrary and not actually defined in the standard – but convention in most languages is generally to do things like the standard library does it, and Microsoft does not do it like the standard library does it. The same rules apply to preprocessor macros.
If I never see a class with camel-case styling again it’ll be too soon.
Tags: C++, programming
I have written a threaded timer that will start on command, and stop on command using the boost threads library. here’s the code:
/* copyright Benjamin Collins 2006 * please contact for licensing information */ #include <iostream> #include <boost/thread/condition.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/recursive_mutex.hpp> #include <boost/thread/thread.hpp> #include <boost/thread/xtime.hpp> typedef boost::recursive_mutex::scoped_lock rt_slock; namespace { bool _start = false; boost::recursive_mutex start_mutex; boost::condition start_condition; bool started() { return _start; } void start() { rt_slock lk(start_mutex); _start = true; } void stop() { rt_slock lk(start_mutex); _start = false; } } class timer_func { public: timer_func() { boost::xtime_get(&_time, boost::TIME_UTC); } void operator()() { while(true) { { rt_slock lk(start_mutex); start_condition.wait(lk); } while(started()) { _time.sec += 1; boost::thread::sleep(_time); if(started()) std::cout << "." << std::flush; } } } private: boost::xtime _time; }; int main() { timer_func timer; boost::thread t(timer); while(true) { if(!started()) { std::cout << "press enter to start: " << std::flush; std::cin.get(); start(); std::cout << "starting" << std::endl; start_condition.notify_one(); } else { std::cout << "press enter to stop: " << std::flush; std::cin.get(); stop(); std::cout << "stopping" << std::endl; } } return 0; }
Tags: C++, programming