Dual Modifiers

The namespace member access control model of Jancy differs from that of most object-oriented languages.

  • There are only two access specifiers:
    • public

    • protected

  • Member access can be specified in two styles:
    • C++-style (i.e. a label)

    • Java-style (i.e. a declaration specifier)

  • The default access specifier is public – even for classes

  • Global namespace members can also have access specifiers just like named type members (and why not?)

The main difference, of course, is the first one. For each namespace the rest of the namespaces falls into one of the two categories:

  • Friends
    • This namespace

    • Nested namespaces

    • Namespaces of derived types

    • Extension namespaces

    • Namespaces declared as friends

  • Aliens
    • Everybody else

Friends have access to all the members including protected ones. Aliens can only access public members.

Admittedly, this approach definitely affords the developer a much lesser degree of flexibility in fine-tuning of who-can-access-what (other object oriented languages typically provide from three to five access specifiers).

On the positive side, this simplified binary model of friends vs aliens and opens up the possibility of dual modifiers, that is, the modifiers having one meaning for friends and another for aliens.

readonly

One of the most common elements used in virtually every program is a read-only field. A class sets and modifies a field; all users of the class can only read this field.

Conventionally this is implemented by declaring a private field and a public getter.

The implementation relying on dual modifiers looks a lot more natural, as it is compact – Jancy’s dual modifier readonly is ignored by friends and means const for aliens:

class C1 {
    int readonly mreadOnly;

    void foo() {
        mreadOnly = 10; // for insiders it's a regular field
    }
}

void bar() {
    C1 c;
    int x = c.mreadOnly; // no problem
    c.mreadOnly = 20;    // error: cannot assign to const-location
}

event

Events represent yet another extremely common programming element that requires dual access control.

The owner of an event must have the full control over this event, including the possibility of actually firing it. Subscribers are only able to add and remove event handlers.

The dual modifier event provides full multicast-access to friends and event-only access to aliens:

class C1 {
    event m_onCompleted();

    void work() {
        // ...

        m_onCompleted(); // insiders have multicast-access to m_onCompleted
    }
}

void onCompleted() {
    // ...
}

void foo() {
    C1 c;
    c.m_onCompleted += onCompleted; // aliens have event-access to m_onCompleted
    c.m_completeEvent(); // error: aliens have no multicast-access to m_onCompleted
}