Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Learn to Tango with D

Learn to Tango with D is a book about the D programming language and the Tango software library. It became available as an eBook 7th of January 2008, whereas the printed version should be available 3 weeks later.

Learn to Tango with D introduces you to D, with special attention given to the Tango software library. A concise yet thorough overview of the language syntax and features is presented, followed by an introduction to Tango.

The book is written by Kris Bell, Lars Ivar Igesund, Sean Kelly and Michael Parker.

Foreword is by Walter Bright, and technical reviewer was Don Clugston.

Buy the Book

All proceeds from the book will be channeled into the Tango project, to the benefit of both Tango and the D community.

  • Apress - eBook available now
  • Amazon - Now indicates in-stock
  • Barnes and Noble - Will have it on the shelves soon
  • ...

Book Reviews

Download Index

Jesse Phillips has kindly compiled an index for the book that you can download in various formats.

Feel free to suggest improvements, if so please use the ODT version.

Talks and Presentations

If you or your company is interested in talks or presentations on D and Tango, please contact us.

Table of Contents

The book proper has 188 pages divided on the following subjects:

  1. First Steps
    • Hello World
    • Source Modules
    • Package, Import, and Symbol Visibility
    • Installation
    • Compilation Tools
  2. D Fundamentals
    • Declarations
    • Pointers
    • Arrays
    • Flow Control
    • Functions
    • Error Handling
  3. D’s Object-Oriented Features
    • Modules
    • Structs and Unions
    • Classes
    • Interfaces
  4. Procedural Lifetime
    • D Language Type Classifications
    • Scope and Lifetime
    • Storage Classes
    • Static Constructors
    • Lifetime Characteristics of Modules
    • Lifetime Characteristics of Functions
    • Garbage Collection
  5. Templates
    • The Problem of Insufficient Information
    • Type Templates
    • Function Templates
    • Template Specialization
    • Template Metaprogramming
    • Compile-Time Function Evaluation
  6. Text Processing
    • String-Manipulation Utilities
    • Text Class
    • Numeric Conversion
    • Layout and Formatting
  7. Input and Output
    • Console I/O
    • Stream I/O
    • Network I/O
    • File Handling
  8. The Other Packages
    • The Package Rundown
    • Threads and Fibers
    • Collections
    • Logging
    • And That’s Not All!


This is deferred to its own Errata page.

User Comments

Author Message

Posted: 01/08/08 09:13:54

Congrats on finishing the book!

Posted: 01/08/08 17:32:07

Congratulations on finishing the book and getting it out the door. I'll be ordering my copy soon enough. :)

-- EricAnderton at yahoo

Posted: 01/09/08 12:01:21

Thank you for providing this important resource. I have bought the ebook, to support the community.

Posted: 01/09/08 15:36:53 -- Modified: 01/09/08 15:47:25 by

Hi there, I hope Kris in particular gets to read this, but maybe anyone could answer me... On page 34, when talking about array copying, Kris uses examples with array slicing, like this:

int[] x = [0, 1, 2, 3, 4];
int[] y = x;                // All 5 elements of x are copied to y.
int[] z = x[];              // All 5 elements of x are copied to z.
y[0 .. 2] = x[1 .. 3];      // Same as y[1] = x[2];.

I believe all the comment statements are false. Compiling this code with dmd 1.025 results in y being another view of x (i.e., same memory space), as well as z.

The last statement is false for two reasons:

- Assuming y has nothing to do with x, speaking of memory allocation,

y[0 .. 2] = x[1 .. 3];

results in

y[0] = x[1];
y[1] = x[2];

- Because y points to x, sort of:

y[0 .. 2] = x[1 .. 3];

is the same as

x[0 .. 2] = x[1 .. 3];

which results in a runtime overlapping error.

This would result as expected if both y and z were declared as static arrays, in which case the allocated memory would be different for each array.

does this apply to dmd 2.0?

Other than that, for what I've read so far, it's a good book, though I mustn't agree with someone who wrote somewhere that it would be a good book for new programmers... I believe it requires a good notion of what computer programming is, and some programming experience to understand the book, but maybe that's just me... I wouldn't feel comfortable to read it without knowing what I know these days (2 years of Java/C/C++ coding), though simple programming notions are recommended...

Good job, and hoping to hear from you. If you can, send me a reply notification to

Posted: 01/09/08 17:26:46 -- Modified: 01/09/08 17:40:38 by

Thanks. Will ensure the author of that chapter sees this. Larsivi is suggesting we maintain an errata list here in the wiki, which seems like a fine idea

Posted: 01/09/08 18:14:55

on page 33 there's other error, but I think most people get it....

int x[] = [0, 1, 2, 3, 4];
// ...
int all = x[];

of course we cannot assing an int[] to int.... I'll keep reading and posting this kind of feedback, if you don't mind....

Posted: 01/10/08 10:20:33 -- Modified: 01/10/08 10:21:50 by

Thanks for catching this.

nDray wrote:

does this apply to dmd 2.0?

It's not a D 2.0 thing, just a mistake. Both x and y should have been declared static rather than dynamic. The examples were taken from the array documentation (specifically the section on array copying), where the sample arrays are properly declared static.

Posted: 01/11/08 09:05:32 -- Modified: 01/11/08 09:06:36 by

I was looking at the template chapter now, and on page 105/106 I found this example:

void func( T )( T val ) {

pragma( msg, "func( T )( T val )" );


void func(T, U = void )( T[] val ) {

pragma( msg, "func( T )( T[] val )" );


void func( T, U = void, V = void )( T* val ) {

pragma( msg, "func( T )( T* val )" );


void main() {

int i;
int* p;
int[] a;
func( i );
func( p );
func( a );


Here, func( i ) should choose the first routine, func( p ) should choose the second, and func( a ) should choose the third. And T will be expanded as int in all three cases.


When I run this code using dmd 1.025 C:\temp>dmd test
func( T )( T val )
func( T )( T val )
func( T )( T val )
C:\d\dm\bin\link.exe test,user32+kernel32/noi+tango-base-dmd.lib+tango-user-dmd.lib;

Posted: 01/13/08 20:14:23

haven't read the whole book, but on chapter 5 you talk about delegates' lifetime without properly expose their definition and/or usage, which should've been done in chapter 2, or so...

a few pages later, on templates, you should let readers know what opApply does in a class....

Posted: 01/15/08 23:00:40

Regarding the template chapter... the book says what /should/ happen, but a bug in DMD is causing different behavior. I verified that this was indeed a bug with Walter when writing the chapter and hoped that this would be fixed by the time of publishing, but unfortunately that is not the case. The relevant ticket is here:

Posted: 01/20/08 01:58:38

Hi, great book, congratulations!

I found a little mistake:

on page 76, example for opOr should obviously be "o | c"

Posted: 01/20/08 10:23:33

Thanks Daniel, added to the Errata page.

Posted: 02/03/08 17:50:11

Nice work boys! I'm considering ordering a paper copy too, since reading pdfs kinda sucks. ;)

When I read the first couple of chapters back when the pdf was released, I wrote down some errors I noticed. It's a kind of 'errata with comments', I guess. I've already shown this page to larsivi, but I've made a couple of edits since then.

You're welcome to add this to the official errata page if you like. I guess it should be trimmed down at bit, do what you feel is best. I could do it, but I'm not sure how much detail the errata should contain, etc.

Posted: 02/09/08 07:21:42

Thank you, tohru :)

Posted: 02/26/08 13:02:10

Page 73, Interface Definition:

interface InputStream {
    IConduit conduit();
    uint read (void [] dst);
    void clear();

I am not sure I understand why it says "These classes need to be implemented in any class that declares this interface". Shouldn't it say instead "These methods need to be implemented in any class that declares this interface"? Thanks.

Posted: 04/11/08 13:01:55

Available in Sweden:

...... rasmus

Posted: 04/28/09 23:49:59

nDray wrote:

a few pages later, on templates, you should let readers know what opApply does in a class....

I agree! opApply appears for the first time on page 99. It should be among the operators on pages 76-77 with some explanation of what it does...

Posted: 04/29/09 00:14:15

just a few more comments, before I know D so well that I will not notice them....

1. assert should be in the index.

2. assert appears for the first time on page 56, inside unittest. I think there needs to be more explanation of what assert does.

3. debug() is not explained. As far as I can see, it appears also on page 56. "...wrapping these imports and the unit test itself in a debug(UnitTest?) block..." that is pretty much impossible to understand. What does debug do? What is UnitTest? as opposed to unittest?

4. typeof appears on page 25. It is not explained how to use it. In fact, the word "operator" (here you refer to "typeof operator" is only used in reference to operator overloading, and the "global scope operator ." So, I'm not really sure what it means that typeof is an operator... I would explain typeof a bit, maybe with some examples...

5. enum is not in the index. (where is it explained? I'm not sure)

Posted: 05/03/09 04:05:33