Repository navigation
Specifications: Avoiding name conflicts
This article describes a proposal of API change for the framework.
If you already know about what motivated this change and the technical aspects related to it, you can directly jump to this section: Situations of conflict
What do we want to address?
As motivated by the issue #216, we decided to limit name collisions between user content and framework content.
In this particular example, the framework automatically adds temporarily the name event inside the current execution environment's namespace associated to the call of the custom event handler. This name references the native event object created by the execution platform. This makes accessing this object possible, which is an important feature. However, this also shadows any other potential name having the value event, making them unreachable.
We call that name masking or in some cases variable shadowing, which is the case where the execution still occurs but does not work as expected.
There are other similar cases where the execution cannot even occur, we call them: name collision, name conflict or even name clashing.
Both cases require the same workarounds.
What we want is to limit the impact of such behaviors on name masking or collision.
The following describes the term as used in the rest of this document.
- namespace: a collection of names. This collection is specific and is a map of strings. This implies many things, like uniqueness. Note that the use of namespaces can be made in different ways, such has using a chain of namespace (with precedence for lookup) and so on.
- platform: the underlying system, or call that (virtual) machine, on which a program is executed.
- environment: the state of the platform at some point of execution. A notable thing is that this state usually contains a namespace.
- name conflict: in this document we will use this term interchangeably with name masking, variable shadowing, name collision, name clashing. A conflict means that it is not possible to use the same name more than once in some context, whether the execution cannot occur or occurs with semantic errors.
There can be several techniques to limit or even completely avoid name collision, quickly recapped here:
- limiting: if several names belonging to different semantic groups are kept inside the same namespace, the collision cannot be avoided. But it can be limited by using naming conventions. One of them is the use of prefixes and/or suffixes, usually with special characters (if/as allowed)
- avoiding: by putting each semantic group of names inside its own namespace. In practice, this would imply creating additional levels of nesting, which can be cumbersome. Also, in some cases it's not always doable, when some names belong to different semantic groups in some context but are considered semantically the same in an other. In this particular case, creating an additional namespace would imply sacrificing one name at least, in order to reference one of the new namespaces.
Our choice is to prefix names belonging to the internals of framework with the character $
What does the issue apply to?
Name conflict occurs when names belonging to different semantic groups are put inside the same namespace.
In our case, we have two semantic groups that we want to distinguish, which are:
- the framework API
- user code
To know what to change, we need to determine two things:
- what are the different possible namespaces, technically
- in which situations a namespace can include those two semantic groups
Our programming system is JavaScript, in which there are only two different kinds of namespace:
- objects: properties inside objects are named, and the object constitutes the namespace (by the way we can see a technique to reduce name collision with the now deprecated property
__proto__, by surrounding the meaningful part with underscores) - execution's environment namespaces (often improperly named scope): this is where variable/reference names are put
Additionally, our platform and framework makes use of HTML, in which there are the following namespaces:
- elements
- elements' attributes
-
specific main HTML elements: we use standard elements to include templates and JavaScript code (respectively
templateandscript) -
statement names: the set of statements cannot be extended by the user
-
properties of the objects passed as parameter to the
klassfunction: specific properties are already prefixed, with a$moreover.Specific properties are:
However this is a case where it would be easy to use the technique of nesting to completely avoid the collision between the two first properties which are only used by the library. The third however falls in the group of the prototype properties, so only the technique of conflict limitation can be used.
-
attributesdefinitions in controller definitionsSee section below for more information about controllers. It's been chosen to prefix the property
attributes.However, this property ends up in the prototype, and the user might want to embed custom additional information inside each attribute definition.
But since
attibutesis already a property specific to the framework and is gonna be prefixed, we decided not to prefix deeper and let the user choose a free name to put its own namespace (object) if needed. -
properties of log entries
Indeed the way log entries are created does not allow putting custom properties in the resulting object. If ever it was possible in the future, we would let the user do the same as for
attributesdefinitions. -
custom HTML elements' attributes:
-
as spotted by the issue #216: the
eventreference injected by the framework when executing a function expression in the context of an event handler -
exactly the same use case as above, there is a reference named
scopeavailable inside whole templates -
The definition of component controllers relies on the
klassutility. The framework uses conventions to handle it specifically. That concretely means that some properties on the prototype of controllers are used by it, and they require an agreed name. However, this names are merged with the one of custom properties defined by the user.That's a situation where only conflict limitation can be used, since there is no distinction in definition and access of these properties (semantically the same from the
klasslibrary point of view, but not from its usage then - one from the framework, one purely from the user).Here are the properties used by the framework:
- potentially conflicting:
attributeson<Attribute>Changeelements-
content: this one is a bit different since it is not used inside the definition (and actually can't be), but is available as a list of instances of the elements mentioned in previous point
- already prefixed:
- potentially conflicting:
This must be applied to the following content:
- code consuming these names: the framework internals
- code produced by users and using the corresponding features by using these names:
- names matching the previous ones must be converted as well to keep the semantic
- possible names corresponding to the new names must be changed to avoid collision
Here is a list of known concrete elements to change:
- tests
- documentation
For the second point, here are additional things:
- samples
- Hashspace Bootstrap
- issue #216