Thread overview
A better language
Apr 16, 2006
NN
Apr 16, 2006
Daniel Keep
Apr 17, 2006
renox
Apr 17, 2006
renox
Apr 18, 2006
David Medlock
Apr 18, 2006
renox
April 16, 2006
I love the idea of D language.
But I think it misses some usefult points.

1.
There is no compile-time reflection.
E.g. one could write:
[d]
class a
{
void f() {}
int i;
}

int a_methods = a.methods.length;
bool has_a_f = a.has_method(f);
int a_variables = a.variables.length;
bool has_a_i = a.has_variable(i);

// Or even
class b
{
void g();
}

type a_f_type = a.f.type;
foreach(auto b_f_type; b.methods)
if(a_f_type == b_f_type)
b.b_f_type(); // call b.g
[/d]

2.
Make all postfix:
[d]
// instead of
typeof(a) x = 1;

// write:
a.type x = 1;

// instead of
int a = cast(int)('a');

// write:
int a = 'a'.cast<int>;
// or if we have static_cast :)
int a = 'a'.static_cast<int>;
[/d]

3.
Extensible Metainformation:
E.g.
[d]
class a
{
meta
{
bool is_a = true;
}
}

meta // For all types
{
bool is_a = false;
}

a x;
int y;

static_assert(x.is_a == true);
static_assert(y.is_a == false);
[/d]

4.
Make built-in types likely to object types.

5.
'auto' keyword problem resolution.
auto x = new a(); // auto type, or auto destructor ?

E.g.:
[d]
auto a x = new a(); // destrutor
var x = new a(); // auto type
auto var x = new a(); // auto type + destructor
[/d]

6.
C syntax for templates.
It's so natural.

7.
More casts.
E.g.
static_cast
dynamic_cast
reinterpret_cast // make it safe, error if size of arguments is different
pointer_cast


8.
implicit 'new'.
E.g.
[d]
a x(...); // same as , a x = new a(...)
// same as , auto x = new a(...)

int[] q(1, 2, 3, 4, 5); // same as int[] q = new int[](1, 2, 3, 4, 5);
[/d]

9.
Will be continued. :)

Thank you for attention.


April 16, 2006
NN wrote:
> I love the idea of D language.
> But I think it misses some usefult points.
> 
> 1.
> There is no compile-time reflection.
[snip]

Yeah, /me wants that too.  You could *probably* fake it using some kind of preprocessor and TypeInfo_* classes, but that's a bit iffy.

> 2.
> Make all postfix:
> [d]
> // instead of
> typeof(a) x = 1;
> 
> // write:
> a.type x = 1;

That's fine for single values, but what if you've got an expression?

# (SomeTemplate!(T,U)).type

looks a bit odd.

> // instead of
> int a = cast(int)('a');
> 
> // write:
> int a = 'a'.cast<int>;
> // or if we have static_cast :)
> int a = 'a'.static_cast<int>;
> [/d]

I can guarantee that you will never see the syntax `cast<int>`, since
that has the same problem as C++-style templates: they aren't context free.

Also, again, (some complex expression).cast(type) just seems a bit funky.

> 
> 3.
> Extensible Metainformation:
> E.g.
> [d]
> class a
> {
> meta
> {
> bool is_a = true;
> }
> }
> 
> meta // For all types
> {
> bool is_a = false;
> }
> 
> a x;
> int y;
> 
> static_assert(x.is_a == true);
> static_assert(y.is_a == false);
> [/d]

I'm ... not entirely sure what you're trying to do with this.  It looks almost like extension methods, except with (basically) wildcard matching.  Interesting idea, but I can't think of any cases where it'd be useful.

You could probably emulate it with templates:

# template is_a(T : a)
# {
#     const bool is_a = true;
# }
#
# template is_a(T)
# {
#     const bool is_a = false;
# }]

> 
> 4.
> Make built-in types likely to object types.

Your sentence no parse correctly. (huh?)

Do you mean "make built-in types object types"?

> 
> 5.
> 'auto' keyword problem resolution.
> auto x = new a(); // auto type, or auto destructor ?
> 
> E.g.:
> [d]
> auto a x = new a(); // destrutor
> var x = new a(); // auto type
> auto var x = new a(); // auto type + destructor
> [/d]

I don't like the name 'var', but I do think Walter should pick a new keyword for inferred types (maybe 'infer'?).

Actually, from the docs, I get the impression it doesn't HAVE to be 'auto'; any storage class will do.  I still think there should be a keyword whose only job is to say "normal storage class, figure out the type for yourself".

> 
> 6.
> C syntax for templates.
> It's so natural.
> 

C doesn't have templates.  I'm going to assume you meant "C++ syntax". In which case, again, ain't going to happen (see `cast<int>`).

> 7.
> More casts.
> E.g.
> static_cast
> dynamic_cast
> reinterpret_cast // make it safe, error if size of arguments is different
> pointer_cast
> 

One of the biggest problems I had with C++ was all the casts.  I spent a considerable amount of time pouring over C++ books, and I never did work out what the hell those things do.

For my money, the cast we have is fine for the moment.  The only thing I can think of that would be nice is some kind of decoupled conversion like so:

# // In module scope
# void opCast(out DestType dest, SourceType src)
# {
#     // ...
# }

So that something like `T y = cast(T)x` would become `opCast(y,x)`.

But maybe that's just me. ^_^

> 
> 8.
> implicit 'new'.
> E.g.
> [d]
> a x(...); // same as , a x = new a(...)
> // same as , auto x = new a(...)
> 
> int[] q(1, 2, 3, 4, 5); // same as int[] q = new int[](1, 2, 3, 4, 5);
> [/d]

Actually, what I'd *really* like to see is implicit 'new', but in the Python sense:

# auto a = X(...); // same as...
# auto a = new X(...);

The rationale behind that is that classes and object factories are suddenly interchangeable.

> 
> 9.
> Will be continued. :)

Dun, dun dunnnnnn...

> 
> Thank you for attention.
> 
> 

	-- Daniel

-- 

v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP    http://hackerkey.com/
April 17, 2006
NN wrote:
[cut]
> 2.
> Make all postfix:

One thing which could be made postfix is pointers instead of having
*p=5; using p@=5; would be better: no need to use parenthesis to distinguish between *(f()) and (*f)(), it becomes f()@ and f@() .

And no need to have the C shortcut pst->field, it just becomes pst@.field

Having postfix pointer dereferencing is better IMHO, what I'm not sure is if postfix is better for getting the address of an object, that is replacing p = &x ; by p = x.get_address; here I'm not sure that there is a real advantage.



I would add one point: replace C like type declaration (which sucks a lot) by Pascal like type declaration.
Pacal like type declaration still sucked because it was too verbose: C terseness with Pascal like variable declaration would be ideal IMHO.

Something looking like: x: @[10]->int; (the variable x is a pointer to an array of 10 int) but I've not yet thought enough about it.

Regards,
Renox
April 17, 2006
renox wrote:
> NN wrote:
> [cut]
> 
>> 2.
>> Make all postfix:
> 
> 
> One thing which could be made postfix is pointers instead of having
> *p=5; using p@=5; would be better: no need to use parenthesis to distinguish between *(f()) and (*f)(), it becomes f()@ and f@() .

Its an interesting idea, although the latter case is not neccessary, I don't believe, even if one uses a C-style function pointer.  D automagically dereferences for member accesses and function/delegate invocations.

> And no need to have the C shortcut pst->field, it just becomes pst@.field

We don't have this, already.  With pointers, you just use the dot (.) operator.  Also, the most common occurance of pointers with fields -- class instances -- does not apply to D, because class variables are references.  So...

# Foo x = new Foo;
# x.field = 123;
#
# Bar* y = &foo;
# y.field = 321;
#
# assert(x.field == 321);

> Having postfix pointer dereferencing is better IMHO, what I'm not sure is if postfix is better for getting the address of an object, that is replacing p = &x ; by p = x.get_address; here I'm not sure that there is a real advantage.

I think the address operator should be left alone.  Besides, it reads well as "address-of" in this position.

> I would add one point: replace C like type declaration (which sucks a lot) by Pascal like type declaration.
> Pacal like type declaration still sucked because it was too verbose: C terseness with Pascal like variable declaration would be ideal IMHO.
> 
> Something looking like: x: @[10]->int; (the variable x is a pointer to an array of 10 int) but I've not yet thought enough about it.

// your idea: x: @[10]->int;
// currently: int[10]* x;

Knowing that in D types are read right-to-left in declerations, I really don't think we need this big of a change.  Especially since we do have the 'function' keyword for doing function pointers.

# void function (int, int) fn;
#
# void sumsqr (int dA, int dB) { return pow(dA + dB, 2); }
#
# fn = &sumsqr;

> Regards,
> Renox

-- Chris Nicholson-Sauls
April 17, 2006
Chris Nicholson-Sauls wrote:
[cut interesting remark showing that automagic pointer dereferencing reduce the interest of postfix pointer derefencing]
> // your idea: x: @[10]->int;
> // currently: int[10]* x;
> 
> Knowing that in D types are read right-to-left in declarations,

I know that and for me, this is an unpleasant pitfall of D, especially for array declaration:
int[Y][X] t; and then t[x][y] = ...

t: [X]->[Y]->int; and then t[x][y] = ...

Honnestly which reads better?

I know that D used to be (is still?) compatible with C declaration, but if helps for the array declaration (int t[X][Y];) but, this is a mess when there are pointers..

> I really don't think we need this big of a change.  Especially since we do have the 'function' keyword for doing function pointers.

I do agree that this is a big change and don't expect to see it in D, and in fact I'm so used to C's declaration that personnaly it's not a problem, but I do remember clearly that I had a hard time learning them while beginning C and I expect D beginners to have the same problem.. which is a pity.

Oh well, at least hopefully the out-of-bound exception will show them the mistake quicky (far from sure of course as it depends on the value used), but it is still a pitfall.

Regards,
renox

> 
> # void function (int, int) fn;
> #
> # void sumsqr (int dA, int dB) { return pow(dA + dB, 2); }
> #
> # fn = &sumsqr;
> 
>> Regards,
>> Renox
> 
> 
> -- Chris Nicholson-Sauls
April 17, 2006
"renox" <renosky@free.fr> wrote in message news:e20n8n$cia$1@digitaldaemon.com...
> I know that and for me, this is an unpleasant pitfall of D, especially for
> array declaration:
> int[Y][X] t; and then t[x][y] = ...

I find it a lot easier to think of multi-dimensional arrays as if they had parentheses to show binding of types, like so:

(int[Y])[X] t;

That is, t is an array of size [X] of (arrays of size[Y] of int).  That is, when you use one level of [] operators,

t[4]

You get an int[Y].  Then you use another set to strip off the [Y] to get at the actual int values.


April 18, 2006
renox wrote:
> Chris Nicholson-Sauls wrote:
> [cut interesting remark showing that automagic pointer dereferencing reduce the interest of postfix pointer derefencing]
>> // your idea: x: @[10]->int;
>> // currently: int[10]* x;
>>
>> Knowing that in D types are read right-to-left in declarations,
> 
> I know that and for me, this is an unpleasant pitfall of D, especially for array declaration:
> int[Y][X] t; and then t[x][y] = ...
> 
> t: [X]->[Y]->int; and then t[x][y] = ...
> 
> Honnestly which reads better?
> 

I would say wrap your array for the specific problem you are trying to solve, then override the opIndex/opIndexAssign  methods:

t[ X, Y ] = ....

Reads much better.

-DavidM

April 18, 2006
renox wrote:
> Chris Nicholson-Sauls wrote:
> [cut interesting remark showing that automagic pointer dereferencing reduce the interest of postfix pointer derefencing]
> 
>> // your idea: x: @[10]->int;
>> // currently: int[10]* x;
>>
>> Knowing that in D types are read right-to-left in declarations,
> 
> I know that and for me, this is an unpleasant pitfall of D, especially for array declaration:
> int[Y][X] t; and then t[x][y] = ...
> 
> t: [X]->[Y]->int; and then t[x][y] = ...
> 
> Honnestly which reads better?

Honestly, to my eyes?  The current style.  I don't care for the `->` symbol needed in the proposed syntax, and I'm just too used (in D) to scanning down columns of variables and glancing (right to left) to check types.  Probably if it had been otherwise from earlier on, my habits would be different, while as it is...  Although I do admit to liking a left-to-right style in general, I just don't see a way to do it in D.  For what its worth, a purely hypothetical pet language of me and a couple buddies (codename Lux) has used this for years:

# {* Equivelant to D decleration "int[10]* x;" *}
# var() {
#   &[10]int32 : x ;
# }

-- Chris Nicholson-Sauls
April 18, 2006
Chris Nicholson-Sauls wrote:

> renox wrote:
> 
>> Chris Nicholson-Sauls wrote:
>> [cut interesting remark showing that automagic pointer dereferencing reduce the interest of postfix pointer derefencing]
>>
>>> // your idea: x: @[10]->int;
>>> // currently: int[10]* x;
>>>
>>> Knowing that in D types are read right-to-left in declarations,
>>
>>
>> I know that and for me, this is an unpleasant pitfall of D, especially for array declaration:
>> int[Y][X] t; and then t[x][y] = ...
>>
>> t: [X]->[Y]->int; and then t[x][y] = ...
>>
>> Honnestly which reads better?
> 
> 
> Honestly, to my eyes?  The current style.  I don't care for the `->` symbol needed in the proposed syntax,

In Pascal it was 'type: array[1,10] of int;' if memory serves which is definitely too verbose. I like '->' that's what Scala use: it looks like math.. But this is just a matter of taste.

> and I'm just too used (in D) to scanning down columns of variables and glancing (right to left) to check types. 

That's the problem once you got used to a syntax, you don't even see its  problem anymore, as I'm not using D and that in C/C++ the array declaration has the correct order, the inverse array declaration/usage of D still 'hurt my eyes'.

> Probably if it had been otherwise from earlier on, my habits would be different, while as it is...  Although I do admit to liking a left-to-right style in general, I just don't see a way to do it in D.  For what its worth, a purely hypothetical pet language of me and a couple buddies (codename Lux) has used this for years:
> 
> # {* Equivelant to D decleration "int[10]* x;" *}
> # var() {
> #   &[10]int32 : x ;
> # }

Interesting, I like it. It's compact and it's clever to use & instead of  *.
The terseness may make it a bit hard to read for beginners, but it's nice.

I prefer 'variable: type' than the other way round because as in Limbo you can do this nice regular syntax:

my_var : int; // declares my_var with type int and initialise it with default value of type int (0).
my_var : int = 5; // declares my_var with type int and initialise it with 5
my_var := 5; // declares my_var with type inferred from 5 (int), and initialise it with 5
my_var = 6; // assign 6 to my_var, my_var must already be declared with a compatible type.

To avoid people abusing of ':=', the language just have to forbid double declaration of variable in the same function.

Regards,
Renaud.

> 
> -- Chris Nicholson-Sauls