## digitalmars.D.learn - Why is immutable not possible as a result of a reduce expression?

"Michael Engelhardt" <me mindcrime-ilab.de> writes:
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.

Michael
Jan 05 2013
"Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
Jan 05 2013
"monarch_dodra" <monarchdodra gmail.com> writes:
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.
Jan 05 2013
=?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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.
Jan 05 2013
Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, January 05, 2013 16:18:51 Ali =C3=87ehreli wrote:
On 01/05/2013 12:09 PM, Simen Kjaeraas wrote:
> A little details is that immutable auto is unnecessary, as immutab=
le
> implies auto (the details are more complex, but that's the short
=20
version).
=20
It is true that the OP does not need auto when there is already
immutable but does immutable really imply auto, or are they orthogona=
l?
=20
Ali
=20
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 co= nst,=20 immutable, and enum also deduce the type if you don't give it (with the= =20 addition of making the type const or immutable in the cases of const an= d=20 immutable). auto a =3D 1; const c =3D 1; immutable i =3D 1; enum e =3D 1; all do type inferrence and all work just fine. - Jonathan M Davis
Jan 05 2013
=?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Jan 05 2013
Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, January 05, 2013 17:15:51 Ali =C3=87ehreli wrote:
On 01/05/2013 04:59 PM, Jonathan M Davis wrote:
> D's auto _is_ automatic type deduction like in C++11.
=20
It must have changed in the last couple of years. I see that the
documentation is now different:
=20
http://dlang.org/attribute.html#auto
=20
It now says "The auto attribute is used when there are no other
attributes and type inference is desired."
=20
It used to be not the case. The historical evidence is still there in=
compiler error messages:
=20
auto auto a =3D 1;
=20
Error: redundant storage class 'auto'
=20
;)
In D, the term storage class is used for pretty much any attribute on a= =20 variable which is not a type constructor and therefore affects the actu= al type=20 (i.e. const and immutable). So, in that sense, auto _is_ a storage clas= s, but=20 the term is pretty meaningless. C and C++ have a stricter definition of= the=20 term storage class. - Jonathan M Davis
Jan 05 2013
Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
Jan 05 2013
Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Jan 06 2013
Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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.
Jan 06 2013
Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, January 06, 2013 21:59:32 Andrej Mitrovic wrote:
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.
Well, I think that we can get a solid definiton for a type qualifier / constructor fairly easily, but storage class is harder, because there really isn't one. - Jonathan M Davis
Jan 06 2013