628 karma · joined November 13, 2021
Yep, SBCL does range analysis and can do inline fixnum or unboxed arithmetic.
> had mentioned to someone that the "prose" of then current programming languages was lower than a cocktail party conversation, and that great progress would have been made if we could even get to the level of making "smalltalk".
Read tables and reader macros are used in the reader, which is separate from the compiler. The compiler macroexpands normal macros though.
> what subsets are implemented before the rest
There are no obvious subsets in Common Lisp - see Baker on the matter <https://www.plover.com/~mjd/misc/hbaker-archive/MetaCircular...>.
SBCL is mostly written without CLOS and then brings in a CLOS implementation late into bootstrapping; that of course prevents you from using CLOS in some places, so you may not want to do that though.
> is there any implementation guide on how a Common Lisp is/should be implemented?
You could do a lot better than the existing Common Lisp implementations, especially in compilers and GC, but the issues there are not specific to Common Lisp.
This can be done by a program called a compiler. There are many compilers for Lisp.
(In other words, the same argument applies to every language ever which doesn't exactly correspond to machine code.)
I joke that the parallel GC is bringing SBCL to 2000s Java. It seems comparable enough to Java's Parallel, though SBCL aims for less space overhead by default, so you need to adjust either GC to have a fair comparison. The concurrent one is based off a collector for SML#, Haskell has a similar low latency "Alligator" collector too.
(Disclaimer: I wrote the parallel collector, and I want to be clear that latency and throughput differ here, because someone didn't before.)
I didn't let schooling interfere with my education.
I thought Self was supposed to be harder to optimise due to using prototypes, accessor methods rather than distinguishing instance variable access, and generally fewer other tricks. Frankly I don't know what the problem is here, but if it was a language issue, then Self should be slower than Smalltalk - you are suggesting that it'd be the other way around, and I don't see why that'd be the case.
Mario Wolczko implemented Smalltalk in Self, yielding a faster Smalltalk than the commercial offerings <http://www.merlintec.com/download/mario.pdf>. The are-we-fast-yet repo has benchmarks for SOMns (SOM modified to run Newspeak, using Truffle for compilation) which outperforms Node <https://github.com/smarr/are-we-fast-yet/blob/master/docs/pe...>.
> Otherwise it's very difficult because a block is just an object and executing it is just a method call on this object via dynamic dispatch; it's not trivial to find out what to inline
We have an object which we know everything about, because we construct it in the method. We know it's a block, and we know what #value will do, which seems like a pretty strong signal to inline. Even without knowing what blocks are, inlining #ifTrue:, #whileTrue: and such is a good move as those methods are very small.
import java.util.Random;
public class Hayley {
public static void main(String... args) {
byte[] b1 = new byte[4], b2 = new byte[2];
(new Random(0x2effe2140e00L)).nextBytes(b1);
(new Random(0xc2f0097)).nextBytes(b2);
System.out.println(new String(b1) + new String(b2));
}
}A sibling comment mentions that Smalltalk-80 played tricks with inlining some block methods such as ifTrue: and whileTrue: in the bytecode, but Self pulled nothing like that.
[0] http://www.wolczko.com/tmp/ChambersThesis.pdf#page=72
*Although maybe too careful - the important parts are that you don't inline forever, so some degree of recursive inlining is okay (and would help in the factorial example), and that you have a good reason to inline.
> Free-ing from another thread can now be a single CAS without needing sophisticated coordination between threads
which may not be the worst thing in the world; depends on what your app does.
Thread local allocation buffers?
In principle you have calls to whatever method associated with a given object, which are indirect as there is not one statically-known target of the call, but in practise you can optimise a lot out <https://youtu.be/9epgZ-e6DUU?t=2543>.
[0] https://www.microsoft.com/en-us/research/publication/deconst...