User:Quickfur/DIP scope

From D Wiki
< User:Quickfur
Revision as of 19:50, 10 July 2014 by Quickfur (talk | contribs) (Description)
Jump to: navigation, search
Title: DIP Proposed design for "scope" implementation
DIP: ???
Version: 1.9
Status: Draft
Created: 2014-7-10
Last Modified: 2014-7-10
Author: H. S. Teoh
Links: ...

Abstract

The goal of this DIP is to work out a concrete design for the implementation of 'scope'.

Rationale

The 'scope' keyword has been around for years, yet it is barely implemented and it's unclear just what it's supposed to mean. This DIP hopes to work out concrete details on the semantics of 'scope' so that it actually has a chance of being implemented.

Description

This DIP proposes the following:

  • scope can be applied to any type in the language, and becomes part of the type. Thus, scope(int) is a distinct type from int, for example. We shall call these types scoped types. They interact with the current types in the language via a set of rules, which will be defined below.
  • Every scoped type is associated with a lifetime. For convenience, we may regard non-scoped types as a special case of scoped types, where the associated lifetime is infinite. The lifetime of a scoped type is inherited from the scope in which it is declared, and is regarded as part of its type. Thus, a scope(int) declared in one lexical scope is considered to be a different type than a scope(int) declared in a different lexical scope (even though they will, in general, be compatible with each other according to the rules described in the remainder of this DIP). Exactly what lifetime is assigned to a scoped type is defined in the following section.

Lifetimes

  • The lifetime of a scoped function parameter is the body of the function.
  • The lifetime of a scoped local variable is the enclosing lexical scope where it is declared. The lifetime of a module-global variable is infinite.
  • The lifetime of a scoped return value of a module-level function is infinite, whereas the lifetime of a scoped return value of a nested function is the body of the enclosing outer function.

Rules

This section defines the rules of interaction between scoped types and non-scoped types.

The underlying guiding principle of all of these rules may be termed the Law of Narrowing Lifetimes, that is, one can only retain or reduce the lifetime of a scoped type, never expand it. The one exception to this law is that value types can be copied from a type of narrower lifetime to a type of a wider lifetime, because semantically, a copy of the value is being made, hence we do not violate the lifetime of the original variable that held the value.

  • A reference to a scoped type is also a scoped type, with a lifetime equal or narrower to the lifetime of the referent. In no case shall there be a reference to a scoped type where the reference has a longer lifetime than the referent scoped type. Thus:
  • Taking the address of a scoped variable produces a scoped pointer of the corresponding type, with the same lifetime as the variable itself.
  • Assignment: here, we distinguish between scoped value types, and scoped reference types. Note that for the purposes of this DIP, we shall regard "assignment" as including the assignment operator =, as well as passing a value to a function, or returning a value from a function.
  • A scoped reference type can only be assigned to another compatible scoped type with the same lifetime or narrower. It is illegal to assign a scoped type to a type with a wider lifetime.
  • A scoped value type may be assigned to a compatible type of a wider lifetime, provided it does not contain any indirections. If it does contain indirections, then it is subject to the assignment rule of scoped reference types, that is, it can only be assigned to a compatible scoped type of equal or narrower lifetime.

Usage

Implementational considerations

TBD: it would be nice if the lifetime of a scoped type can be statically determined from its lexical context, so that the lifetime annotation on the type can be erased at compile-time (i.e., if the types of x and y in a particular lexical context are both scope(int), then they should have the same lifetime). Otherwise it will have to be included in the mangling of functions, which is uglier.

Copyright

This document has been placed in the Public Domain.