April 30, 2012
On 04/30/2012 05:36 PM, H. S. Teoh wrote:
> On Sun, Apr 29, 2012 at 11:55:43PM -0700, Jonathan M Davis wrote:
> [...]
>> Honestly, I don't think that you _can_ take much from this thread
>> other than the fact that pretty _every_ feature is wanted and used by
>> someone, even if other people hate it. Pretty much every feature
>> listed as undesirable by someone was listed as desirable by someone
>> else.
> [...]
>
> So far, I've not seen a single response in favor of keeping the comma
> operator.
>
>
> T
>

I think I use it about every 60 lines of code. Also, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.
April 30, 2012
On 04/30/2012 08:46 PM, Timon Gehr wrote:
> On 04/30/2012 05:36 PM, H. S. Teoh wrote:
>> On Sun, Apr 29, 2012 at 11:55:43PM -0700, Jonathan M Davis wrote:
>> [...]
>>> Honestly, I don't think that you _can_ take much from this thread
>>> other than the fact that pretty _every_ feature is wanted and used by
>>> someone, even if other people hate it. Pretty much every feature
>>> listed as undesirable by someone was listed as desirable by someone
>>> else.
>> [...]
>>
>> So far, I've not seen a single response in favor of keeping the comma
>> operator.
>>
>>
>> T
>>
>
> I think I use it about every 60 lines of code.

(outside for)

> Also, I don't think it
> should be removed for the sake of removing it. If it is removed, the
> syntax should be reused.

April 30, 2012
On 04/30/2012 04:47 AM, H. S. Teoh wrote:
> On Sun, Apr 29, 2012 at 03:06:53AM +0200, bearophile wrote:
>> Jonathan M Davis:
>>
>>> * foreach_reverse is essentially redudant at this point (not to
>>> mention
>>> confusing if combined with delegates), since we have retro.
>>
>> retro() can't replace foreach_reverse until the front-end
>> demonstrability produces asm code equally efficient.
>> Loops _must_ be fully efficient, they are a basic language
>> construct, this is very important. Even foreach() is sometimes not
>> equally efficient as a for() in some cases...
> [...]
>
> IMO, the compiler needs to _aggressively_ inline opApply() delegates,
> unless it's impossible (e.g. opApply is recursive), or perhaps exceeds
> some reasonable size limit for loop inlining). It's rather disheartening
> to design a great abstract type for manipulating collections, only to
> have opApply always incur the overhead of allocating

Use a scope delegate in the opApply signature to avoid the allocation.

> and invoking a
> delegate _every loop iteration_, even when opApply is as simple as:
>
> 	int opApply(int delegate(ref T arg) dg) {
> 		someSetupCode();
> 		for (i=0; i<n; i++) {
> 			dg(element[i]);
> 		}
> 		someCleanupCode();
> 	}
>
> As far as I'm concerned, the compiler *should* just inline the whole
> thing (both opApply and the delegate body) when you write foreach(c;
> container) {...}. There's no reason for such a trivial loop to incur a
> call to a delegate every iteration.
>
> Powerful abstractions such as opApply need to be optimized to the max,
> so that D's generic programming capabilities can be a strong selling
> point.
>
>
> T
>

April 30, 2012
On 04/30/2012 04:21 AM, H. S. Teoh wrote:
> On Sun, Apr 29, 2012 at 01:46:25AM -0700, Jonathan M Davis wrote:
>> On Sunday, April 29, 2012 10:37:10 Timon Gehr wrote:
>>> Well, what if the programmer "knows" that foo does not change 'aa',
>>> but it actually does? Then there would possibly be a segmentation
>>> fault.  This implies that the 'in' operator cannot be used in @safe
>>> code. (Or there would have to be a special case, that allows 'in' if
>>> the result is directly cast to bool.)
>>
>> It's exactly as safe as any iterator or range which could be
>> invalidated - both of which can occur in safe code. Any of those could
>> blow up in entertaining ways if you use them after they've been
>> invalidated.
>>
>> Pointers are considered safe. It's pointer arithmetic which isn't.
> [...]
>
> I get that this discussion is about what type 'in' should return, but
> taking a step back, isn't it all moot because you could just use the
> .get() method?
>
>
> T
>

