www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can pure functions accept const parameters or only invariant ?

reply mastrost <titi.mastro free.fr> writes:
Hello,
I read in the doc that pure functions can only accept invariant parameters, but
it seems that const parameters are also accepted by the compiler. For instance:


import std.stdio;

class A{
    int x;
}

pure int f(const A a){
    //- as const is transitive, we cannot modify any part of 'a' from here.
    //  b u t:
    //- as 'a' is not invariant, it may be changed in the same time by a non
constant view of this
    //  same data
    return a.x;
}

void main(){
    A a= new A; //a is not invariant
    writefln(f(a));
}

So why is this code accepted by the compiler?
Dec 29 2008
parent reply Christopher Wright <dhasenan gmail.com> writes:
mastrost wrote:
 So why is this code accepted by the compiler?

I'm not sure whether it's intentional, but a pure function is correct for mutable input as well as invariant input (barring threading issues), so this avoids code duplication.
Dec 29 2008
next sibling parent reply mastrost <titi.mastro free.fr> writes:
Christopher Wright Wrote:

 mastrost wrote:
 So why is this code accepted by the compiler?

I'm not sure whether it's intentional, but a pure function is correct for mutable input as well as invariant input (barring threading issues), so this avoids code duplication.

Yes maybe, but it creates strange stuffs... you could have a pure function taking const inputs, another pure function taking invariant inputs, and of course the first one could not call the second one, even if it was called with invariant inputs.....I mean this would not be allowed: pure int g(invariant A a){ return a.x; } pure int f(const A a){ assert(is(typeof(a) == const(A))); //a is seen as const, even if a is in fact invariant return g(a); //error } Wich means that it is possible that a pure function can not call another one.
Dec 29 2008
parent mastrost <titi.mastro free.fr> writes:
Denis Koroskin Wrote:

 On Tue, 30 Dec 2008 03:37:55 +0300, mastrost <titi.mastro free.fr> wrote:
 
 Christopher Wright Wrote:

 mastrost wrote:
 So why is this code accepted by the compiler?

I'm not sure whether it's intentional, but a pure function is correct for mutable input as well as invariant input (barring threading issues), so this avoids code duplication.

Yes maybe, but it creates strange stuffs... you could have a pure function taking const inputs, another pure function taking invariant inputs, and of course the first one could not call the second one, even if it was called with invariant inputs.....I mean this would not be allowed: pure int g(invariant A a){ return a.x; } pure int f(const A a){ assert(is(typeof(a) == const(A))); //a is seen as const, even if a is in fact invariant return g(a); //error } Wich means that it is possible that a pure function can not call another one.

Does everyone still remember discussion we had some time ago about equivariant functions (http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=77729)? Perhaps, we could use a property of pure functions that they can accept all kind of input data (mutable, const and immutable) and still be correct and checked by compiler? Currently, we have to declare three distinct functions: pure invariant(char)[] trim(invariant(char)[] str); const(char)[] trim(const(char)[] str); char[] trim(char[] str); Could they be reduced to just one: pure char[] trim(char[] str); // ?

It is true that one should not duplicate code, but you can avoid that by using mixins. If we use only one declaration, then what is the use of the 'pure' keyword ? Anyway does anyone know what is the current behaviour in version 2.022 (why const is accepted in pure functions??) ?
Dec 30 2008
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 30 Dec 2008 03:37:55 +0300, mastrost <titi.mastro free.fr> wrote:

 Christopher Wright Wrote:

 mastrost wrote:
 So why is this code accepted by the compiler?

I'm not sure whether it's intentional, but a pure function is correct for mutable input as well as invariant input (barring threading issues), so this avoids code duplication.

Yes maybe, but it creates strange stuffs... you could have a pure function taking const inputs, another pure function taking invariant inputs, and of course the first one could not call the second one, even if it was called with invariant inputs.....I mean this would not be allowed: pure int g(invariant A a){ return a.x; } pure int f(const A a){ assert(is(typeof(a) == const(A))); //a is seen as const, even if a is in fact invariant return g(a); //error } Wich means that it is possible that a pure function can not call another one.

Does everyone still remember discussion we had some time ago about equivariant functions (http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=77729)? Perhaps, we could use a property of pure functions that they can accept all kind of input data (mutable, const and immutable) and still be correct and checked by compiler? Currently, we have to declare three distinct functions: pure invariant(char)[] trim(invariant(char)[] str); const(char)[] trim(const(char)[] str); char[] trim(char[] str); Could they be reduced to just one: pure char[] trim(char[] str); // ? Another example: class Matrix3x3 { pure ref float at(int row, int col) { return _values[row][col]; } float _values[3][3]; } The only problem here is that no modifier is applied to return value. It may mislead novices by giving false impression that function always accepts and returns mutable data. My suggestion was to attach 'same' modifier to both input and return type: pure same(char)[] trim(same(char)[] str); class Matrix3x3 { pure ref same(float) at(int row, int col) same(this) { return _values[row][col]; } float _values[3][3]; }
Dec 29 2008