In the course of investigating #573, I found another bug involving defined constants. Here's an example script:
initialize() {
initializeMutationRate(1e-6);
initializeMutationType("m1", 0.5, "f", 0.0);
initializeGenomicElementType("g1", m1, 1.0);
initializeGenomicElement(g1, 0, 99999);
initializeRecombinationRate(1e-8);
defineConstant("homozygous", 1:5);
}
1 early() {
sim.addSubpop("p1", 50);
}
mutationEffect(m1) {
if (homozygous)
return 0.0;
return effect;
}
20000 late() { }
The defined constant homozygous conflicts with the pseudo-parameter homozygous, and the local pseudo-parameter shadows the global defined constant. That is not the end of the world – it's better than if it were the other way around! – but according to the scoping rules it should not be allowed.
The question is, when should an error be raised about it? On entry to the mutationEffect() callback would be the logical spot, but I don't want to slow down the callback mechanism with checks like this; it needs to be as fast as possible. So the check needs to happen earlier. I think what needs to happen, actually, is that an error gets raised at the defineConstant() call, that homozygous has been reserved by the Context (i.e., SLiM) for its own use, and so it cannot be used as the name of a defined constant. Then SLiM can reserve all the names it uses, and this conflict is avoided. That's a little over-aggressive, since the homozygous is reserved even if the script doesn't contain a mutationEffect() callback, and so a conflict would never actually occur; but it seems better to just prohibit it, rather than have a script with homozygous work fine until such time as the user adds a mutationEffect() callback, and then suddenly the use of homozygous errors; that would kinda feel like "spooky action at a distance".
In the course of investigating #573, I found another bug involving defined constants. Here's an example script:
The defined constant
homozygousconflicts with the pseudo-parameterhomozygous, and the local pseudo-parameter shadows the global defined constant. That is not the end of the world – it's better than if it were the other way around! – but according to the scoping rules it should not be allowed.The question is, when should an error be raised about it? On entry to the
mutationEffect()callback would be the logical spot, but I don't want to slow down the callback mechanism with checks like this; it needs to be as fast as possible. So the check needs to happen earlier. I think what needs to happen, actually, is that an error gets raised at the defineConstant() call, thathomozygoushas been reserved by the Context (i.e., SLiM) for its own use, and so it cannot be used as the name of a defined constant. Then SLiM can reserve all the names it uses, and this conflict is avoided. That's a little over-aggressive, since thehomozygousis reserved even if the script doesn't contain a mutationEffect() callback, and so a conflict would never actually occur; but it seems better to just prohibit it, rather than have a script withhomozygouswork fine until such time as the user adds amutationEffect()callback, and then suddenly the use ofhomozygouserrors; that would kinda feel like "spooky action at a distance".