The AA might actually contain the provided default value, so 'get' is not always a good match.
April 30, 2012
On 04/30/2012 05:35 PM, H. S. Teoh wrote:
> On Mon, Apr 30, 2012 at 10:21:23AM +0200, bearophile wrote:
>> H. S. Teoh:
>>
>>> I think the correct solution here is to use alias. (If that doesn't
>>> work, then it should be made to work. It's a lot cleaner and doesn't
>>> introduce potentially nasty ambiguities into code,
>>
>> What ambiguities?
> [...]
>
> 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;
> 		}
> 	}
>
> [snip.]

You probably should try compiling that code. ;)
April 30, 2012
On 04/30/2012 07:05 PM, 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

It is not unrelated.

> is broken just by changing S: it breaks encapsulation.

No it does not. Changing an interface is bound to break code.

> 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.
>

That is an extremely constructed argument. I cannot imagine that this will ever be a problem in practice.


> 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.
>

int* x = cast(int*)&s;
int y = *x;
S t = *cast(S*)&y;

static if(!is(typeof(S.y)){ ... }




April 30, 2012
On 4/30/12, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> Then
> you can write:
>
> 	uint[] a = [
> 		2: 100,
> 		10: 200
> 	]
>
> and it will be equivalent to:
>
> 	uint[] a = [0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200];

But you can already use this syntax right now?
April 30, 2012
On 04/30/2012 05:13 PM, Alex Rønne Petersen wrote:
> On 30-04-2012 12:18, foobar wrote:
>> Meta comment: C++ is the spawn of the devil so I don't accept anything
>> related to c++ as a valid argument.
>>
>> On Sunday, 29 April 2012 at 20:09:34 UTC, Alex Rønne Petersen wrote:
>> [...]
>>>>
>>>> I have used D and didn't claim that foreach isn't useful.
>>>> What I said that is that it belongs in the library, NOT the language.
>>>
>>> Yeah, we tried that in C++. It sucked.
>>
>> See meta comment above.
>>
>>>
>>> The reason it works for many functional languages is that they have
>>> even more terse syntax than D. It would suck to make foreach a
>>> function in D.
>>>
>>
>> D wants to support functional programming. That means we should provide
>> whatever is necessary to write functional style code including foreach
>> methods. IF D can't properly implement a FP foreach method (And IMO it
>> *can*) than we have failed.
>
> Of course it can, but not with type inference, unless you templatize it.
> That is:
>
> void forEach(alias fun, R)(R range)
> {
> // ...
> }
>
> enjoys type inference: forEach!(item => foo(item))(myRange);
>
> But this doesn't:
>
> void forEach(R)(R range, scope void delegate(ElementType!R) dg)
> {
> // ...
> }
>
> This won't work: forEach(myRange, item => foo(item));
>
> You have to do: forEach(myRange, (ElementType!(typeof(myRange)) =>
> foo(item));
>
> which, frankly, sucks.
>

I agree. It is due to the fact that currently actually no inference takes place, it is just simple deduction. It shouldn't be very hard to add that functionality.

April 30, 2012
On Monday, 30 April 2012 at 18:46:02 UTC, Timon Gehr wrote:
> On 04/30/2012 05:36 PM, H. S. Teoh wrote:
>> So far, I've not seen a single response in favor of keeping the comma
>> operator.
> I think I use it about every 60 lines of code. Also, I don't think it should be removed for the sake of removing it. If it is removed, the syntax should be reused.

Care to show some examples?

David
April 30, 2012
On 4/30/12, SomeDude <lovelydear@mailmetrash.com> wrote:
> I'd like to have a bit of an idea of how
> fast the compilers really are.

Personally my gripe with compilation times is that I get very used to having fast build times where I can go through an edit+compile+run cycle really fast, but after a while build times get slower (especially when templates get in the mix) and this really throws me off. Sometimes I wish I could just interpret D code at runtime just to save on compilation time, because I might just be testing the semantics of code and not necessarily its performance at a time.