Skip to content

Remaining design issues re: Components #519

@rjplevin

Description

@rjplevin

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:

  1. Use as a key to reference parameters and backups a ParameterDefReference (an immutable struct with a ComponentPath and Symbol rather than just a Symbol) and keep the current structure. Use ParameterDefReference to identify backups as well.

  2. 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.

  3. Drop the external_params dict altogether and add (i) a flag to ParameterDef 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:

  1. Limiting visibility to the exported data items
  2. 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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions