Part 1 of the Language Reference Docs Review

Andrej Mitrovic andrej.mitrovich at gmail.com
Fri Jun 25 16:44:28 PDT 2010


Hello,

This is Part 1 of the language spec documentation review which I'm doing. So
far I've covered maybe 1/3rd of the links in the spec docs.

I am going to make a bug report for this, but I was thinking it might be a
good idea if someone could review my findings first (Let me know if you want
the bug report right away and I will do one asap.). Some of these could
likely be my own mistakes, or my misinterpretation of the docs.

The first column is the link to the docs section, the next indentation is
the relevant subsection title (you'll have to do a CTRL+F to find the code
examples, there's not that many 'href' anchors in the html docs, sorry), and
the next indent are the errors/comments. When I say "example" in the text, I
mean the relevant code example from the docs.

All of these examples were tested with DMD 2.046 on XP-32bit, unfortunately
I had trouble setting up DSSS in Ubuntu (and I'm too lazy to make makefiles)
so I didn't test on that platform.

So, here's the copypasta:

http://www.digitalmars.com/d/2.0/module.html
    "Mixin Declaration"
        This should be moved to the "Declarations" section.


http://www.digitalmars.com/d/2.0/declaration.html
    "Aliases cannot be used for expressions"
        The code example compiles even though it says it is illegal.


http://www.digitalmars.com/d/2.0/type.html
    "Implicit Conversions"
        Last line in the example:
            f = E;
        E is undefined, the line should be:
            f = Foo.E;

    "Delegates"
        In the example, assigning the address of a function to a
        function pointer gives a compilation error:
            Error: cannot implicitly convert expression
            (&func) of type int delegate(int) to int function(int)


http://www.digitalmars.com/d/2.0/property.html
    ".init Property"
        "Foo.b.init" is 0, not 7.

    ".stringof Property"
        Example contains two lines refering to "test.Foo",
        but "test" isn't declared anywhere.
        The compiler output is different too.

        The lines should be replaced with:
            writefln((1+2).stringof);       // "1 + 2"
            writefln(Foo.stringof);         // "Foo"
            writefln(int.stringof);         // "int"
            writefln((int*[5][]).stringof); // "int*[5u][]"
            writefln(Enum.RED.stringof);    // "Enum
            writefln((5).stringof);         // "5"

    ".sizeof Property"
        Compilation error:
            sizeof_test.d(14): Error: 'this' is only defined in non-static
            member functions, not test

        Maybe a compiler bug? If "int x = S.a.sizeof" is put outside the
        test() function, it will compile.


http://www.digitalmars.com/d/2.0/attribute.html
    "immutable Attribute"
    "__gshared Attribute"
    "shared Attribute"
    "inout Attribute"

    There is missing documentation for these.


http://www.digitalmars.com/d/2.0/expression.html
    "A CatExpression concatenates arrays, producing a dynmaic"
        typo: dynmaic > dynamic.

    "Array Literals"
        Third example from the title:
            writeln(ct);  // writes [1 1]
            writeln(rt);  // writes [257]

        The output is instead:
            1 1
            1 0 1 0

    "is ( Type Identifier )"
        Replace any 'writefln' with 'writeln' (missing format specifiers).

    "is ( Type Identifier : TypeSpecialization )"
        Replace any 'writefln' with 'writeln'.

    "is ( Type Identifier == TypeSpecialization , TemplateParameterList )"
        Replace any 'writefln' with 'writeln'.

http://www.digitalmars.com/d/2.0/statement.html
    "Labeled Statements"
        It states:
            ''Labels are in a name space independent of declarations,
variables,
            types, etc. Even so, labels *cannot* have the same name as local
            declarations.''

        However this custom example compiles:

        void func() {
            int t;
            t: {
                int xyz;
            }
        }

        So does this one:

        void func() {
            int t;
            xyz: {
                int xyz;
            }
        }

        Perhaps this was meant to state:
            "Declarations *inside* labels cannot have the same name
            as local declarations" ?

    "foreach_reverse"
        IIRC this will be replaced with retro sometime soon? foreach_reverse
        still works though.

    "Foreach over Arrays of Characters"
        First example, these lines:
            char[] a = "\xE2\x89\xA0";    // \u2260 encoded as 3 UTF-8 bytes
            dchar[] b = "\u2260";            // prints 'a[] = 2260'

        Should be replaced with:
            char[] a = "\xE2\x89\xA0".dup;    // \u2260 encoded as 3 UTF-8
bytes
            dchar[] b = "\u2260"d.dup;          // prints 'a[] = 2260'

    "Foreach over Associative Arrays"
        The first example code gives these compiler errors:
            foreach_test.d(38): Error: function

object.AssociativeArray!(const(char)[],double).AssociativeArray.opApply
            (scope int delegate(ref const(char)[], ref double) dg) is not
callable
            using argument types (int delegate(ref double __applyArg0,
            ref char[] __applyArg1))

            foreach_test.d(38): Error: cannot implicitly convert expression
            (__foreachbody524) of type int delegate(ref double __applyArg0,
            ref char[] __applyArg1) to int delegate(ref double)

        Changing the foreach statement like so seems to work:
            double[char[]] a;

            foreach (const (char)[] s, ref double d; a)
            {
                writefln("a['%s'] = %g", s, d);
            }

    "Foreach over Structs and Classes with opApply"
        The sentence:

        "The body of the apply function iterates over the elements it
aggregates"
        Has a typo, change "it aggregates" to "in aggregates".

    "Foreach over Tuples"
        In the first example, replace any 'writefln' with 'writeln'.

        In foreach over arrays it states:
            ''The index must be of int, uint or size_t type''

        In foreach over tuples it states:
            ''The index must be of int or uint type.''

        Is there a reason why one is allowed to be of size_t type,
        and the other is not?

    "Foreach Restrictions"
        The example:
            int[] a;
            int[] b;
            foreach (int i; a)
            {
                a = null;                    // error
                a.length = a.length + 10;    // error
                a = b;                        // error
            }
            a = null;                        // ok

        None of these give compilation errors or warnings.
        Adding memmory allocation statements for a and b before
        entering the loop does not cause any compiler errors, and
        no runtime exceptions are raised.

    "Switch Statement"
        The sentence:
            ''If none of the case expressions match, and there is not a
default
            statement, a [link:std.switcherr.SwitchError] is thrown.''

        The link redirects to a 404 page.
        "std.switcherr.SwitchError" should be replaced
        with "core.exception.SwitchError".

    "Final Switch Statement"
        What is this used for? CTFE maybe? I'm curious. :)

    "Scope Guard Statement"
        In all of the examples under this section
        'writefln' should be replaced with 'writeln',
        and 'writef' with 'write'.

    "Mixin Statement"
        Replace 'writefln' with 'writeln' in the mixin string.

        The line:
            char[] t = "y = 3;";
        Replace it with:
            char[] t = "y = 3;".dup;

        Now only the documentation-relevant errors are shown when compiling.

    "Foreach Range Statement"
        This should be moved up, close to where the other foreach
definitions are.

        In the example code:
            Replace 'writefln' with 'writeln', and 'writef' with 'write'.


http://www.digitalmars.com/d/2.0/arrays.html
    "Usage"
        The lines:
            p = s;        // p points to the first element of the array s.
            p = a;        // p points to the first element of the array a.

        Give compiler errors:
            Error: cannot implicitly convert expression (s) of
            type int[3u] to int*
            Error: cannot implicitly convert expression (a) of
            type int[] to int*

        Casts work:
            p = cast(int*) s;
            p = cast(int*) a;

        But is that a good workaround? Don't ask me.. :p

    "Array Properties"
        In the first example there are missing declarations.
        Could add these before the first line:
            int* p;
            int[3] s;
            int[] a;

    "Setting Dynamic Array Length"
        From the comments in the first example, it states:
            ''// always resized in place because it is sliced
              // from a[] which has enough memory for 15 chars''

        But in this shorter example:
            char[] a = new char[50];
            char[] b = a[0..10];

            b.length = 11;
            a[3] = 'z';
            writeln(b); // writes 11 default characters

        from my tests, resizing b to any bigger length always creates a
copy,
        regardless of how big the length of a is.

        Resizing to a smaller length (e.g. 8) will keep the reference,
        and b[3] will still refer to a[3] in the example.

        Has the resizing behavior changed recently, or is that comment
inaccurate?

    "Functions as Array Properties"
        From this example code:
            int[] array;
            void foo(int[] a, int x);

            foo(array, 3);
            array.foo(3);    // means the same thing

        The last line does not compile, even when foo() is fully defined:
            Error: undefined identifier module main.foo

    "Array Bounds Checking"
        In the example code, "ArrayBoundsError" should be replaced
        with "RangeError".

    "Static Initialization of Static Arrays"
        For the example code:
            enum Color { red, blue, green };
            int value[Color.max + 1] = [ Color.blue:6, Color.green:2,
Color.red:5 ];

        The documentation states:
            ''These arrays are static when they appear in global scope.
            Otherwise, they need to be marked with const or static
            storage classes to make them static arrays.''

        In non-global scope, the array has to be marked with static in order
        to compile. const alone is not compilable. At least not in my case.

    "Special Array Types"
        The 6th example from the title:
            cast(wchar [])"abc"    // this is an array of wchar characters
            "abc"w                // so is this

        It should probably be noted that the first line returns a copy of
the
        string with type wchar[], while the second line returns a copy(?)
        of the string with type immutable(wchar)[]. But correct me if I'm
wrong with this one.

        The next example has this line:
            w = \r[0];        // w is assigned the carriage return wchar
character
        Needs to be replaced with:
            w = "\r"[0];    // w is assigned the carriage return wchar
character

    "Associative Arrays"
        Accessing a nonexistent key for an AA throws the RangeError
exception.
        Perhaps a different exception should be created for AA's, such as:
            core.exception.KeyNotInAssocArray
        ?

    "Using Classes as the KeyType"
        In the example code, any "f" in a declaration/expression needs to be
        replaced with "foo".

    "Using Structs or Unions as the KeyType"
        The line in the example:
            foreach (char c; s)
        Should be:
            foreach (char c; str)

// end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100626/116395d4/attachment-0001.html>


More information about the Digitalmars-d mailing list