April 30, 2012
On Monday, 30 April 2012 at 15:38:41 UTC, simendsjo wrote:
>
> I think struct literals is worse in this regard:
> struct S {
>   int a;
>   int b;
> }
>
> user code:
> S(1, 2);
>
> The author of S cleans up the struct and changes the order:
> struct S {
>   int b;
>   int a;
> }
>
> Suddely user code has bugs. I believe the reason named parameters hasn't been introduced is because the names becomes part of the public interface. Well.. With struct literals, the _position_ of the parameters is part of the interface.

Structs provide POD value types and as such MUST include the position as part of the interface. The memory layout of these types is used to copy, compare,  transmit over the net, etc. If you want encapsulation you need to at the least to define a ctor or maybe change to a class.

I'd be very upset if I defined a struct for serialization/transmitting over the net/etc and changing its memory _didn't_ cause loud compiler errors.

named parameters are 99% of the time a horrible idea and likely indicate a design flaw.


April 30, 2012
On Mon, Apr 30, 2012 at 05:47:59PM +0200, bearophile wrote:
> H. S. Teoh:
> 
> >When you have nested with's.
> >
> >Or when the object members shadow local variables in the parent scope.
> >
> >	struct S {
> >		int x;
> >	}
> >
> >	void main() {
> >		int x, y;
> >		S s;
> >
> >		with(s) {
> >			x = 1;
> >			y = 2;
> >		}
> >	}
> 
> That code doesn't compile:
> 
> test.d(10): Error: with symbol test.S.x is shadowing local symbol
> test.main.x
[...]

Which means your code is at the mercy of the external library. Upstream updates a class, and suddenly a whole bunch of code is unnecessarily broken (if you had just used aliases instead, there would be no problem).


T

-- 
It is of the new things that men tire --- of fashions and proposals and improvements and change. It is the old things that startle and intoxicate. It is the old things that are young. -- G.K. Chesterton
April 30, 2012
On 30 April 2012 17:16, SomeDude <lovelydear@mailmetrash.com> wrote:
> On Monday, 30 April 2012 at 16:14:58 UTC, SomeDude wrote:
>>
>> On Monday, 30 April 2012 at 15:19:29 UTC, Alex Rønne Petersen wrote:
>>>
>>> On 30-04-2012 11:46, SomeDude wrote:
>>>
>>> I don't have a clone of my repo from where I am now, so I can't count, but it usually takes around ~30 seconds with DMD, ~2 minutes with GDC.
>>
>>
>> For how many files/lines of code ?
>
>
> And on what hardware ? I'd like to have a bit of an idea of how fast the compilers really are.

That sort of speed difference sounds about right.  I'm not sure how the DMD backend works, but I assume that there is no more than about 3 passes.  A conversion from D Frontend AST to DM Backend AST, possibly a peephole optimiser, then an output to object code.

GCC backend has some 50+ passes it processes the generated AST through passed from GDC. Not to mention it only outputs assembly code.  So there is some overhead for calling AS to compile to object code (something that DMD just compiles straight to), and double overhead for calling LD to link the resultant binary/library.


Regards

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
April 30, 2012
H. S. Teoh:

> Which means your code is at the mercy of the external library.
> Upstream updates a class, and suddenly a whole bunch of code is
> unnecessarily broken

How? (I think you are wrong again).

Bye,
bearohile
April 30, 2012
On 30 April 2012 17:44, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
> On 30 April 2012 17:16, SomeDude <lovelydear@mailmetrash.com> wrote:
>> On Monday, 30 April 2012 at 16:14:58 UTC, SomeDude wrote:
>>>
>>> On Monday, 30 April 2012 at 15:19:29 UTC, Alex Rønne Petersen wrote:
>>>>
>>>> On 30-04-2012 11:46, SomeDude wrote:
>>>>
>>>> I don't have a clone of my repo from where I am now, so I can't count, but it usually takes around ~30 seconds with DMD, ~2 minutes with GDC.
>>>
>>>
>>> For how many files/lines of code ?
>>
>>
>> And on what hardware ? I'd like to have a bit of an idea of how fast the compilers really are.
>
> That sort of speed difference sounds about right.  I'm not sure how the DMD backend works, but I assume that there is no more than about 3 passes.  A conversion from D Frontend AST to DM Backend AST, possibly a peephole optimiser, then an output to object code.
>
> GCC backend has some 50+ passes it processes the generated AST through passed from GDC. Not to mention it only outputs assembly code.  So there is some overhead for calling AS to compile to object code (something that DMD just compiles straight to), and double overhead for calling LD to link the resultant binary/library.
>
>


Having said that, I did produce a report from GDC once with a list of times it takes to compile D2 code (in this instance, libphobos and druntime).

http://iainbuclaw.files.wordpress.com/2010/09/d2-time-report2.pdf

TOTAL is the total time taken (ie: 0.08 seconds in the first file), and the other elements are a breakdown of what passes took the longest amount of processing time during the entire compilation.


If you could get DMD to pull off a similar report, you'd have something nice to compare to. ;-)


