www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Static array as immutable

reply Ivan Trombley <itrombley dot-borg.org> writes:
Is there some way that I can make this array immutable?

   static float[256] ga = void;
   static foreach (i; 0 .. 256)
       ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
Dec 11 2017
next sibling parent reply Radu <void null.pt> writes:
On Tuesday, 12 December 2017 at 07:33:47 UTC, Ivan Trombley wrote:
 Is there some way that I can make this array immutable?

   static float[256] ga = void;
   static foreach (i; 0 .. 256)
       ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
Check https://dlang.org/phobos/std_exception.html#assumeUnique
Dec 11 2017
parent Ivan Trombley <itrombley dot-borg.org> writes:
On Tuesday, 12 December 2017 at 07:44:55 UTC, Radu wrote:
 On Tuesday, 12 December 2017 at 07:33:47 UTC, Ivan Trombley 
 wrote:
 Is there some way that I can make this array immutable?

   static float[256] ga = void;
   static foreach (i; 0 .. 256)
       ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
Check https://dlang.org/phobos/std_exception.html#assumeUnique
Thanks.
Dec 12 2017
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via Digitalmars-d-learn 
wrote:
 Is there some way that I can make this array immutable?

    static float[256] ga = void;
    static foreach (i; 0 .. 256)
        ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
If you want anything to be immutable, you either have to initialize it directly or give it a value in a static constructor (and the static constructor solution won't work for local variables). So, you'd need to do something like static immutable float[256] ga = someFuncThatGeneratesGA(); If the function is pure, and there's no way that the return value was passed to the function, then its return value can be assigned to something of any mutability, since the compiler knows that there are no other references to it, and it can implicitly cast it, or if the type is a value type (as in this case), then you just get a copy, and mutability isn't an issue. Alternatively to using a pure function, you can use std.exception.assumeUnique to cast to immutable, but that relies on you being sure that there are no other references to the data, and it may not work at compile-time, since casting is a lot more restrictive during CTFE. So, in general, using a pure function is preferable to assumeUnique. - Jonathan M Davis
Dec 12 2017
parent reply Ivan Trombley <itrombley dot-borg.org> writes:
On Tuesday, 12 December 2017 at 09:48:09 UTC, Jonathan M Davis 
wrote:
 On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via 
 Digitalmars-d-learn wrote:
 Is there some way that I can make this array immutable?

    static float[256] ga = void;
    static foreach (i; 0 .. 256)
        ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
If you want anything to be immutable, you either have to initialize it directly or give it a value in a static constructor (and the static constructor solution won't work for local variables). So, you'd need to do something like static immutable float[256] ga = someFuncThatGeneratesGA(); If the function is pure, and there's no way that the return value was passed to the function, then its return value can be assigned to something of any mutability, since the compiler knows that there are no other references to it, and it can implicitly cast it, or if the type is a value type (as in this case), then you just get a copy, and mutability isn't an issue. Alternatively to using a pure function, you can use std.exception.assumeUnique to cast to immutable, but that relies on you being sure that there are no other references to the data, and it may not work at compile-time, since casting is a lot more restrictive during CTFE. So, in general, using a pure function is preferable to assumeUnique. - Jonathan M Davis
Ah, it doesn't work. I get this error using the ^^ operator: /usr/include/dmd/phobos/std/math.d(5724,27): Error: cannot convert &real to ubyte* at compile time /usr/include/dmd/phobos/std/math.d(6629,24): called from here: signbit(x) /usr/include/dmd/phobos/std/math.d(6756,16): called from here: impl(cast(real)x, cast(real)y) :(
Dec 12 2017
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, December 12, 2017 10:35:15 Ivan Trombley via Digitalmars-d-learn 
wrote:
 On Tuesday, 12 December 2017 at 09:48:09 UTC, Jonathan M Davis

 wrote:
 On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via

 Digitalmars-d-learn wrote:
 Is there some way that I can make this array immutable?

    static float[256] ga = void;
    static foreach (i; 0 .. 256)

        ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
If you want anything to be immutable, you either have to initialize it directly or give it a value in a static constructor (and the static constructor solution won't work for local variables). So, you'd need to do something like static immutable float[256] ga = someFuncThatGeneratesGA(); If the function is pure, and there's no way that the return value was passed to the function, then its return value can be assigned to something of any mutability, since the compiler knows that there are no other references to it, and it can implicitly cast it, or if the type is a value type (as in this case), then you just get a copy, and mutability isn't an issue. Alternatively to using a pure function, you can use std.exception.assumeUnique to cast to immutable, but that relies on you being sure that there are no other references to the data, and it may not work at compile-time, since casting is a lot more restrictive during CTFE. So, in general, using a pure function is preferable to assumeUnique. - Jonathan M Davis
Ah, it doesn't work. I get this error using the ^^ operator: /usr/include/dmd/phobos/std/math.d(5724,27): Error: cannot convert &real to ubyte* at compile time /usr/include/dmd/phobos/std/math.d(6629,24): called from here: signbit(x) /usr/include/dmd/phobos/std/math.d(6756,16): called from here: impl(cast(real)x, cast(real)y) :(
Well, if the code you need to initialize a variable can't be run at compile time, then that variable can't be a variable that needs to be initialized at compile time and be immutable. - Jonathan M Davis
Dec 12 2017
parent reply Nathan S. <no.public.email example.com> writes:
On Tuesday, 12 December 2017 at 11:37:40 UTC, Jonathan M Davis 
wrote:
 On Tuesday, December 12, 2017 10:35:15 Ivan Trombley via 
 Digitalmars-d-learn wrote:
 On Tuesday, 12 December 2017 at 09:48:09 UTC, Jonathan M Davis

 wrote:
 On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via

 Digitalmars-d-learn wrote:
 Is there some way that I can make this array immutable?

    static float[256] ga = void;
    static foreach (i; 0 .. 256)

        ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
If you want anything to be immutable, you either have to initialize it directly or give it a value in a static constructor (and the static constructor solution won't work for local variables). So, you'd need to do something like static immutable float[256] ga = someFuncThatGeneratesGA(); If the function is pure, and there's no way that the return value was passed to the function, then its return value can be assigned to something of any mutability, since the compiler knows that there are no other references to it, and it can implicitly cast it, or if the type is a value type (as in this case), then you just get a copy, and mutability isn't an issue. Alternatively to using a pure function, you can use std.exception.assumeUnique to cast to immutable, but that relies on you being sure that there are no other references to the data, and it may not work at compile-time, since casting is a lot more restrictive during CTFE. So, in general, using a pure function is preferable to assumeUnique. - Jonathan M Davis
Ah, it doesn't work. I get this error using the ^^ operator: /usr/include/dmd/phobos/std/math.d(5724,27): Error: cannot convert &real to ubyte* at compile time /usr/include/dmd/phobos/std/math.d(6629,24): called from here: signbit(x) /usr/include/dmd/phobos/std/math.d(6756,16): called from here: impl(cast(real)x, cast(real)y) :(
Well, if the code you need to initialize a variable can't be run at compile time, then that variable can't be a variable that needs to be initialized at compile time and be immutable. - Jonathan M Davis
While what you're saying is true, exponentiation not being runnable at compile-time is a defect and I would assume a regression. I'll file a bug report. FWIW when trying to run the following with DMD v2.077.1 I get: ``` void main(string[] args) { import std.stdio; enum e = (1.0 / 255.0f) ^^ (1 / 2.2f); writeln("e = ", e); } ``` => [...]/dmd/std/math.d(440): Error: y.vu[4] is used before initialized [...]/dmd/std/math.d(413): originally uninitialized here [...]/dmd/std/math.d(4107): called from here: floorImpl(x) [...]/dmd/std/math.d(2373): called from here: floor(x + 0.5L) [...]/dmd/std/math.d(2110): called from here: exp2Impl(x) [...]/dmd/std/math.d(6743): called from here: exp2(yl2x(x, y)) [...]/dmd/std/math.d(6756): called from here: impl(cast(real)x, cast(real)y)
Dec 12 2017
parent reply Ivan Trombley <itrombley dot-borg.org> writes:
On Tuesday, 12 December 2017 at 15:30:01 UTC, Nathan S. wrote:
 While what you're saying is true, exponentiation not being 
 runnable at compile-time is a defect and I would assume a 
 regression. I'll file a bug report. FWIW when trying to run the 
 following with DMD v2.077.1 I get:

 ```
 void main(string[] args)
 {
     import std.stdio;
     enum e = (1.0 / 255.0f) ^^ (1 / 2.2f);
     writeln("e = ", e);
 }
 ```

 =>

 [...]/dmd/std/math.d(440): Error: y.vu[4] is used before 
 initialized
 [...]/dmd/std/math.d(413):        originally uninitialized here
 [...]/dmd/std/math.d(4107):        called from here: 
 floorImpl(x)
 [...]/dmd/std/math.d(2373):        called from here: floor(x + 
 0.5L)
 [...]/dmd/std/math.d(2110):        called from here: exp2Impl(x)
 [...]/dmd/std/math.d(6743):        called from here: 
 exp2(yl2x(x, y))
 [...]/dmd/std/math.d(6756):        called from here: 
 impl(cast(real)x, cast(real)y)
FWIW, if the exponent is an integer, I don't get an error.
Dec 12 2017
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Dec 12, 2017 at 06:06:48PM +0000, Ivan Trombley via Digitalmars-d-learn
wrote:
 On Tuesday, 12 December 2017 at 15:30:01 UTC, Nathan S. wrote:
 While what you're saying is true, exponentiation not being runnable
 at compile-time is a defect and I would assume a regression.
[...]
 FWIW, if the exponent is an integer, I don't get an error.
I don't think exponentiation with non-integer exponents have ever been supported at compile-time. It requires evaluating exp(x) for non-integer x, which, AFAIK, has never been supported at compile-time because the implementation of exp(x) requires constructs that the current CTFE engine doesn't support, namely, inline asm in older versions of std.math, or more recently, the need to access the binary representation of floats/doubles. Perhaps when Stefan Koch's new CTFE engine is ready for public consumption, we will be able to finally have std.math runnable in CTFE. T -- Latin's a dead language, as dead as can be; it killed off all the Romans, and now it's killing me! -- Schoolboy
Dec 12 2017