(I'd also add that there are some issues surrounding larger unboxed types, but I won't venture to posit how SBCL handles those).
But yes, it's a lot easier to write code with a GC than without one. That's true in any language.
But let's not forget that the original article was saying, essentially, "Hey, look, we can make C++ do Lispy things!". My point is just that if you want to do Lispy things it's a lot easier just to use Lisp than to try to shoehorn Lisp's features into C++.
(It does appear that SBCL lets you drop down to assembly, but again if you do that all the advantages of using LISP are gone. Anyway, what is the goal here? Do you really want to use a typed LISP with no lists, with large of featureless statically allocated memory, manually handling concurrency, mutability everywhere, inline assembly, and the inability to use even most of the C++ LISPy features because LISP has no support for using them without runtime costs? Writing a language without resorting to costly abstractions is hard and it was explicitly never a goal of LISP to be one. That's not to mention that in LISP it's nonobvious which features are costly and which ones aren't, so the abstraction it provides over hardware is only theoretical in this context).
In any LISP in a high performance context, you are always paying for things you don't use. You could probably argue that some of the above problems could be mitigated if everyone adopted SBCL as the standard, but unfortunately that's just the way it is in the real world. And while it is unfortunate, the fact is that even all the technical problems could be resolved (I have my doubts), it would be much more irritating to write such low-level systems code in LISP than in a language that wasn't so far removed from the workings of modern computer architecture.
I'm actually a big fan of Lisp and I've found it quite useful for a number of projects, but when you really need to do low-level programming, it is significantly easier in (modern) C++.
That's right. There's no such thing as a free (no pun intended) lunch.
> (by the way, writing a performant, bugfree, concurrent malloc and free is not that easy :)),
It's pretty easy, actually:
(defvar free-list)
(defun initial-malloc (n) (dotimes (i n) (push (cons nil nil) free-list)))
(defun my-cons (car cdr) (setf (caar free-list) car (cdar free-list) cdr) (pop free-list))
(defun free (cons) (push cons free-list))
The reason it's hard to write a malloc for C is that it has to manage variable-length blocks.
> That's not to mention that LISP has to interact with C on a regular basis for things like system calls, and comes with a runtime that prevents it from playing nicely as an embedded library
No, that's just wrong. There's nothing about Lisp that prevents it from being implemented as an embedded library, e.g.:
http://en.wikipedia.org/wiki/Embeddable_Common_Lisp
> You could probably argue that some of the above problems could be mitigated if everyone adopted SBCL as the standard
No, I'm saying use the right tool for the job. If you really need every last bit of speed and you don't care about safety or engineering cost then by all means use C or C++. But if you want safety, reliability, and the sort of run-time dynamism described in the original article you're better off using Lisp or its progeny.
I'm also saying that if you want performance and you also want to use Lisp, you can. But at the end of the day there are fundamental tradeoffs in computing between speed, safety, dynamism, and engineering cost that no language will save you from.