Skip to content

Instantly share code, notes, and snippets.

@rikkimax
Last active May 2, 2024 19:28
Show Gist options
  • Save rikkimax/12559717ade88278f1ef8be07ccf0478 to your computer and use it in GitHub Desktop.
Save rikkimax/12559717ade88278f1ef8be07ccf0478 to your computer and use it in GitHub Desktop.

Private to the Scope

Field Value
DIP: (number/id -- assigned by DIP Manager)
Author: Richard (Rikki) Andrew Cattermole firstname@lastname.co.nz
Implementation: (links to implementation PR if any)
Status: Draft

Abstract

Some people feel that D's visibility is too coarse, this proposal introduces an additional visibility modifier that provides finer protection against unexpected mutation and access based upon sharing of the this pointer in a declaration.

Contents

Rationale

Some D programmers feel that having D's private to the module is far too loose, it prevents them from feeling like they have control over the granuality over the visibility of their symbols.

class Class {
	void callable() {}
	private void sideEffectsHere() {}
}

Class c = new Class;
c.callable(); // Okay
c.sideEffectsHere(); // Not okay

Having the ability to control visibility to finer grained and limit it to just that one type's methods would give confidence that they are not going to step on code that was not intended to be touched.

Prior Work

Many heated threads on adding private to the this pointer exists on the D's News Group. These in the past have not lead to any language additions of this nature. Including the recent DIP ideas[0] thread for the introduction of this feature.

An example of a langauge that supports private to a class, struct or union is Java[1]. It includes a visibility modifier which acts as the default that prevents all accesses outside of the current above to the symbol, declaration.

An exception exists to this requirement is the permit clause in a class declaration. It allows the parent to specify children that may implement it and therefore have access to its private symbols.

Description

The primary change this DIP introduces is the private to the this pointer visibility modifier.

VisibilityAttribute:
	private
+	private ( this )

This allows symbols that share a this pointer within a declaration to access each other.

Nested classes, nested structs, nested unions, static methods, module constructors and unit tests do not support this, and therefore are not capable of having access to their parent types symbols with it.

struct Encapsulation {
	private(this) int field;

	unittest {
		Encapsulation encapsulation;
		assert(encapsulation); // Error: Cannot access Encapsulation's symbol `field` as it is private to the this pointer.
	}
}

Nested classes, structs and unions can be declared as being private(this) but their methods will not have access to the parent's private(this) symbols.

class Parent {
	private(this) int field;
	
	private(this) class Nested {
		void accessIt() {
			field++; // Error: Parent classes symbols that are private to the this pointer cannot be accessed from nested children symbol's.
		}
	}
}

Class inheritance does not introduce access, use protected instead.

class Parent {
	private(this) int field;
}

class Child : Parent {
	void accessIt() {
		field++; // Error: symbol `field`` is private to this scope, and cannot be accessed in child class.
	}
}

Like private, private to the this pointer will also act as final upon a class method.

Breaking Changes and Deprecations

There are no expected behavioral changes will be introduced by this proposal.

Reference

Copyright & License

Copyright (c) 2024 by the D Language Foundation

Licensed under Creative Commons Zero 1.0

History

The DIP Manager will supplement this section with links to forum discsusionss and a summary of the formal assessment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment