July 23, 2009
Walter Bright wrote:
> Of course that's true, but why is a dedicated syntax better than Tuple!( ...) ?

Why is dedicated syntax for comma expressions better than commaExpr(...) ? I take it most folks on this NG would prefer to have shorter syntax for tuples instead the virtually never used comma expressions.

Other than that, you need Tuple!(...) for type tuples, some sorta STuple!(...) for struct-tuples (so they can be nested and passed around properly) and makeTuple(...) for struct-tuple instances.

Comma expressions don't even have to be first-class members of the language:

----

import tango.io.Stdout;

T[$-1] commaExpr(T ...)(lazy T t) { foreach (x; t[0..$-1]) { auto y = x; } return t[$-1]; }
T[0] revCommaExpr(T ...)(lazy T t) { foreach_reverse (x; t[1..$]) { auto y = x; } return t[0]; }

void main() {
    {
        int x;
        int y = revCommaExpr(x += 123, x *= 2, Stdout.formatln("{}", x), Stdout("omg").newline);
		assert (y == 123);
    }

    {
        int x;
        commaExpr(x += 123, x *= 2, Stdout.formatln("{}", x), Stdout("omg")).newline;
    }
}

----
Output:

omg
0
246
omg
----



-- 
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode
July 23, 2009
Michiel Helvensteijn Wrote:

> Lutger wrote:
> 
> > There have been a lot of discussions on this topic in the past but I can't recall any conclusions. Perhaps some brave soul would dare to write a DIP on properties?
> 
> Property DIPs have been offered in the newsgroup in the past, only before they were called DIPs. I also offered a possible design:
> 
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81759
> 
> Feel free to modify and/or DIPify it.
> 
> -- 
> Michiel Helvensteijn
> 

from your post:

property int length {
    get() { return this.len; }
    set(newLen) { this.len = newLen; }
    void opIncrement() { this.len++; }
}

I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.
July 23, 2009
Eldar Insafutdinov wrote:

> from your post:
> 
> property int length {
>     get() { return this.len; }
>     set(newLen) { this.len = newLen; }
>     void opIncrement() { this.len++; }
> }
> 
> I don't think that's flexible to overload every operator to get the best performance. As Walter likes to say the best way should be the most obvious. Besides we forgot that D2 allows to return references, which eliminates the issue.

If your property really just hides a private member variable, it was probably for encapsulation purposes or because you want redundant actions to be taken for every access. If you return a reference, you give unlimited and unrestricted access to that variable with only one call, and you might as well not have used a property at all.

If your property is derived -- that is, if it doesn't directly mirror a variable --, there is no reference to return.

Besides, in D, you can probably use mixins to copy the entire interface of a type into the property without code duplication.

-- 
Michiel Helvensteijn

July 23, 2009
On Thu, Jul 23, 2009 at 10:49:49PM +0100, Tom S wrote:
> Why is dedicated syntax for comma expressions better than commaExpr(...)?

What do you propose we do about the commas in loops? Breaking them would be a pretty big change to the C folks.


With the naked comma tuple, how do you pass them to a function?

void func(Tuple!(int, int) a, int b);

Is that just the same as:

void func(int a, int b, int c);



You'd call them the same way without the tuple decoration :S


It might be my years of C bias, but the naked tuples just look wrong.



-- 
Adam D. Ruppe
http://arsdnet.net
July 23, 2009
Adam D. Ruppe wrote:

> It might be my years of C bias, but the naked tuples just look wrong.

There are ways -- elegant ways, I believe -- to make it work.

Would you look at this page and give me your opinion?

http://code.google.com/p/mist/wiki/Tuples

I'm not sure if it can ever work for D, to be honest. There may be too many differences between the two languages.

-- 
Michiel Helvensteijn

July 23, 2009
Rainer Deyke wrote:
>   - Implementation inheritance of value types, even without actual
> polymorphism, is useful.  See, for example, the curiously recurring
> template pattern (and all of its uses).

You can do this with 'alias this'.

>     And, yes, you can achieve similar results in D by using template
> mixins, but this is a specialized mechanism where C++ manages to do with
> the same generalized mechanism used for polymorphism and interface
> inheritance.

It should be a different mechanism to show that it is a very different thing. Value types aren't polymorphic and shouldn't look like they are.


>     I use inheritance of value types all the time.
> 
>   - Polymorphic references to value types are often useful.  D has
> references to value types (in the form of 'ref' parameters and pointers)
> but these are not polymorphic.  As an example, I would name the standard
> C++ iostream.

iostream isn't a good example of design <g>.


>     They're value types (non-copyable for the most part, but stored
> directly instead of as pointers, with RAII), but they're often passed
> around as polymorphic references.

I.e. they're a mess. You just confused the heck out of me.


>     I use polymorphic references to value types occasionally.
> 
>   - C++ makes a clear distinction between a reference and the thing
> being referenced.  Even if value types and polymorphism were mutually
> exclusive, this distinction would be useful.  All types are consistently
> treated as value types, even those types that reference another object.
> 
>   I *like* having to write 'gc_ptr<Object> p;' instead of 'Object p;'.
> I *like* having to write 'p->f();' instead of 'p.f();'.  It keeps my
> code clearly and more explicit.
> 
>   - C++ does not have separate rules for value types and reference
> types.  All types are implicitly value types; values of all types can be
> placed on the heap.  This simplifies the language by having just one set
> of rules instead of separate rules for classes and structs.  Again, this
> unification would be useful even if it was an error to declare a
> variable of a polymorphic type as a direct variable.

That philosophy conflicts with using . for values and -> for references.


>>> deterministic destructors,  arbitrary copy constructors, and optional
>>> lack of default constructor.
>> Struct have that except for default constructor. In D, currently default
>> constructors cannot execute code. This is a limitation that we might
>> need to address, although it has some advantages.
> 
> There are things that copy constructors can do that the post-blit
> operator can't do.  Also, unless I am mistaken, D can move value types
> around in memory at will, which also invalidates designs that are useful
> in C++.

The capability of being able to move value types is deliberately designed in. It's there for the obvious reason of being able to create a moving garbage collector, and for the more subtle reason of being able to optimize away many more cases of copy-construction and destruction.
July 23, 2009
On Fri, Jul 24, 2009 at 12:03:37AM +0200, Michiel Helvensteijn wrote:
> Would you look at this page and give me your opinion?

Looking at it quickly, the big difference seems to be you leave the tuple word off, and use them in more places.

Is

Tuple!(int, bool) A = tuple(a, b)

really that much worse than:

(int, bool) A = (a, b)

?

Better yet, of course is:

auto A = tuple(a, b);


By keeping the tuple word there, it is no longer conflicting with my C expectations, but seems to be just as useful as your proposal.



-- 
Adam D. Ruppe
http://arsdnet.net
July 23, 2009
Adam D. Ruppe wrote:

> By keeping the tuple word there, it is no longer conflicting with my C expectations, but seems to be just as useful as your proposal.

Hm. Then I believe you haven't read the whole thing. (That's ok, it does go on for a while.) Yes, much of the appeal is in the shorter syntax. But some of the features proposed even require that no 'tuple' keyword is used.

Looking like C is not the be-all and end-all of programming languages. Mist tries to follow mathematical notation wherever possible. This has had other implications, like using <- for assignment and = for equality.

-- 
Michiel Helvensteijn

July 23, 2009
Adam D. Ruppe wrote:
> On Fri, Jul 24, 2009 at 12:03:37AM +0200, Michiel Helvensteijn wrote:
>> Would you look at this page and give me your opinion?
> 
> Looking at it quickly, the big difference seems to be you leave the tuple
> word off, and use them in more places.
> 
> Is
> 
> Tuple!(int, bool) A = tuple(a, b)
> 
> really that much worse than:
> 
> (int, bool) A = (a, b)
> 
> ?
> 
> Better yet, of course is:
> 
> auto A = tuple(a, b);

It's not much worse, but it's not everything that's to tuples. Here's one more example:

> int a, b;

----

> a, b = 2, 3;

Can't do it with tuple(a, b) = tuple(2, 3);
One would have to create yet another helper function, e.g.
> ptuple(&a, &b) = tuple(2, 3);

Or perhaps something with 'ref' instead of pointers, but I remember it being buggy with tuples, and might be too dangerous, since you wouldn't see that you're passing pointers around


-- 
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode
July 23, 2009
Jarrett Billingsley wrote:
> On Thu, Jul 23, 2009 at 4:34 PM, Rainer Deyke<rainerd@eldwood.com> wrote:
>> In my first (and to date only) D project, *all* my user-defined types started as structs, and *all* became classes when I found out that D1 structs don't support all of the features I need.  (None of them used polymorphism.  In C++, all would have been value types.)
> 
> And you don't think that has *anything* to do with trying to program C++ in D.

No, it was clearly a case of trying to program D2 in D1.  In D2, all of these types should be structs.


-- 
Rainer Deyke - rainerd@eldwood.com
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19