Jump to page: 1 2
Thread overview
Why is immutable not possible as a result of a reduce expression?
Jan 05, 2013
Michael Engelhardt
Jan 05, 2013
Simen Kjaeraas
Jan 05, 2013
monarch_dodra
Jan 06, 2013
Ali Çehreli
Jan 06, 2013
Jonathan M Davis
Jan 06, 2013
Ali Çehreli
Jan 06, 2013
Jonathan M Davis
Jan 06, 2013
Andrej Mitrovic
Jan 06, 2013
Jonathan M Davis
Jan 06, 2013
Andrej Mitrovic
Jan 06, 2013
Jonathan M Davis
January 05, 2013
Hi,
just playing around with the functional capabilities of D. One concept of the pure functional programming is that variables should not be reassigned, so the best(?) way to assure this is using immutable:

    immutable auto gen = sequence!("n");
    immutable auto seq = take(gen,10);
    immutable auto filtered = filter!("a % 3 == 0 || a % 5 ==0")(seq);
    immutable auto sum = reduce!("a+b")(filtered);

but the last line gives a compiler error:

Error: template instance std.algorithm.reduce!("a+b").reduce!(immutable(FilterResult!(unaryFun,immutable(Take!(immutable(Sequence!("n",Tuple!()))))))) error instantiating

It compiles and run as expected if I remove the immutable constraint on the reduce expression. So what is happening here? I thought reduce will create a new data structure containing the resulting values like filter and other operations too? That seems not to be the case, maybe someone could give me a deeper understanding of this.

Thanks in advance

Michael
January 05, 2013
On 2013-52-05 20:01, Michael Engelhardt <me@mindcrime-ilab.de> wrote:

> Hi,
> just playing around with the functional capabilities of D. One concept of the pure functional programming is that variables should not be reassigned, so the best(?) way to assure this is using immutable:
>
>      immutable auto gen = sequence!("n");
>      immutable auto seq = take(gen,10);
>      immutable auto filtered = filter!("a % 3 == 0 || a % 5 ==0")(seq);
>      immutable auto sum = reduce!("a+b")(filtered);
>
> but the last line gives a compiler error:
>
> Error: template instance std.algorithm.reduce!("a+b").reduce!(immutable(FilterResult!(unaryFun,immutable(Take!(immutable(Sequence!("n",Tuple!()))))))) error instantiating
>
> It compiles and run as expected if I remove the immutable constraint on the reduce expression. So what is happening here? I thought reduce will create a new data structure containing the resulting values like filter and other operations too? That seems not to be the case, maybe someone could give me a deeper understanding of this.

The reason is that ranges may not be immutable or const.

Ranges need to be mutated (popFront) to be iterable, and your filtered
range cannot be mutated, by virtue of being immutable. I'm surprised that
seq and filtered work, but I guess there may be specializations that
circumvent the problem.

In other words, remove immutable from the first three lines, and the
program should compile.

