Open davidorme opened 9 months ago
I was following the argument well until I got here:
That seems super clean and simple but we then have the core constants multiply defined independently in each model constants class - they shouldn't differ but why would we even open up the possibility?
How is that possibility open? Core constants will be defined using ClassVar
, like in https://github.com/ImperialCollegeLondon/virtual_rainforest/blob/dd41f744e6177151e9e7c1b51ffb9ebe78904622/virtual_rainforest/core/constants.py#L21
So even if the constants are multiply defined, the core ones will be the same. By construction, they cannot be changed.
Did I miss anything?
Not all core constants are necessarily defined using ClassVar
- there may be core constants that users can sensibly alter. My concern here is that in theory, users could get models with different core constants, but looking back, that is extremely paranoid:
vr_run
I think the more compelling argument is that it is just needless duplication.
As we all know, in Python, if a user want to change something, there's absolutely nothing that can prevent that. But beyond certain reasonable cases, if a user changes something they should not and that results in useless results, to be honest, they deserve it.
On your last point, needless duplication does not sound too compelling to me if you sacrifice simplicity. For me needless duplication is having to keep two separate sets of constants. That makes the interface more complicated - not super complicated, just a bit more complicated. If the risk of having inconsistent set of constants is as small as you suggest, I honestly would go for the super clean and super simple
approach you have come up with.
I agree about users deserving what they get in those cases π
I think there is a cost to simplicity in what we would need to do to load_constants
to merge the currently separated config namespaces for core and model constants. In the meeting, I think @vgro , @jacobcook1995 and I generally agreed that having two constants namespaces was a mild complication we were happy to live with?
Beyond the handling of core constants, though, the approach for the meta constants seems sound?
Yes, that looked sensible, considering the problem to solve. I guess one potential difficulty might be finding the common constants that should go in the Meta model, but maybe I'm seeing a problem where there is none.
This is a cross between a meta-issue and a discussion to tidy up a backlog of constants questions that we've grouped in the "Constants system" milestone.
This issue is also a summary of the inaugural monthly "GitHub issues" developer meetings to bundle existing issues and clean them up π π₯
Where we are now
CoreConstants
andModelSpecificConstants
and whether it might be easier to merge core constants into each model constants to provide a simpler namespace (see #342).Outstanding issues
We have five outstanding constants issues:
129 is about creating core constants but contains still relevant discussions about units. We have a separate milestone bundling units issues so I think we can simply close #129.
277 is about how we ensure that configured constants are passed down correctly rather than falling back to defaults. I think this is largely outdated now that we are using the constants system, so I think we can close #277.
348 is still active and just needs a PR to redefine constants values through the models.
The remaining two issues are linked and this PR suggests a resolution for both:
342 is the discussion about simplifying model signatures to only need one bundled constants class. Implementations for this were also discussed in #341.
358 is an issue that @vgro had with sharing constants and functions between parallel model development: if a function using constants is defined in one model then currently importing and re-using that function in another model requires also importing the constants and juggling multiple parallel constants classes.
Sharing constants and functionality
The proposed solution to #358 that we can define model "meta" constants classes and use class inheritance to allow the clean use of different constants classes with shared functions. So:
These can then be used seamlessly in both models - all of the statements below are
mypy
friendly because the typing ofModelMeta
supports the meta class itself and any derived model specific subclasses.Merging core constants into models - we could but no
That solution also opens up this resolution for #342 - which seems really clean and avoids the whole issue with properties that was mentioned on this topic in #341.
And hence:
However, the dev meeting concluded:
Config
, but we should simply create one instance at startup and share it through the model signature somehow. We could addcore_constants
to the ABC signature.So - we should simply close #342 and live with having two constants classes.