The D Programming Language

Author: Andrei Alexandrescu
4.4
All Comments
TopTalkedBooks posted at August 20, 2017

I would point out that there is a big difference between a grammar rule named StorageClass, and what is semantically a storage class in the language. The grammar rules have to do with parsing, not the semantic phase of compilation.

First off, TDPL, chapter 8, is explicitly about type qualifiers (for which Walter used the term type constructor). There are only 3 of them in D:

const
immutable
shared

All three of them are a part of the type that they modify. Such is not true with storage classes such as ref.

inout is what TDPL calls a "wildcard qualifier symbol," so it's a placeholder for a type qualifier rather than really being either a type qualifer or a storage class.

Now, as to what's a storage classes or not, I give two quotes from TDPL:

Each function parameter (base and exponent in the example above) has, in addition to its type, an optional storage class that decides the way that arguments are passed to the function when invoked.

(from pages 6 - 7)

Although static is not related to passing arguments to functions, discussing it here is appropriate because, just like ref, static applied to data is a storage class, meaning an indication about a detail regarding how data is stored.

(from page 137)

Also, there's this line with regards to storage classes in C which seems to be used quite a bit in explanations on storage classes in C found online:

A storage class defines the scope (visibility) and life time of variables and/or functions within a C Program.

A storage class has no effect on the type of a variable, just how it's stored. Unfortunately, I can't find an exact list of storage classes in D, and people are quite liberal with the term storage class, using it even when it doesn't apply. Pretty much any attribute applied to a type save for access modifiers seems to get called a storage class, depending on who's talking. However, there are a few which are beyond a doubt storage classes:

enum (when used as a manifest constant)
extern
lazy
out
ref
scope
static

lazy, out, and ref can be used to modify function parameters and indicate how they're passed, whereas enum and static are used to indicate how the variables are stored (which is nowhere in the case of enum, since manifest constants are copy-pasted everywhere that they're used rather than being actual variables). extern affects linkage.

in is a hybrid, since it's a synonym for scope const, and while scope is a storage class, const is a type qualifier.

The online documentation also refers to auto and synchronized as storage classes, though I don't know on what basis. auto is like inout in that it's a placeholder (in its case a placeholder for a type rather than a type qualifier) and therefore indicates nothing about how a type is stored, so I wouldn't have thought that it would be a storage class. synchronized doesn't modify variables but rather classes.

__gshared is probably a storage class as well, though it's a bit funny, since it does more or less what shared (which is a type qualifier) does, but it's not part of the type.

Beyond that, I don't know. The fact that synchronized is listed as a storage class implies that some of the others (such as final) might be, but (like synchronized) they have nothing to do with how variables are stored or linked. So, I don't know how they could be considered storage classes.

I'll ask on the newsgroup though and see if I can get a more definitive list.

EDIT: It seems that there is no definitive, official list of storage classes in D. The term is used for almost any attribute used on a variable declaration which doesn't affect its type (i.e. not a type qualifier). It seems that Walter and Andrei tend to make a big point about the type qualifiers to underline which attributes actually affect the type of a variable, but the term storage class hasn't been given anywhere near the same level of importance and ends up being used informally rather than per any rigorous definition.

TopTalkedBooks posted at August 20, 2017

You could try D. My one-sentence description of why it's an awesome language is that its generic programming/compile-time introspection/template metaprogramming facilities are good enough to give you almost flexibility of a duck-typed language, while its execution speed and static type checking rival or exceed C++ and C#.

I think it meets your requirements quite well.

  • Open source: The frontend to the reference DMD implementation is open source (the back end isn't due to restrictions beyond the author's control). Work is underway to glue the reference frontend to open source backends such as LLVM (LDC) and GCC (GDC). In the case of D1 (the older version of the language) the LLVM port is fairly mature.
  • Compiled: D is meant to be compiled to native machine code, i.e. raw, inscrutable hexadecimal numbers.
  • Cross-platform: The reference DMD compiler supports x86 Windows, Linux, Mac OS X and FreeBSD. GDC and LDC will likely support a lot more CPU architectures.
  • Object oriented: D isn't a "pure" OO language in the Ruby sense of everything being an object, or in the Java sense of not supporting any other paradigm. It does, however, fully support Java-style OO as a subset of the language, along with procedural and functional style programming.
  • Large standard library: D1 has Tango, which qualifies. D2 has Phobos, which is not "large" yet by modern standards but is larger than C or C++'s standard lib. However, recently there has been a large interest in contributing and Andrei Alexandrescu (its main designer) has accepted several new contributors, including myself.
  • Extensive documentation: The standard library and language are reasonably well documented at the Digital Mars website. There's also Andrei Alexandrescu's book "The D Programming Language".
  • Web development: This is an admitted weakness. D doesn't (yet) have a good web framework, though its native unicode support and excellent generic programming support should make writing one relatively easy.
TopTalkedBooks posted at August 20, 2017

At the moment, the answer is a resounding "it depends". Specifically, it depends on the OS and which version of D.

DMD, or the Digital Mars D compiler, is the reference implementation and offers 64-bit support. The 64bit support is restively new (see comments below) but Walter Bright, the language creator, has indicated that getting it on par with 32bit is a high priority now that D2 out the door (or more correctly now that Andrei Alexandrescu's book "The D Programming Language" has been released). However, he has indicated that due to linker issues, the first few versions will not support 64-bit on Windows (this seems to still be true).

For D1, 64-bit support is great on Linux and Mac if you use LDC, which is a D compiler targetting LLVM. For Windows, the GDC compiler, which targets the GCC back end, has been resurrected but is several versions behind the curve. On D1 this isn't terribly important since the language spec is fairly stable.

For D2, 64-bit support is currently basically non-existent. The aforementioned GDC does support it, but D2 has been evolving rapidly and GDC is too out of date to be useful here. Most non-trivial code written for version 2.015 (the latest GDC supports) probably won't even compile on version 2.040 (the latest version of DMD) and vice-versa.

Edit: As of today, June 21, 2010, there are some commits in SVN towards 64-bit support for DMD. These are far from a working compiler, but the point is that it's underway.

Edit # 2: As of mid-February, 2011, DMD 2.052 supports 64-bit on Linux.

Edit # 3: As of November, 2011, GDC is usable and only one release behind DMD, though it's somewhat beta-ish and not packaged yet. You have to compile it from source.

Top Books
We collected top books from hacker news, stack overflow, Reddit, which are recommended by amazing people.