A little details is that immutable auto is unnecessary, as immutable
implies auto (the details are more complex, but that's the short version).
-- 
Simen
January 05, 2013
On Saturday, 5 January 2013 at 20:09:24 UTC, Simen Kjaeraas wrote:
>
> The reason is that ranges may not be immutable or const.
>
> Ranges need to be mutated (popFront) to be iterable, and your filtered
> range cannot be mutated, by virtue of being immutable. I'm surprised that
> seq and filtered work, but I guess there may be specializations that
> circumvent the problem.

No, they just make the erroneous assumption that copying strips immutablity. There are cases where this is true, but not always. The *only* time when this is true is with arrays, where "immutable(T[])" can be copied to a "immutable(T)[]". Even then, the compiler strips to top immutable of the type implicitly, so no extra code should be rolled out for it anyways...

IMO, the only sensible behavior when calling "auto filter!(immutable R)(r)" would be to return an "immutable Filter!R" initialized with r...
...but you'd have to do it with the actual "immutable constructor". Simply creating a Filter!R and then castng it to immutable would also be wrong.

Ditto for all other range types. I'll try and review them.
January 06, 2013
On 01/05/2013 12:09 PM, Simen Kjaeraas wrote:

> A little details is that immutable auto is unnecessary, as immutable
> implies auto (the details are more complex, but that's the short version).

It is true that the OP does not need auto when there is already immutable but does immutable really imply auto, or are they orthogonal?

Ali

P.S. I had wrongly assumed that D's auto was the same as C++11's auto and that it came from "automatic type deduction." That is not true in D. As in C and old C++, D's auto comes from "automatic storage duration." We still use it for automatic type deduction to make the syntax happy when there is no other keyword to put to the left of the symbol.

January 06, 2013
On Saturday, January 05, 2013 16:18:51 Ali Çehreli wrote:
> On 01/05/2013 12:09 PM, Simen Kjaeraas wrote:
>  > A little details is that immutable auto is unnecessary, as immutable
>  > implies auto (the details are more complex, but that's the short
> 
> version).
> 
> It is true that the OP does not need auto when there is already immutable but does immutable really imply auto, or are they orthogonal?
> 
> Ali
> 
> P.S. I had wrongly assumed that D's auto was the same as C++11's auto and that it came from "automatic type deduction." That is not true in D. As in C and old C++, D's auto comes from "automatic storage duration." We still use it for automatic type deduction to make the syntax happy when there is no other keyword to put to the left of the symbol.

D's auto _is_ automatic type deduction like in C++11. It's just that const, immutable, and enum also deduce the type if you don't give it (with the addition of making the type const or immutable in the cases of const and immutable).

auto a = 1;
const c = 1;
immutable i = 1;
enum e = 1;

all do type inferrence and all work just fine.

- Jonathan M Davis
January 06, 2013
On 01/05/2013 04:59 PM, Jonathan M Davis wrote:

> D's auto _is_ automatic type deduction like in C++11.

It must have changed in the last couple of years. I see that the documentation is now different:

  http://dlang.org/attribute.html#auto

It now says "The auto attribute is used when there are no other attributes and type inference is desired."

It used to be not the case. The historical evidence is still there in compiler error messages:

    auto auto a = 1;

Error: redundant storage class 'auto'

;)

Ali

January 06, 2013
On Saturday, January 05, 2013 17:15:51 Ali Çehreli wrote:
> On 01/05/2013 04:59 PM, Jonathan M Davis wrote:
>  > D's auto _is_ automatic type deduction like in C++11.
> 
> It must have changed in the last couple of years. I see that the documentation is now different:
> 
>    http://dlang.org/attribute.html#auto
> 
> It now says "The auto attribute is used when there are no other attributes and type inference is desired."
> 
> It used to be not the case. The historical evidence is still there in compiler error messages:
> 
>      auto auto a = 1;
> 
> Error: redundant storage class 'auto'
> 
> ;)

In D, the term storage class is used for pretty much any attribute on a variable which is not a type constructor and therefore affects the actual type (i.e. const and immutable). So, in that sense, auto _is_ a storage class, but the term is pretty meaningless. C and C++ have a stricter definition of the term storage class.

- Jonathan M Davis
January 06, 2013
On 1/6/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> In D, the term storage class is used for pretty much any attribute on a variable which is not a type constructor

This topic pops up in the newsgroups every once in a while[1]. Maybe we should properly document it in the docs, a special section on storage class vs type qualifier (or type constructor or whatever it's called).

There is documentation for function parameter storage classes[2], but that's about it.

1: http://www.digitalmars.com/d/archives/digitalmars/D/Definitive_list_of_storage_classes_164063.html 2: http://dlang.org/function.html#parameters
January 06, 2013
On Sunday, January 06, 2013 05:33:04 Andrej Mitrovic wrote:
> On 1/6/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > In D, the term storage class is used for pretty much any attribute on a variable which is not a type constructor
> 
> This topic pops up in the newsgroups every once in a while[1]. Maybe we should properly document it in the docs, a special section on storage class vs type qualifier (or type constructor or whatever it's called).
> 
> There is documentation for function parameter storage classes[2], but that's about it.
> 
> 1: http://www.digitalmars.com/d/archives/digitalmars/D/Definitive_list_of_stor age_classes_164063.html 2: http://dlang.org/function.html#parameters

Well, since no one (including Walter or Andrei) could give a propery definition for storage class last time I brought it up, I don't know what we'd put in the docs. If you or someone else can come up with something appropriate though, that would be great. It's clear which are type qualifiers / constructors, but everything else has to be inferred from that.

- Jonathan M Davis
January 06, 2013
On 1/6/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> If you or someone else

It's going to have to be someone else. When someone asks something on IRC/NG and another person responds with "it's because it's not a type constructor", or "it's not a storage class" I get completely thrown off and don't understand what they mean, exactly because there's no solid definition in the docs.
« First   ‹ Prev
1 2