January 19, 2004
In article <slrnc0mcde.f82.jsykari@pulu.hut.fi>, Antti Sykäri wrote:
> In article <bu73om$o91$1@digitaldaemon.com>, davepermen wrote:
>>>>auto ExeModule xmod(moduleName);
>> 
>> I'd prefer
>> 
>> ExeModule xmod = auto(moduleName);
>> 
>> somehow.. i don't like the constructor parameters bound to the object.. looks like an opCall for me, dunno how nice to parse..
>> 
>> or
>> 
>> ExeModule(moduleName) xmod;
> 
> For some reason, this one actually seems an incredibly good. It just seems as if it's the one syntax everybody's been hunting down all the time.

*Ahem*  I probably was in an imaginary wonderland where saying

ExeModule xmod;

would indicate declaring a variable of type xmod _and_ instantiating it using the default constructor. In the D as we know it, it may or may not instantiate an object of type xmod, depending on its kind (class objects are not instantiated, struct objects are.) Now it would be silly if a class object suddenly _would_ be instantiated if it's just marked "auto". The policy of how to create an object should not be controlled by whether it's a representative of a "class", or a "struct", or an "auto class", however obvious it is to the seasoned programmer who knows how these concepts are implemented (and who never makes mistakes anyway).

The rules could be simplified to some extent if "ExeModule() xmod" would instantiate the object it but "ExeModule xmod" wouldn't. But then we are in the C++ land where "Foo bar();" means a different thing than "Foo bar;", and confusing the two causes diabolically cryptical parse errors since the former is a function declaration and the latter is a variable declaration. In other words: don't go there.

*However* -- I'm not quite out of silly ideas yet -- what if *all* references were explicitly marked so instead of being implicitly determined by the "classness" of an object? Let's create a new kind of derived type, "reference type" -- which acts precisely like class object types do, namely that objects are treated by reference as opposed to by value.  This means effectively pointers with implicit address-taking and dereferencing. Then introduce the rule that all objects, whether they be struct or class or fundamental type, are by value by default and by reference only if marked as so.

Since these references are not the same references as C++ has, and because C++ has an awfully confusing syntax for them, we don't use C++ syntax. Instead let's adopt the syntax "ref Type" (originally from Algol 68). Examples:

class Object
{
    this() { ... }
    this(int x) { ... }
}

struct Struct
{
    this() { ... }
    this(int x) { ... }
}

void main()
{
    int i;        // an int, initialized to 0.
    int j = 5;    // an int, initialized to 5.
    int(5) j;     // the same, using the cool syntax invented by davepermen.

    ref Struct a; // a reference to a Struct, initialized to null.
    ref Struct b = new Struct(5); // reference to a struct, new'ed from the heap
    ref Struct(5) c; // same as above. (maybe?)
    Struct d;     // a Struct, initialized to default value
    Struct(5) e;    // do as the ints do!

    // With objects, everything is the same except they can't be
    // instantiated on the stack.

    ref Object x; // Reference to Object, initialized to null.
    ref Object y = new Object(5); // Do like the structs do. :)
    ref Object(5) z; // likewise
    Object w;     // Illegal! You can only make references of class types
    Object(5) v;  // Illegal as well.

    // Actually, why not the following as well, if need be:
    ref int = new int(5); // do as the structs do! ;)
}

Perhaps "ref" could be similar property like "auto", so that you can declare "ref class ClassName { ... }" and then they would be all by reference. OTOH then you wouldn't know whether you're looking at a reference or a normal variable if you see a declaration somewhere. So just perhaps.

Now why would this be good?

a) overall simplicity and consistency in the language

which leads to:

b) seamless migration from structs to classes. You can use structs and pass them around using references, and if you need dynamic behavior you can change them to classes with no change in semantics at all. And vice versa! (Ignoring the fact that constructors do not (yet?) properly work for structs, is that correct)

c) no need to think "should I make this concept a struct or a class" -- just pick one, you can change it later if needed

d) even less need to use pointers (now that structs can be passed by
reference)

and, most importantly,

e) no newbies asking "Why does my program 'MyClass x; x.helloWorld();'
fail"

I don't really know just *how* important (e) would be, but guess it wouldn't hurt either. Besides everybody is supposed to know Java (tm) nowadays so I guess everybody knows how to avoid the dreaded NullPointerException.

Not all roses and sunshine here though. Some bad sides of making reference types explicit that I can think of are:

a) it's a move that would require significant re-engineering of the language; For example, do function argument passing modes need to be rethought?  How?

b) there might be non-obvious semantical gaps in the language after the change (well, probably more than there are now at least); For example, how do references to references behave?

c) doing it differently from The Big Languages, C# and Java, is always
risky (as if it mattered before)

...All right, maybe I'll implement it in my OWN language (some day!)

-Antti

January 19, 2004
Antti Sykäri wrote:
>>ExeModule(moduleName) xmod;
> 
> 
> For some reason, this one actually seems an incredibly good. It just
> seems as if it's the one syntax everybody's been hunting down all the
> time.
> 
> It might have small but solvable parsing issues (the part before "xmod"
> first looks like a function call) and it just might not be the perfect
> one, but I like the terseness and consistency with "new
> ExeModule(moduleName)"
> 
> Yet I think that the following should mean the same:
> 
> ExeModule() xmod; // instantiate ExeModule with no args
> ExeModule xmod;   // instantiate ExeModule with no args

That's the problem: the last one is already used to create a reference. And I think the one before is too close to the reference thing - there should be some more noticeable difference.

However, I agree that having the arguments after the class name does seem "right" and is more consistent with the rest of the language (i.e. the new syntax).

So, what about

auto ExeModule(moduleName) xmod;

This makes it more obvious that you're dealing with an auto object and at the same time it solves the minor parsing issue you mentioned.

Hauke
1 2 3
Next ›   Last »