September 21, 2013
On Friday, 20 September 2013 at 16:28:49 UTC, Joseph Rushton Wakeling wrote:
> I wouldn't single out DMD for criticism -- I don't know to what extent the underlying reasons overlap, but all the compilers cope less well with range-based material than they might in theory.
>
> The canonical example would be something like,
>
>     foreach (i; iota(10)) { ... }
>
> which in theory shouldn't be any slower than,
>
>     foreach (i; 0 .. 10) { ... }
>
> but in practice is, no matter what the compiler.

Chandler made a talk about missed optimization opportunities in LLVM some time ago visible here http://llvm.org/devmtg/2013-04/videos/carruth-hires.mov

You may also want to look at that one for some basics before : http://www.youtube.com/watch?v=eR34r7HOU14

What happen with range is that they do not fit that model properly. Range code often look like a tree (front calling subrange.front, popFront call subrange.popFront, etc . . .). At each inlining, front/popFront and firend become bigger and bigger to the point they aren't good inlining candidate. The compiler do not see that everything cancels out at the end.

The other big performance pitfall in LLVM with range are bug in the optimizer when it comes to aggregate store/load. I reported some of these and LLVM team seems willing to get rid of them because a lot of frontend generate them (notably gcc frontend). clang do not use them, so they got less attention in the first place.
September 21, 2013
On Friday, 20 September 2013 at 19:29:33 UTC, Andrei Alexandrescu wrote:
> I'm not sure such a conversion is needed all that often.
>

That has been a show stopper for several things I wanted to implement in SDC.

We need to be able to do that.
September 22, 2013
On Friday, 20 September 2013 at 16:28:49 UTC, Joseph Rushton Wakeling wrote:
[...]
> The canonical example would be something like,
>
>     foreach (i; iota(10)) { ... }
>
> which in theory shouldn't be any slower than,
>
>     foreach (i; 0 .. 10) { ... }
>
> but in practice is, no matter what the compiler.

Some compilers are unexpectedly smart in this case. I just benchmarked somewhat similar code with two version of the same function: one using a straight for loop, the other mixture of iota and "..". Plain for loop should be the fastest, right? Almost right. Here are the functions:

int e28_0(int N = 1002) {
	int diagNumber = 1;					
	int sum        = diagNumber;	

	for (int width = 2; width < N; width += 2)	
		for (int j = 0; j < 4; ++j) {			
			diagNumber += width;				
			sum        += diagNumber;			
		}

	return sum;
}

int e28_1(int N = 1002) {
	int diagNumber = 1;					
	int sum        = diagNumber;	

	foreach (width; iota(2, N, 2))
		foreach (_; 0..4) {			
			diagNumber += width;				
			sum        += diagNumber;			
		}

	return sum;
}

Here are the results:

GDC 4.8.1:     gdc-4.8 -m64 -march=native -fno-bounds-check -frename-registers -frelease -O3
669171001  830ns  e28_0
669171001  830ns  e28_1

DMD64 2.063.2: dmd -O -noboundscheck -inline -release
669171001  1115ns  e28_0
669171001  1958ns  e28_1

LDC 0.11.0: ldmd2 -m64 -O -noboundscheck -inline -release
669171001  454ns  e28_0
669171001  395ns  e28_1

September 23, 2013
On Friday, 20 September 2013 at 15:23:20 UTC, Paulo Pinto wrote:
> Am 20.09.2013 16:24, schrieb renoX:
>> That said, he made the same mistake as Haskell's authors: currying is a
>> *mathematical detail* which shouldn't obscure function type:
>> 'f: a->b->c' is less readable than 'f: a,b->c'.
>>
>> renoX
>
> That is standard in all languages of the ML family, not only Haskell.

I know, but 'standard' doesn't mean that it is a good idea..

renoX


September 23, 2013
On Monday, 23 September 2013 at 12:08:48 UTC, renoX wrote:
> On Friday, 20 September 2013 at 15:23:20 UTC, Paulo Pinto wrote:
>> Am 20.09.2013 16:24, schrieb renoX:
>>> That said, he made the same mistake as Haskell's authors: currying is a
>>> *mathematical detail* which shouldn't obscure function type:
>>> 'f: a->b->c' is less readable than 'f: a,b->c'.
>>>
>>> renoX
>>
>> That is standard in all languages of the ML family, not only Haskell.
>
> I know, but 'standard' doesn't mean that it is a good idea..
>
> renoX

I guess it depends on the reader, I always found it quite natural.

But then again, I enjoy ML languages since I learned Caml Light.

