4 ms·
A minor nitpick: ICs don't give that much benefit in monomorphic languages like scheme.
by bjoli 2y ago
A minor nitpick: ICs don't give that much benefit in monomorphic languages like scheme.
- sitkack 2y agoCouldn't PICs and monomorphization be seen as duals? They are both solving the problem of how to make polymorphic code have fewer branches.
- pizlonator 2y agoPICs are the core mechanism of monomorphization in the VMs that do it
- sitkack 2y agoI was thinking of static monomorphization as in Rust.
- pizlonator 2y agoBut then there isn't a duality. If your language is static enough, then static devirt is profitable enough that you can stop there. If your language is dynamic enough, then PICs are the main driver of devirt. (Though all PIC-based systems couple that with static analysis and that static analysis is powerful enough that it can sometimes devirt without the PICs' help.)
- sitkack 2y agoI meant "dual" in the analogous sense, not as strict mathematical duals where one could replace the other. That both are solving devirt from opposite ends. I read @bjoli's comment with the analogous connotation. Your last sentence, would be if Rust used a PIC to optimize calls to dyn Traits?
- kannanvijayan 2y agoApologies if this response seems aggressive - this is just a topic I'm very passionate about :) I think technically in languages like scheme, the opportunity would be to optimize other sorts of dispatches. The classic dispatch mechanism in scheme is the "assoc" style list-of-pairs lookup. In this case, the "monomorphization" would be extracting runtime information on the common lookups that are taken. This is doable in a language like scheme, but it requires identifying parts of data structures that are less likely to change over time - where it makes sense to lift them up into hidden types and effectively make them "static". Imagine if you could designate particular `(list (cons key value) ...)` value as "optimizable" - maybe even with a macro/function call : `(optimizable ((a 1) (b 2) ...))` This would build a hidden shape for the association's "backbone" and give you back a shaped assoc list, and then you would be able to optimize all uses of `(assoc ...)` on lists of that kind in the same way you optimize shaped objects. A plumbing exposed version of this would just let you do `(let my-shape (make-shape '(prop1 prop2 ...)))` and later `(my-shape '(1 2 ...))` to build the shape-optimized association list. It's kind of neat when you realize that almost everything the runtime type-inference regime in a JIT compiler does.. is enable eliding lookups across data structures where we can assume that some part of that data structure is "more static" than other parts. In JS that data structure is a linked-list-of-hashtables, where the hashtable keys and the linked list backbone are expected to be stable. But the general idea applies to literally any structure you'd want to do lookups across. If you can extract a 'conserved shape', you can apply this optimization.