Thread overview
Runtime constant definitions
Sep 12, 2008
Lars Kyllingstad
Sep 12, 2008
Bill Baxter
Sep 12, 2008
Lars Kyllingstad
Sep 12, 2008
Frank Benoit
Sep 12, 2008
Lars Kyllingstad
Sep 12, 2008
Bill Baxter
September 12, 2008
Hi,

I'm trying to define a couple of constants that I want to be computed at run time. I have written the following code:

---

/// Square root of real-number precision.
final real REAL_EPSILON_SQRT;

/// Cube root of real-number precision.
final real REAL_EPSILON_CBRT;


static this()
{
    REAL_EPSILON_SQRT = sqrt(real.epsilon);
    REAL_EPSILON_CBRT = cbrt(real.epsilon);
}

---

Compiling this, I get the errors

scid/core.d:21: Error: cannot modify final variable 'REAL_EPSILON_SQRT'
scid/core.d:22: Error: cannot modify final variable 'REAL_EPSILON_CBRT'

where the lines 21 and 22 are the ones inside the curly braces. What's wrong?


Thanks,
Lars
September 12, 2008
On Fri, Sep 12, 2008 at 3:14 PM, Lars Kyllingstad <public@kyllingen.nospamnet> wrote:
> Hi,
>
> I'm trying to define a couple of constants that I want to be computed at run time. I have written the following code:
>
> ---
>
> /// Square root of real-number precision.
> final real REAL_EPSILON_SQRT;
>
> /// Cube root of real-number precision.
> final real REAL_EPSILON_CBRT;
>
>
> static this()
> {
>    REAL_EPSILON_SQRT = sqrt(real.epsilon);
>    REAL_EPSILON_CBRT = cbrt(real.epsilon);
> }
>
> ---
>
> Compiling this, I get the errors
>
> scid/core.d:21: Error: cannot modify final variable 'REAL_EPSILON_SQRT' scid/core.d:22: Error: cannot modify final variable 'REAL_EPSILON_CBRT'
>
> where the lines 21 and 22 are the ones inside the curly braces. What's wrong?

D1 or D2?
Does something in the spec lead you to believe that static this()
should get around final's restrictions?

It does seem like there should be some way to make a module-level constant that requires some computation.

But I'd say just make 'em non final.  Or use CTFE cbrt/sqrt functions.
 Or just precompute the value.

--bb
September 12, 2008
Bill Baxter wrote:
> On Fri, Sep 12, 2008 at 3:14 PM, Lars Kyllingstad
> <public@kyllingen.nospamnet> wrote:
>> Hi,
>>
>> I'm trying to define a couple of constants that I want to be computed at run
>> time. I have written the following code:
>>
>> ---
>>
>> /// Square root of real-number precision.
>> final real REAL_EPSILON_SQRT;
>>
>> /// Cube root of real-number precision.
>> final real REAL_EPSILON_CBRT;
>>
>>
>> static this()
>> {
>>    REAL_EPSILON_SQRT = sqrt(real.epsilon);
>>    REAL_EPSILON_CBRT = cbrt(real.epsilon);
>> }
>>
>> ---
>>
>> Compiling this, I get the errors
>>
>> scid/core.d:21: Error: cannot modify final variable 'REAL_EPSILON_SQRT'
>> scid/core.d:22: Error: cannot modify final variable 'REAL_EPSILON_CBRT'
>>
>> where the lines 21 and 22 are the ones inside the curly braces. What's
>> wrong?
> 
> D1 or D2?

D1, using GDC.

> Does something in the spec lead you to believe that static this()
> should get around final's restrictions?

None other than the fact that the following compiles perfectly:

class Foo
{
    final real bar;

    this()
    {
        bar = 1.0;
    }
}

I thought the whole point of a final variable was that it becomes constant AFTER the first time one assigns a value to it.

> It does seem like there should be some way to make a module-level
> constant that requires some computation.

Agreed.

> But I'd say just make 'em non final.  Or use CTFE cbrt/sqrt functions.
>  Or just precompute the value.

The best would of course be to calculate the values at compile time. I didn't know that's possible in D. How do I do this?

Since real is an architecture-dependent type, I don't want to precompute the values.

-Lars
September 12, 2008
I think 'const' should work.
September 12, 2008
Frank Benoit wrote:
> I think 'const' should work.

It works! Thanks! :)

But isn't this the opposite of the intended behaviour? I thought consts were evaluated at compile time, and finals and static this() blocks at run time. At least that's how I've interpreted the D1 specs.

-Lars
September 12, 2008
On Fri, Sep 12, 2008 at 4:20 AM, Lars Kyllingstad <public@kyllingen.nospamnet> wrote:
> Frank Benoit wrote:
>>
>> I think 'const' should work.
>
> It works! Thanks! :)
>
> But isn't this the opposite of the intended behaviour? I thought consts were evaluated at compile time, and finals and static this() blocks at run time. At least that's how I've interpreted the D1 specs.
>
> -Lars
>

http://www.digitalmars.com/d/1.0/attribute.html#const

"A const declaration without an initializer must be initialized in a
constructor (for class fields) or in a static constructor (for static
class members, or module variable declarations). "

To be honest I'm not sure if the "un-reassignable" property of "final" is documented anywhere.  There is a mention in the 1.011 changelog that "final for variables now works" but I don't know what "works" means.
September 12, 2008
On Fri, Sep 12, 2008 at 9:49 PM, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
> On Fri, Sep 12, 2008 at 4:20 AM, Lars Kyllingstad <public@kyllingen.nospamnet> wrote:
>> Frank Benoit wrote:
>>>
>>> I think 'const' should work.
>>
>> It works! Thanks! :)
>>
>> But isn't this the opposite of the intended behaviour? I thought consts were evaluated at compile time, and finals and static this() blocks at run time. At least that's how I've interpreted the D1 specs.
>>
>> -Lars
>>
>
> http://www.digitalmars.com/d/1.0/attribute.html#const
>
> "A const declaration without an initializer must be initialized in a
> constructor (for class fields) or in a static constructor (for static
> class members, or module variable declarations). "
>
> To be honest I'm not sure if the "un-reassignable" property of "final" is documented anywhere.  There is a mention in the 1.011 changelog that "final for variables now works" but I don't know what "works" means.

Sounds like a bug then.  If there's a loophole for const to init in static this() there should be the same loophole for final vars. Almost certainly just an oversight.

--bb