www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - makeIndex not working

reply Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
I'm confused, what am I doing wrong here? This example came from the 
std.algorithm documentation.

import std.algorithm;

void main()
{
     immutable int[] arr = [ 2, 3, 1, 5, 0 ]; // index using pointers
     auto index1 = new immutable(int)*[arr.length];
     makeIndex!("a < b")(arr, index1);
}

Error is:

main.d(7): Error: template std.algorithm.makeIndex(alias less = "a < 
b",SwapStrategy ss = SwapStrategy.unstable,Range,RangeIndex) if 
(isForwardRange!(Range) && isRandomAccessRange!(RangeIndex) && 
is(ElementType!(RangeIndex) : ElementType!(Range)*)) does not match any 
function template declaration
main.d(7): Error: template std.algorithm.makeIndex(alias less = "a < 
b",SwapStrategy ss = SwapStrategy.unstable,Range,RangeIndex) if 
(isForwardRange!(Range) && isRandomAccessRange!(RangeIndex) && 
is(ElementType!(RangeIndex) : ElementType!(Range)*)) cannot deduce 
template function from argument types !("a < 
b")(immutable(int[]),immutable(int)*[])
main.d(7): Error: template instance errors instantiating template
Jul 02 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Johann MacDonagh:

 I'm confused, what am I doing wrong here?

I think that Phobos needs way more&better unittests. I think the error you receive reduces to this: import std.range: isForwardRange; void foo(R)(R r) if (isForwardRange!R) {} void main() { immutable arr = [1, 2]; foo(arr); } Bye, bearophile
Jul 02 2011
parent reply Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 7/2/2011 9:00 PM, bearophile wrote:
 Johann MacDonagh:

 I'm confused, what am I doing wrong here?

I think that Phobos needs way more&better unittests. I think the error you receive reduces to this: import std.range: isForwardRange; void foo(R)(R r) if (isForwardRange!R) {} void main() { immutable arr = [1, 2]; foo(arr); } Bye, bearophile

Strangely enough there is a unit test for this... https://github.com/D-Programming-Language/phobos/blob/phobos-2.053/std/algorithm.d#L6742 Does this code fail to compile for you too? I want to make sure I didn't mess up my config here.
Jul 02 2011
next sibling parent reply Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 7/2/2011 9:00 PM, Johann MacDonagh wrote:
 On 7/2/2011 9:00 PM, bearophile wrote:
 Johann MacDonagh:

 I'm confused, what am I doing wrong here?

I think that Phobos needs way more&better unittests. I think the error you receive reduces to this: import std.range: isForwardRange; void foo(R)(R r) if (isForwardRange!R) {} void main() { immutable arr = [1, 2]; foo(arr); } Bye, bearophile

Strangely enough there is a unit test for this... https://github.com/D-Programming-Language/phobos/blob/phobos-2.053/std/algorithm.d#L6742 Does this code fail to compile for you too? I want to make sure I didn't mess up my config here.

Ah, here we go: http://d.puremagic.com/issues/show_bug.cgi?id=6148 Replacing immutable with auto works. I'm still confused how the phobos unit tests pass though...
Jul 02 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Jonathan M Davis wrote:
 The range has to be mutable.

Is there any easy way around this, aside from casting away the outer immutable? It's a very annoying limitation that doesn't really have to be there - I believe the language itself would let you pass immutable int[] to a regular function that expects immutable(int)[], since the outermost reference is passed by value anyway.
Jul 02 2011
next sibling parent reply Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 7/2/2011 10:42 PM, Adam D. Ruppe wrote:
 Jonathan M Davis wrote:
 The range has to be mutable.

Is there any easy way around this, aside from casting away the outer immutable? It's a very annoying limitation that doesn't really have to be there - I believe the language itself would let you pass immutable int[] to a regular function that expects immutable(int)[], since the outermost reference is passed by value anyway.

Just the pointer is passed by value, referencing elements in the array mutate the source.
Jul 02 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Johann MacDonagh wrote:
 Just the pointer is passed by value, referencing elements in the
 array mutate the source.

That's true, but when just moving through a range, the pointer is the only thing that changes. The stuff it points to can still be immutable.
Jul 02 2011
prev sibling parent Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 7/2/2011 10:42 PM, Adam D. Ruppe wrote:
 Jonathan M Davis wrote:
 The range has to be mutable.

Is there any easy way around this, aside from casting away the outer immutable? It's a very annoying limitation that doesn't really have to be there - I believe the language itself would let you pass immutable int[] to a regular function that expects immutable(int)[], since the outermost reference is passed by value anyway.

Oh, I misread your comment. I agree, but I bet you run into issues when it comes to appending data to your newly casted immutable(int)[] reference (any appending would require a relocation). I should probably re-read the D-slices article.
Jul 02 2011
prev sibling parent Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 7/2/2011 10:22 PM, Jonathan M Davis wrote:
 On 2011-07-02 18:14, Johann MacDonagh wrote:
 On 7/2/2011 9:00 PM, Johann MacDonagh wrote:
 On 7/2/2011 9:00 PM, bearophile wrote:
 Johann MacDonagh:
 I'm confused, what am I doing wrong here?

I think that Phobos needs way more&better unittests. I think the error you receive reduces to this: import std.range: isForwardRange; void foo(R)(R r) if (isForwardRange!R) {} void main() { immutable arr = [1, 2]; foo(arr); } Bye, bearophile

Strangely enough there is a unit test for this... https://github.com/D-Programming-Language/phobos/blob/phobos-2.053/std/al gorithm.d#L6742 Does this code fail to compile for you too? I want to make sure I didn't mess up my config here.

Ah, here we go: http://d.puremagic.com/issues/show_bug.cgi?id=6148 Replacing immutable with auto works. I'm still confused how the phobos unit tests pass though...

That's because they're using immutable(int)[], not immutable int[]. The elements in the range are immutable, but the range is not. Whereas with immutable int[], the whole thing is immutable, so it doesn't work. The range has to be mutable. - Jonathan M Davis

Ah! How could I miss that? Some of the examples in std.algorithm should be updated to reflect this at least until that bug is fixed.
Jul 02 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-07-02 18:14, Johann MacDonagh wrote:
 On 7/2/2011 9:00 PM, Johann MacDonagh wrote:
 On 7/2/2011 9:00 PM, bearophile wrote:
 Johann MacDonagh:
 I'm confused, what am I doing wrong here?

I think that Phobos needs way more&better unittests. I think the error you receive reduces to this: import std.range: isForwardRange; void foo(R)(R r) if (isForwardRange!R) {} void main() { immutable arr = [1, 2]; foo(arr); } Bye, bearophile

Strangely enough there is a unit test for this... https://github.com/D-Programming-Language/phobos/blob/phobos-2.053/std/al gorithm.d#L6742 Does this code fail to compile for you too? I want to make sure I didn't mess up my config here.

Ah, here we go: http://d.puremagic.com/issues/show_bug.cgi?id=6148 Replacing immutable with auto works. I'm still confused how the phobos unit tests pass though...

That's because they're using immutable(int)[], not immutable int[]. The elements in the range are immutable, but the range is not. Whereas with immutable int[], the whole thing is immutable, so it doesn't work. The range has to be mutable. - Jonathan M Davis
Jul 02 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-07-02 19:42, Adam D. Ruppe wrote:
 Jonathan M Davis wrote:
 The range has to be mutable.

Is there any easy way around this, aside from casting away the outer immutable? It's a very annoying limitation that doesn't really have to be there - I believe the language itself would let you pass immutable int[] to a regular function that expects immutable(int)[], since the outermost reference is passed by value anyway.

The problem is how the type is determined with templates. The _exact_ type is used. So, instead of generating a function which takes immutable(int)[], the compiler generates a function which takes an immutable int[], because you passed it an immutable int[], not an immutable(int)[]. And it doesn't work to iterate over an immutable int[], so the function fails to compile. It's the same reason why you can't use static arrays with range-based functions unless you slice them. They don't work when the type is a static array, since you can't pop elements off of a static array. If the compiler were smart enough to use immutable(int)[] instead of immutable int[], and to use a dynamic array instead of a static one when choosing the type for the template, then the problem would be solved. But it isn't that smart. There are at least a couple of enhancement requests which relate to the issue, and it may be resolved at some point, but as long as the compiler uses the _exact_ type given for the template even when a more relaxed type would work, you're not going to be able to pass immutable arrays or static arrays to templated functions. - Jonathan M Davis
Jul 03 2011