--
Paulo
September 24, 2013
On 09/23/2013 02:08 PM, renoX wrote:
> On Friday, 20 September 2013 at 15:23:20 UTC, Paulo Pinto wrote:
>> Am 20.09.2013 16:24, schrieb renoX:
>>> That said, he made the same mistake as Haskell's authors: currying is a
>>> *mathematical detail* which shouldn't obscure function type:
>>> 'f: a->b->c' is less readable than 'f: a,b->c'.
>>>
>>> renoX
>>
>> That is standard in all languages of the ML family, not only Haskell.
>
> I know, but 'standard' doesn't mean that it is a good idea..
>
> renoX
>
>

Neither does 'mathematical detail' mean it is obscure, unreadable or a mistake as you seem to imply.
September 24, 2013
On Tuesday, 24 September 2013 at 09:15:37 UTC, Timon Gehr wrote:
> On 09/23/2013 02:08 PM, renoX wrote:
>> On Friday, 20 September 2013 at 15:23:20 UTC, Paulo Pinto wrote:
>>> Am 20.09.2013 16:24, schrieb renoX:
>>>> That said, he made the same mistake as Haskell's authors: currying is a
>>>> *mathematical detail* which shouldn't obscure function type:
>>>> 'f: a->b->c' is less readable than 'f: a,b->c'.
>>>>
>>>> renoX
>>>
>>> That is standard in all languages of the ML family, not only Haskell.
>>
>> I know, but 'standard' doesn't mean that it is a good idea..
>>
>> renoX
>
> Neither does 'mathematical detail' mean it is obscure, unreadable or a mistake as you seem to imply.

I'm not sure you understood my point: a 'normal' function takes inputS and produce an output, in the notation: a,b->c you can clearly see the inputS and the output with a minimum of 'syntax noise' around them.
In the notation a -> b -> c, the 'syntax noise' is bigger (those arrows between the input parameters are much more 'heavy on the eye' than a quote), and what does it bring?
Nothing..

It's the notation which makes the function type less readable which I consider a mistake.

renoX
September 24, 2013
On Tuesday, 24 September 2013 at 11:32:18 UTC, renoX wrote:
> On Tuesday, 24 September 2013 at 09:15:37 UTC, Timon Gehr wrote:
>> On 09/23/2013 02:08 PM, renoX wrote:
>>> On Friday, 20 September 2013 at 15:23:20 UTC, Paulo Pinto wrote:
>>>> Am 20.09.2013 16:24, schrieb renoX:
>>>>> That said, he made the same mistake as Haskell's authors: currying is a
>>>>> *mathematical detail* which shouldn't obscure function type:
>>>>> 'f: a->b->c' is less readable than 'f: a,b->c'.
>>>>>
>>>>> renoX
>>>>
>>>> That is standard in all languages of the ML family, not only Haskell.
>>>
>>> I know, but 'standard' doesn't mean that it is a good idea..
>>>
>>> renoX
>>
>> Neither does 'mathematical detail' mean it is obscure, unreadable or a mistake as you seem to imply.
>
> I'm not sure you understood my point: a 'normal' function takes inputS and produce an output, in the notation: a,b->c you can clearly see the inputS and the output with a minimum of 'syntax noise' around them.
> In the notation a -> b -> c, the 'syntax noise' is bigger (those arrows between the input parameters are much more 'heavy on the eye' than a quote), and what does it bring?
> Nothing..
>
> It's the notation which makes the function type less readable which I consider a mistake.
>
> renoX

A 'normal' function in Haskell takes exactly one object and returns exactly one object. a -> b -> c is actually a -> (b -> c) because -> is right-associative. It's perfectly readable for people in the Haskell subculture. You'll have hard time convincing them otherwise :)
September 24, 2013
On Tuesday, 24 September 2013 at 12:06:22 UTC, Max Samukha wrote:
>
> A 'normal' function in Haskell takes exactly one object and returns exactly one object. a -> b -> c is actually a -> (b -> c) because -> is right-associative. It's perfectly readable for people in the Haskell subculture. You'll have hard time convincing them otherwise :)

Isn't function application in Haskell left-associative? (I might be confusing terms as I am just learning it)
September 24, 2013
On Tuesday, 24 September 2013 at 12:09:28 UTC, Szymon Gatner wrote:
> On Tuesday, 24 September 2013 at 12:06:22 UTC, Max Samukha wrote:
>>
>> A 'normal' function in Haskell takes exactly one object and returns exactly one object. a -> b -> c is actually a -> (b -> c) because -> is right-associative. It's perfectly readable for people in the Haskell subculture. You'll have hard time convincing them otherwise :)
>
> Isn't function application in Haskell left-associative? (I might be confusing terms as I am just learning it)

So am I.

Function application is left-associative. (f a b) is the equivalent of ((f a) b).

Arrow in the lambda types is right-associative. If you mentally add parens, then things like (a -> b -> c) -> [a] -> [b] -> [c] look less intimidating - (a -> (b -> c)) -> ([a] -> ([b] -> [c])). Well, they don't. But at least you can make some sense of them, sometimes. They definitely don't look more intimidating than D's template instantiations.