Re: Casting non-aliased mutable arrays to immutable in return values

2017-08-29 Thread Nordlöw via Digitalmars-d-learn
On Tuesday, 29 August 2017 at 16:41:48 UTC, Jonathan M Davis 
wrote:
Regardless, using assumeUnique or using a pure function to 
construct the object and implicitly convert it to immutable 
works for types in general.


- Jonathan M Davis


I'm, as always, grateful for your thorough answers, Jonathan.

Thank you.


Re: Casting non-aliased mutable arrays to immutable in return values

2017-08-29 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, August 29, 2017 16:09:17 Per Nordlöw via Digitalmars-d-learn 
wrote:
> Is it recommended to cast an unaliased array to `immutable` after
> it has been initialized?
>
> The reason for asking is that I would like the following function
>
> void[] rawReadNullTerminated(string path)
>  @safe
> {
>  import std.stdio : File;
>  auto file = File(path, `rb`);
>
>  import std.array : uninitializedArray;
>  ubyte[] data = uninitializedArray!(ubyte[])(file.size + 1);
>  file.rawRead(data);
>  data[file.size] = 0; // null terminator for sentinel
>
>  return data;// TODO can we cast this to
> `immutable(void)[]`?
> }
>
> to have an immutable return type.
>
> I'm aware of that I need to verify the contexts as UTF-8 if I
> want to treat it as text.

It's perfectly legitimate to construct an object as mutable and then cast it
to immutable if there are no other mutable references to it - that's what
std.exception.assumeUnique is for. It does the cast for you while
documenting your intent. However, the better solution if you can do it is to
create the object in a pure function that returns it. Then, it can be
implicitly converted to immutable so long as the compiler can guarantee that
the return value was not passed to the function. In this particular case,
you'd probably create a pure, nested function that took the File object and
returned the array.

Now, as for immutable(void)[], that seems pretty weird to me. Normally, when
folks use void[], it doesn't have any qualifiers on it. But I don't know
that there's actually a problem using qualifiers on it. Certainly, it
compiles. I'd probably just use immutable(ubyte)[] and not anything with
void, but this is obviously just a snippet of your code, and I have no idea
what the rest of it is doing, so something with void instead of ubyte may
very well be the correct solution. You'll obviously have to be the judge of
that. But pretty much the only time that I'd use any kind of void array
though is when accepting arbitrary arrays of data that is going to be
converted to bytes (e.g. for a socket). I wouldn't pass it around. I don't
know what other folks would do though.

Regardless, using assumeUnique or using a pure function to construct the
object and implicitly convert it to immutable works for types in general.

- Jonathan M Davis




Re: Casting non-aliased mutable arrays to immutable in return values

2017-08-29 Thread Ali Çehreli via Digitalmars-d-learn

On 08/29/2017 09:09 AM, Per Nordlöw wrote:

Is it recommended to cast an unaliased array to `immutable` after it has
been initialized?

The reason for asking is that I would like the following function

void[] rawReadNullTerminated(string path)
@safe
{
import std.stdio : File;
auto file = File(path, `rb`);

import std.array : uninitializedArray;
ubyte[] data = uninitializedArray!(ubyte[])(file.size + 1);
file.rawRead(data);
data[file.size] = 0; // null terminator for sentinel

return data;// TODO can we cast this to
`immutable(void)[]`?
}

to have an immutable return type.

I'm aware of that I need to verify the contexts as UTF-8 if I want to
treat it as text.


Yes and assumeUnique does exactly that:

  https://dlang.org/library/std/exception/assume_unique.html

Further, if your function is pure, the cast is implicit for the caller:

void[] foo() pure {
return new void[](10);
}

void main() {
void[] a = foo();
immutable(void)[] b = foo();// works
}

Ali



Casting non-aliased mutable arrays to immutable in return values

2017-08-29 Thread Per Nordlöw via Digitalmars-d-learn
Is it recommended to cast an unaliased array to `immutable` after 
it has been initialized?


The reason for asking is that I would like the following function

void[] rawReadNullTerminated(string path)
@safe
{
import std.stdio : File;
auto file = File(path, `rb`);

import std.array : uninitializedArray;
ubyte[] data = uninitializedArray!(ubyte[])(file.size + 1);
file.rawRead(data);
data[file.size] = 0; // null terminator for sentinel

return data;// TODO can we cast this to 
`immutable(void)[]`?

}

to have an immutable return type.

I'm aware of that I need to verify the contexts as UTF-8 if I 
want to treat it as text.