That isn't what Bjarne means by zero cost abstractions.
It means the abstractions produce the same code as having written the same manually without the abstraction, e.g. having a class with virtual methods versus having a struct with function pointers as fields.
I interpret the term compostitonally. But CL doesn’t have zero cost abstractions in that sense either.
Take the example I mentioned. Say that you’re looping through an array of pairs of 2D vectors and calculating the dot product of each pair. In C++ you can use your 2D vector class without any additional cost. In CL you either need to remove that abstraction (and deal with flat arrays of scalars) or incur the cost of boxing.
More generally, if every object with its own methods requires a boxed representation, then that severely limits the range of zero cost abstractions that you can create. If using the abstraction requires boxing then it’s not zero cost. (If Bjarne disagrees on that point, then I disagree with him!)
Anyway, I’m sure you know all this, so I’m not really sure what point you’re trying to make here. I don’t think anyone would suggest that CL is a good language for building zero cost abstractions, whatever the precise definition of the term.
I am interested though: how would you define an unboxed array of structs in Genera's dialect of Lisp?
Your quote clearly applies to my example. You can avoid the boxing by hand coding the dot product computation over flat arrays; you can't avoid the boxing if you use a 2D vector abstraction (in CL).
I don't think so? Judging by the documentation that's just the usual option (also available in CL) to have struct fields stored in an array, list, name value pair list, etc. There's no suggestion that it would accomplish unboxing in general. I guess it is possible that if each field of the struct had the same type (say, a float), then the backing storage for the struct would be an unboxed array of floats, and an array of such structs would then come out with its backing storage as an unboxed multidimensional array of floats. But:
* I'd really want to see this actually working to believe it. The documentation doesn't make clear what would happen in this circumstance. (Time to spin up OpenGenera? Ha!)
* At best this works for structures with homogenous field types. My example of a 2D vector happens to fit that criterion, but it is also useful to have unboxed arrays of structures with heterogenous field types.
Accessors take care of reading/writing from the backing storage mechanism.
If you want to be really picky, don't forget the whole OS was written in Lisp, and even the C, Pascal and Ada compilers targeted it, and much follow the same semantics. The same folder has the manuals for C and Pascal.
And if you want to be really sure how it goes, there is the low level forms for Assembly like coding, e.g. sys:art-q, which is used to pack C structures into arrays.
(:type :array) is documented as the default. So there must be something more required to create an unboxed array of structs than just that.
If, for whatever reason, it is important to you to persuade the internet that the Lisp dialect of a long-defunct operating system was able to define unboxed arrays of structs, then I think you should at least show example code demonstrating this. The more salient point, however, is that Common Lisp can't do this.
> Say that you’re looping through an array of pairs of 2D vectors and calculating the dot product of each pair. In C++ you can use your 2D vector class without any additional cost. In CL you either need to remove that abstraction (and deal with flat arrays of scalars) or incur the cost of boxing.
Or maybe use compiler macros to remove the abstraction without the cost of boxing?
Here is the relevant paragraph from Stroustrup, B (2013): The C++ programming language, 4th edition. Pearson Education, page 10:
"What you don’t use you don’t pay for. If programmers can hand-write reasonable code to
simulate a language feature or a fundamental abstraction and provide even slightly better
performance, someone will do so, and many will imitate. Therefore, a language feature and
a fundamental abstraction must be designed not to waste a single byte or a single processor
cycle compared to equivalent alternatives. This is known as the zero-overhead principle."
I don't know who came up with "zero cost" abstractions, but it's wrong since there is no zero cost. For the people chanting "zero cost" the cost might not be obvious though.
It means the abstractions produce the same code as having written the same manually without the abstraction, e.g. having a class with virtual methods versus having a struct with function pointers as fields.