Remix.run Logo
a-french-anon 21 hours ago

Common Lisp doesn't use (expensive) CLOS dispatch in the core language, e.g. to add two numbers or find the right equality operator. That's one known pain point due to CLOS having been "bolted-on" rather than part of the language which makes the divide between internal (using typecase and similar) and external (generic functions) dispatch pretty ugly; and gave use the eql/equal/equalp/etc... hell.

Thing is that you need a complex JIT like Julia's or stuff like https://github.com/marcoheisig/fast-generic-functions to offset the cost of constant dynamic dispatch.

I actually had such a conversation on that comparison earlier this year: https://lwn.net/Articles/1032617/

majoe 15 hours ago | parent | next [-]

> Thing is that you need a complex JIT like Julia's or stuff like https://github.com/marcoheisig/fast-generic-functions to offset the cost of constant dynamic dispatch.

Julia is always the odd one out, when talking about dynamic vs. static dispatch, because its JIT compiler acts more like an Ahead-of-Time compiler in many regards.

In the best case, types are statically decidable and Julia's compiler just produces a static dispatch and native code like e.g. a C compiler would.

In the worst case, there are a big (or unlimited) number of type candidates.

The grey area in between, where there are a limited number of type candidates, is interesting. As far as I understand, Julia does something similar to the link you provided. Based on some heuristics it will compile instances for a "sealed" number of candidates and fallback to a fully dynamic dispatch, if there are two many type candidates.

At JuliaCon 2025 there was an interesting talk about this topic: https://m.youtube.com/watch?v=iuq534UDvR4&list=PLP8iPy9hna6S...

For the worst case scenario, Julia chooses what's in my regard the nuclear option: If the types are not decidable, it just ships the whole compiler with your code and tries again at runtime. But I guess, that's not the only possible solution. Presumably, it would also be possible to fallback to a Julia interpreter for dynamic code. That would be more similar to what JavaScript is doing, just the other way around. Instead of interpreting the majority if the code and optimising hot paths with a JIT, our alternative Julia would compile most code statically and use the interpreter for the dynamic parts.

martinflack 18 hours ago | parent | prev | next [-]

> and gave use the eql/equal/equalp/etc... hell.

You don't like those? I've always considered them a fairly elegant deconstruction of the problem domain of equality checking. DWIM languages can get very confusing when they DWIM or don't DWIM.

a-french-anon 18 hours ago | parent [-]

Where's the elegance? Equality is well defined on everything handled by those three, since they only compare the same types without doing coercion. Plus, you can't extend these to handle user types.

Which is why https://cdr.common-lisp.dev/document/8/cleqcmp.html exists, really; all the "copy-x" would benefit from the same fix, in my opinion.

psychoslave 20 hours ago | parent | prev [-]

What is CLOS in this context?

bradrn 20 hours ago | parent | next [-]

The Common Lisp Object System: https://en.wikipedia.org/wiki/Common_Lisp_Object_System

brabel 20 hours ago | parent | prev [-]

Common Lisp Object System. The language amazing version of what OOP can be.