www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12282] New: Immutable result of std.array.array

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12282

           Summary: Immutable result of std.array.array
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: rejects-valid
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc


--- Comment #0 from bearophile_hugs eml.cc 2014-03-01 08:47:19 PST ---
I am not sure if this is an enhancement:


void main() {
    import std.array: array;
    const a = [1];
    immutable b = a.array;
}


DMD 2.066alpha gives:

test.d(4,20): Error: cannot implicitly convert expression (array(a)) of type
const(int)[] to immutable(int[])


Another example shows the same problem:

void main() pure {
    import std.range: transversal;
    import std.array: array;
    const m = [[1.0, 2.0], [3.0, 4.0]];
    immutable first = m.transversal(0).array;
}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12282


monarchdodra gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |monarchdodra gmail.com


--- Comment #1 from monarchdodra gmail.com 2014-03-09 14:00:09 PDT ---
I don't think that can work, at least, not without massive help from the
compiler, and the language itself. Let's forget `array` itself for a moment.

Basically, you want the `const(int)[]` to cast to `immutable(int)[]`. Both you
and I know that this conversion is not legal.

You are probably thinking: Since `array` is pure, then the "uniqueness" of the
result should make the cast possible?

Yes and no... The problem is that `array` *also* takes an array as an argument,
which may reference mutable data, making the function weakly pure. The language
has no way to know if the return value isn't aliasing something in the input
argument. Take this example

```D
void main()
{
    int a[];
    immutable b = array();     //OK
    immutable c = array(null); //OK
    immutable d = array(a);    //OK?
}

const(int[]) array(              ) pure {return (int[]).init;}
const(int[]) array(const(int[]) p) pure {return p;} 
```

Currently, 1) and 2) pass, but 3) fails. For a good reason.

So, unless the language gives us some sort of "noalias" for the return value, I
don't see how your request could be implemented.

The only way I see for it to work would be for `array` to *actually* return an
immutable when possible. But:
1) The code would be difficult to write.
2) It would break auto-inference, since the expected return is "const", and not
"immutable".

I'm not closing, because it is a valid request, but I don't see any way of
making it happen.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 09 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12282



--- Comment #2 from bearophile_hugs eml.cc 2014-03-09 14:26:13 PDT ---
(In reply to comment #1)

 I'm not closing, because it is a valid request, but I don't see any way of
 making it happen.

Thank you for your answers :-) In general if a request is impossible there's not much sense in keeping it open. But let's keep this open for some more time.
 const(int[]) array(              ) pure {return (int[]).init;}
 const(int[]) array(const(int[]) p) pure {return p;} 
 ```
 
 Currently, 1) and 2) pass, but 3) fails. For a good reason.
 
 So, unless the language gives us some sort of "noalias" for the return value,

If you have a function like this: int[] array(scope const int[] a) pure {} Or even like this: int[] array(scope int[] a) pure {} The input is const, so it can't be mutated, ints don't have indirections, and "scope" once implemented means the input data can't escape the array function. Is this enough to be able to cast the result to immutable? -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 09 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12282



--- Comment #3 from monarchdodra gmail.com 2014-03-09 14:37:18 PDT ---
(In reply to comment #2)
 If you have a function like this:
 
 int[] array(scope const int[] a) pure {}
 
 Or even like this:
 
 int[] array(scope int[] a) pure {}
 
 The input is const, so it can't be mutated, 

Isn't it only const with "in" ? Not that it makes an actual difference here.
 Is this enough to be able to cast the result to immutable?

Actually, maybe. It's the "help from the compiler, and the language itself" I was talking about, and the "noalias" type qualifier.
 ints don't have indirections, and
 "scope" once implemented means the input data can't escape the array function.

I'm not fluent with how `scope` would work, but I fear it would not work for generic types, which may themselves have indirections. Would this be legal? Or would it violate the "scope" constraint? int*[] array(scope int*[] a) pure {} -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 09 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12282



--- Comment #4 from bearophile_hugs eml.cc 2014-03-09 15:11:59 PDT ---
(In reply to comment #3)

 Isn't it only const with "in" ? Not that it makes an actual difference here.

"in" means "scope const". Currently scope is not implemented, there is no DIP and no one knows if and when it is coming.
 but I fear it would not work for
 generic types, which may themselves have indirections.

I think it can't work for generic types, unless D adds a region typing as Rust.
 Would this be legal? Or would it violate the "scope" constraint?
 
 int*[] array(scope int*[] a) pure {}

Kenji, Walter, Timon and Andrei are the few persons able to think about all the cases that can happen :) -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 09 2014