-
Notifications
You must be signed in to change notification settings - Fork 35
Description
I'll try to explain these here, but it might require meeting to flesh it out adequately.
A. External params
External params are created when a parameter is set using set_param!
. Following the legacy code, the external param is named the same as the "internal" param defined in @defcomp
. This creates a namespace conflict, as multiple leaf components can define a parameter with the same name. With non-component ("flat") models, we simply avoided this issue since the modeler controlled all the components. This is no longer adequate for "third-party" components.
In the old structure, external params were stored in the ModelDef
. The current component implementation stores them in the "parent" composite object, which may be a ModelDef
or any CompositeComponentDef
. This, however, duplicates the namespace clash.
Similarly, backups
are indicated only by a single Symbol
, with potential namespace conflicts.
A few solutions occur to me:
-
Use as a key to reference parameters and backups a
ParameterDefReference
(an immutable struct with aComponentPath
andSymbol
rather than just aSymbol
) and keep the current structure. UseParameterDefReference
to identifybackups
as well. -
Move the dict of external params into the leaf component in which the param is defined, rather than in the "parent" composite. Within the component, a
name::Symbol
is unique. -
Drop the
external_params
dict altogether and add (i) a flag toParameterDef to indicate which params are "external", and (ii) a
ModelParameter` slot to store the parameter value.
The last 2 still require addressing backups
, but I like the idea of dropping the external_params
dict and using the existing structure instead.
B. Visibility of vars and params
In the current composite design, exporting vars/params serves two functions:
- Limiting visibility to the exported data items
- Renaming items referenced in a composite to handle namespace collisions
We discussed limiting visibility to exported vars/params, but it's not clear to me when this would occur. The current composite implementation allows setting params and connecting vars & params anywhere in the composite structure, if you know the full "path" to a component.
We could treat composites as essentially opaque, with only explicitly exported vars/pars visible to the "consumer" of the component. This seems potentially annoying though, if a needed data item is not exported by the component developer.
We might consider a different approach, where a composite developer or end user can define an "alias" for any var/param occurring anywhere in the composite structure, and attach these at any composite level.
This would allow an alias to a parameter :foo
in the component at ComponentPath("/top/A/B/C")
to be stored as, say, :foo_C
in any other composite. This is similar to the "export" idea except that end users can use them to reference data in pre-existing components. The user would have the option of referencing data using the full path, or via an alias.
Where exports exposed data elements only to the next composite level, aliases would allow a developer of a multi-level component to add aliases to the top level referencing data anywhere in the structure. We could add creation of aliases to @defcomposite
, allowing them to refer to anything data items below the composite, using a relative component path.