Regards

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
April 30, 2012
On Monday, April 30, 2012 11:15:17 bearophile wrote:
> Jonathan M Davis:
> > Honestly, I don't think that you _can_ take much from this thread other than
> 
> I don't agree, I see some recurring patterns.
> 
> People have spent energy and time to write lot of answers in this thread, some good answer bits too, so I expect such work to not let be fully wasted. Asking for opinions, receiving lot of them, and then ignoring them all is not a good way to run a community.
> 
> And thank you for your answer, I always appreciate your answers,
> but you aren't Walter, that post was for him (and Andrei) to
> answer :-)

I never claimed that I _was_ Walter. I was pointing out that there's very little consensus in this thread (almost all of the comments are in conflict with other comments) so that even if it was our intention to go and remove things from the language based on this thread, there is very little, if anything, that has a clear consensus on being removed. The closest would probably be the comma operator, and there wasn't even a complete consensus on _that_.

And while I obviously can't say for certain what Walter intended, it was my impression that the point of this thread was more out of curiosity and for "lessons learned" from designing D than to actually make any changes to the language right now (especially when you consider how much Walter hates breaking backwards compatibility). But obviously, he'd have to clarify for us to know for sure.

- Jonathan M Davis
April 30, 2012
On Mon, Apr 30, 2012 at 06:54:31PM +0200, bearophile wrote:
> H. S. Teoh:
> 
> >Which means your code is at the mercy of the external library. Upstream updates a class, and suddenly a whole bunch of code is unnecessarily broken
> 
> How? (I think you are wrong again).
[...]

	struct S {
		int x;
	}
	void main() {
		int y;
		S s;

		with(s) {
			x = 1;
			y = 2;
		}
	}

This works. Now suppose S is updated to:

	struct S {
		int x;
		int y;
	}

Now the program fails to compile because S.y conflicts with the local y.

This is bad because unrelated code is broken just by changing S: it breaks encapsulation. This is just a small example; imagine if a lot of code uses S. Many places may break when S changes just because they happen to use the wrong local variable names.

Whereas if you had _not_ used with, this is a non-problem, since you'd be referring to s.x, and the fact that S now has a new member does not break any existing code regardless of how it was named.


T

-- 
People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANG
April 30, 2012
H. S. Teoh:

> This is bad because unrelated code is broken just by changing S: it
> breaks encapsulation. This is just a small example; imagine if a lot of
> code uses S. Many places may break when S changes just because they
> happen to use the wrong local variable names.

But it's a kind of safe breaking, it doesn't cause a lot of silent bugs.
I have found with useful in many situation to reduce the noise in my code.

Bye,
bearophile
April 30, 2012
On Mon, Apr 30, 2012 at 01:04:01PM -0400, Jonathan M Davis wrote: [...]
> And while I obviously can't say for certain what Walter intended, it was my impression that the point of this thread was more out of curiosity and for "lessons learned" from designing D than to actually make any changes to the language right now (especially when you consider how much Walter hates breaking backwards compatibility). But obviously, he'd have to clarify for us to know for sure.
[...]

It would be unwise to make major changes to the language at this point. Personally I'd like to see the comma operator removed, but people keep saying it will break existing code, so that's probably not going to happen in D2. D3 perhaps will be able to clean up a lot of this mess.

And frankly, most of the responses on this thread (including my own, I'll admit) are more wishlist items than the truly "redundant" features that Walter referred to initially.

And I have to say that in spite of little annoyances here and there, D2 is still the closest to my ideal programming language, and that's unlikely to change anytime soon. What we really need to focus on now is to hone the existing features, clean up the bugs, and improve the implementation, rather than continue to introduce new features and breaking changes. Existing features really need to Just Work(tm). We will drive away many potential D users by incomplete/buggy implementation of advertised features.


T

-- 
There are three kinds of people in the world: those who can count, and those who can't.
April 30, 2012
On 30-04-2012 19:05, H. S. Teoh wrote:
> On Mon, Apr 30, 2012 at 06:54:31PM +0200, bearophile wrote:
>> H. S. Teoh:
>>
>>> Which means your code is at the mercy of the external library.
>>> Upstream updates a class, and suddenly a whole bunch of code is
>>> unnecessarily broken
>>
>> How? (I think you are wrong again).
> [...]
>
> 	struct S {
> 		int x;
> 	}
> 	void main() {
> 		int y;
> 		S s;
>
> 		with(s) {
> 			x = 1;
> 			y = 2;
> 		}
> 	}
>
> This works. Now suppose S is updated to:
>
> 	struct S {
> 		int x;
> 		int y;
> 	}
>
> Now the program fails to compile because S.y conflicts with the local y.
>
> This is bad because unrelated code is broken just by changing S: it
> breaks encapsulation. This is just a small example; imagine if a lot of
> code uses S. Many places may break when S changes just because they
> happen to use the wrong local variable names.
>
> Whereas if you had _not_ used with, this is a non-problem, since you'd
> be referring to s.x, and the fact that S now has a new member does not
> break any existing code regardless of how it was named.
>
>
> T
>

You always risk breaking *something* when you change an interface, whether it's through adding or removing members. The problem you point out is not at all specific to with. Consider UFCS: You have struct S and free function foo operating on S. Upstream now adds a method foo to S.

-- 
- Alex