Skip to content

Commit

Permalink
Rewrite storage classes as type qualifiers (#112)
Browse files Browse the repository at this point in the history
* Rewrite storage classes as type qualifiers

- fixes terminology
- fixes wrong statement (const is not guaranteed to not change)
- changes to example to show why const is useful

* Make it clear that string is an immutable array and .dup returns a mutable copy (#4)
  • Loading branch information
Михаил Страшун authored and wilzbach committed Feb 18, 2017
1 parent ed2fc00 commit af4d9c2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 24 deletions.
2 changes: 1 addition & 1 deletion basics/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ordering:
- imports-and-modules
- basic-types
- memory
- storage-classes
- type-qualifiers
- controlling-flow
- functions
- structs
Expand Down
53 changes: 30 additions & 23 deletions basics/storage-classes.md → basics/type-qualifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,46 @@ the compiler to prevent bugs early and enforce restrictions
at compile time. Good type-safety provides the support one needs
to make large programs safer and more maintainable.

There are several type qualifiers in D but most commonly used ones are
`const` and `immutable`.

### `immutable`

In addition to a static type system, D provides
type qualifiers that enforce additional constraints on certain objects.
For example, an`immutable` object can only
be initialized once and then isn't
allowed to change.
In addition to a static type system, D provides type qualifiers (sometimes also
called "type constructors") that enforce additional constraints on certain
objects. For example an `immutable` object can only be initialized once and
after that isn't allowed to change.

immutable int err = 5;
// or: immutable err = 5 and int is inferred.
err = 5; // won't compile

`immutable` objects can thus be safely shared among different threads
because they never change by design. This implies that `immutable`
objects can be cached perfectly.
`immutable` objects can thus be safely shared among different threads with no
synchronization because they never change by definition. This also implies that
`immutable` objects can be cached perfectly.

### `const`

`const` objects can't be modified either. This
restriction is only valid for the current scope. A `const`
pointer can be created from either a *mutable* or an
`immutable` object. This means that the object
is a `const` reference for the current scope, but someone
else might modify it in the future. Only with an `immutable` type qualifier
can you be certain that an object's value will never
change. It is common for APIs to accept `const` objects
to ensure they don't modify the input.

immutable a = 10;
int b = 5;
const int* pa = &a;
const int* pb = &b;
*pa = 7; // disallowed
`const` objects can't be modified, too. This restriction is just valid for the
current scope. A `const` pointer can be created from either a *mutable* or
`immutable` object. This means that the object is `const` for your current
scope, but someone else might modify it from a different context. It is common
for APIs to accept `const` arguments to ensure they don't modify the input as
that allows same function to process both mutable and immutable data.

void foo ( const char[] s )
{
// if not commented out, next line will
// result in error (can't modify const):
// s[0] = 'x';

import std.stdio;
writeln(s);
}

// thanks to `const`, both calls will compile:
foo("abcd"); // string is an immutable array
foo("abcd".dup); // .dup returns a mutable copy

Both `immutable` and `const` are _transitive_ type qualifiers, which ensures that once
`const` is applied to a type, it applies recursively to every sub-component of that type.
Expand Down

0 comments on commit af4d9c2

Please sign in to comment.