# 6.2 Context Identifiers

As described [earlier](https://rede.gitbook.io/a-general-introduction-to-contextual-programming/chapter-2-creating-context/2.1-organizing-data#contexts-vs.-records), a context can't maintain values of other contexts. However, it may be necessary for a context to be able to refer to another context. This can be done through an identifier that is unique to each instance of a context, called a context identifier.

The ability to identify a specific context, consistently and uniquely, particularly to retrieve from (or to verify a context within) a bucket is important enough of a concept to make it apply to all contexts. This identifier is different than any normal context value though, for the following reasons:

* In Rede, it is accessed through special syntax, using the `@` symbol preceding the context instance, such as `@some context`. Technically, this `@` is not an accessor but instead a specialized conversion from a context instance to its identifier.
* It can be used alongside a context's creation to attempt to create a context identified by that context identifier.
* It only exists for an instance after it has been accessed or when explicitly associated with the context. This prevents identifiers from taking up memory for contexts that won't use it.
* It cannot be changed for a context after the context's creation.

For a simple practical example, consider the small part of a video game implementation from [earlier](https://rede.gitbook.io/a-general-introduction-to-contextual-programming/chapter-5-abstracting-evaluations/5.1-compositions#building-a-composition). The behavior in that example was:

```
Protect Character :: enables a character identified by a shared Character Id to 
    reduce incoming damage as specified by Armor : behavior {id, armor}
    when armor(wearer id) = id?
    
    Reduce Damage :: reduce Attack damage : <attack> for {armor} before all?
        `Alter the potential attack damage based on the armor`.
```

The qualification for the behavior is comparing some kind of ID in `Armor` with an associated `Character Id`. This might not truly be unique, and the `Character Id` could have its value be changed, which may lead to many unintended side effects, considering how it is being used. This code can be updated to instead use the context identifier of `Character Id`:

```
Protect Character :: enables a character identified by a shared Character Id to 
    reduce incoming damage as specified by Armor : behavior {id, armor}
    when armor(wearer id) = @id?
    
    Reduce Damage :: reduce Attack damage: <attack> for {armor} before all?
        `Alter the potential attack damage based on the armor`.
```

It's assumed that `Armor` would have also updated `wearer id` to be of type `Id` (Rede's built-in type of a context identifier) for the comparison to work. The `Character Id` context could now just be a flag context, representing a context identifier that uniquely identifies a character for any other contexts it is associated with.

For a more thorough example, using the [earlier logging feature](https://rede.gitbook.io/a-general-introduction-to-contextual-programming/chapter-6-abstracting-contexts/6.1-contracts), consider how a specific log route could be disabled or re-enabled. There will be a few assumed changes to the existing implementation to make this example work:

* All log routes are associated with the `App State` (currently, `Console Log Route` is associated through the `Maintain Console Log Route` behavior).
* Some context is maintaining all of the log routes as `Id` values, so the following behavior's operation can be initiated with one of the `Id` values specifying the `Log Route Id` of the provided context.

With those assumptions, the example behavior and its relevant contexts can be:

<pre><code>Disable Log Route :: specifies the Id of a log route to be disabled : context
    log route id.

Enable Log Route :: specifies the Id and Type of a log route to be enabled : context
    log route id,
    log route type.

Manage Log Routes ::
    enables and disables the log routes associated with the App State: {app}?
    
    :: <a data-footnote-ref href="#user-content-fn-1">Enable Log Route  :  &#x3C;details></a>
        <a data-footnote-ref href="#user-content-fn-2">where type</a> is details(log route type),
        where id is details(log route id),
        <a data-footnote-ref href="#user-content-fn-3">where log route</a> is $type$ <a data-footnote-ref href="#user-content-fn-4">with</a> id?
            activate log route;
    
    :: Disable Log Route : &#x3C;details> for {app}
        where log routes is app &#x3C;# Log Route,
        where log route is log routes(details(log route id))?
            deactivate log route.
</code></pre>

{% hint style="warning" %}
`Type`, as seen above in `Manage Log Routes`, is a built-in type of record that Rede provides to specify a type of a construct (record, context, etc.). It can also be used to create instances of a type without specifically knowing which type. Although that instance can't really be used for anything in the immediate operation. The syntax to use a Type (or a String) as a literal type for instance creation is to surround the Type with `$`.

There is much more that can be done with `Type`, but it isn't specific to Contextual Programming, so it isn't covered in detail here.
{% endhint %}

In the operation above for `Enable Log Route`, in `Manage Log Routes`, there are a couple of convenience qualification values to improve readability and then `where log route is $type$ with id`. This line creates a new (presumably[^5]) log route of the specified type with the given context identifier. If a context is already activated for that identifier, then this qualification value will fail to be created and the operation won't be performed. The operation itself activates the new context, which effectively initializes the log route to begin outputting log messages.

{% hint style="info" %}
If the `minimum level` of a re-enabled route should be restored to the new context, assuming it was provided through `Enable Log Route`, and stored in a qualification value called `log level`, then it could be applied by changing the log route creation qualification to `where log route is $type$ [minimum level [log level]] with id`. This will attempt to set `minimum level` on the created instance, although if such a property is not available, the attempt will be ignored with the new instance still being successfully created.
{% endhint %}

The operation for `Disable Log Route` does the inverse. It defines `log route` as the context identified by `log route id`, from the composition of `Log Route` contexts that are associated with the `App State`, as it has been stated that they all will be through some other behavior. If such a log route is found, then the operation will be performed, which is to say that the log route will be deactivated, thus preventing it from outputting any additional log messages.

[^1]: Here the identifier before `::` is left empty, since it would likely be a duplicate of the context name. When a context name is expressive enough for the operation, as in this case, and an operation identifier isn't necessary, it can suffice to use this shortest form of an operation's declaration.

[^2]: These first two qualification values are purely for readability. It can be convenient to explicitly describe values of the operation in the declaration like this.

[^3]: This qualification value is necessary to create the value `log route`, since the creation can fail if a context for the specified `id` already exists, in which case, the operation won't be performed.

[^4]: `with` is a Rede keyword that associates an Id with a context that is being created.

[^5]: Rede offers ways to restrain this type to ensure it is a type of log route.
