Conversation
|
Does this make linking to external primitives less "weak"? I believe that today, one can link against a module with some external primitives without requiring to link an implementation for those primitives (if the primitives are never called or used indirectly). |
|
Yes it does. That required some changes to the testsuite. Do you know if anyone uses that for anything? I also adjusted the rules for when using an external forces linking. Previously it did not apply for builtin primitives, which seemed pretty arbitrary. It would be easy to put it back though if people insisted. |
I'm not aware of any specific use, but I wouldn't be surprised that it's used in the wild, perhaps not deliberately; and probably in contexts which would be easy to fix, but perhaps not. |
|
I seemed to remember that we changed something about uses of |
|
I think that was the flip-side of what @alainfrisch is describing: you could use the external primitives without linking the module. |
|
|
I tried this PR on opam packages and it fails on jbuilder with a compiler fatal error: I get this on all jbuilder versions between 1.0+beta9 and 1.0+beta16. It seems that no other package (that currently compiles with trunk) is impacted. I'll try to dig a little deeper. |
|
Having a stack trace of the compiler failure would be nice. (This looks quite like the jbuilder error due to pattern matching changes, which could still be present in this PR if it targets a version of trunk that is buggy in this way and has not been rebased since.) |
That indeed seems to be the case. |
|
The exception is raised by the anonymous function passed to |
|
Update: full opam log: |
b23cf73 to
2675597
Compare
|
1.5 years later, any news about this PR? For the record, I'm neutral about it: it does simplify the compiler internals, but we lose some opportunities for type-based specialization of primitives (and there are not enough such opportunities already...), and the "no breakage in OPAM" check is unconvincing and needs to be run again. |
|
I'm fairly neutral on this change now myself. I now believe that this sentence from my description:
is not really true, which makes me much less interested in it. |
|
OK, thanks for reply. Since there is no longer much interest in the proposed change, and since it has some potential for breaking existing code (by requiring more libraries to be linked), let me close this PR. |
Currently
externalcomponents of a module do not appear in the runtime representation of the module. This means that when coercing anexternalto aval, as in:we must insert an eta-expansion of the
externalinto the module. It also means that all references to anexternalthat are not direct applications cause a fresh eta-expansion of theexternalto be generated.This PR implements a different scheme. We treat
externalcomponents much likevalcomponents -- they are ordinary fields of the module at runtime containing an eta-expansion of theexternal. This means that module coercions do not need to considerexternalcomponents. It also means that most uses of theexternalthat are not direct applications can just reference the field of the module.Note that direct applications of
externals will still be compiled to direct applications of the corresponding primitive. Similarly, uses of builtinexternals which can take advantage of type-based specialization will still generate a fresh eta-expansion so that they use the most efficient version of the primitive available.The advantages of this new approach are:
externalThe main disadvantage of the new approach:
externalwere changed toint -> int -> boolthen the new scheme would also use integer equality. Similarly, if the types were not changed until a later coercion then the old scheme would have used generic equality.Note that this PR is rebased on top of #1557 so reviewers should ignore the first commit.