Thread overview
CTFE Evaluation with JSON Objects
Jan 22, 2020
rbscott
Jan 23, 2020
rbscott
Jan 25, 2020
James Blachly
Jan 30, 2020
rbscott
January 22, 2020
Hello,

I am running into an error during compilation and I can't figure out a way to work around it. The use case is pretty simple, to pull an integer out of a JSON Object at compile time.

import std.json;

void main()
{
    // Basic, should be the same principle?
    const jsonNumber = new JSONValue(1);
    pragma(msg, jsonNumber.integer);

    // Why does this work?
    const jsonObject = parseJSON(`{ "str" : "string", "integer": 2 }`);
    pragma(msg, jsonObject["str"].str);

    // Why does this fail?
    pragma(msg, jsonObject["integer"].integer);
}

All of the compilers seem to fail with the error, "Error: reinterpretation through overlapped field integer is not allowed in CTFE". I think this is related to working with unions at compile time, but a. I am not sure why it doesn't happen when using a new JSONValue directly, and b. how to work around this limitation. Looking at the JSONValue source, the store is private and so even using a C cast wouldn't work without modifying the source.

Any thoughts or ideas?

thanks!
rbscott
January 23, 2020
On Wednesday, 22 January 2020 at 10:17:43 UTC, rbscott wrote:
> Hello,
>
> [snip]
>
> Any thoughts or ideas?
>
> thanks!
> rbscott

Hi,

I hope this helps:

```D
import std.json;

void main()
{
    // 1) Use `enum` instead of `const` to
    // guarantee that the value will be
    // computed at compile-time.
    // 2) Don't use `new` for enum values
    // as we currently don't have a robust
    // mechanism to materialize heap-allocated values.
    enum jsonNumber = JSONValue(1);
    pragma(msg, jsonNumber.integer);

    // Q: Why does this work?
    // A: Although reinterpretation through unions
    // is (mostly?) forbidden during CTFE, you can
    // still read union members that have been
    // written to before.
    const jsonObject = parseJSON(`{ "my key" : "some value", "integer": 42 }`);
    pragma(msg, jsonObject["my key"].str);

    // Q: Why does this fail?
    // A: Because of a slightly obscure implementation
    // detail of std.json:
    // https://github.com/dlang/phobos/blob/45b2b0d1ad67ee041cf67e4e10c9e225b75acb18/std/json.d#L1275-L1281
    // Basically, if the value read is a non-negative
    // integer, the `uinteger` union member is set,
    // however if the value is <= 2^^63,
    // then the `JSONType.integer` type is set,
    // which prevents reading through the uinteger() JSONValue property.
    // This can be worked around by directly accessing
    // the `store` private field using `.tupleof[0]`:
    pragma(msg, jsonObject["integer"].tupleof[0].uinteger);
}
```

Cheers,
Petar
January 23, 2020
On Thursday, 23 January 2020 at 00:20:24 UTC, Petar Kirov [ZombineDev] wrote:
> Hi,
>
> I hope this helps:
>
> ```D
> import std.json;
>
> void main()
> {
>     const jsonObject = parseJSON(`{ "my key" : "some value", "integer": 42 }`);
>     pragma(msg, jsonObject["my key"].str);
>     pragma(msg, jsonObject["integer"].tupleof[0].uinteger);
> }
> ```
>
> Cheers,
> Petar

Hi Petar,

This worked perfectly. I was stuck on that for a while, and now I understand what is going on. Using tupleof is a nice trick!

Thanks!
rbscott
January 23, 2020
On 1/22/20 7:20 PM, Petar Kirov [ZombineDev] wrote:
>      // Q: Why does this fail?
>      // A: Because of a slightly obscure implementation
>      // detail of std.json:
>      // https://github.com/dlang/phobos/blob/45b2b0d1ad67ee041cf67e4e10c9e225b75acb18/std/json.d#L1275-L1281 
> 
>      // Basically, if the value read is a non-negative
>      // integer, the `uinteger` union member is set,
>      // however if the value is <= 2^^63,
>      // then the `JSONType.integer` type is set,
>      // which prevents reading through the uinteger() JSONValue property.

This is a bug in std.json that can/should be fixed.

https://issues.dlang.org/show_bug.cgi?id=20527

I'll whip up a PR.

-Steve
January 25, 2020
On 1/23/20 8:00 AM, Steven Schveighoffer wrote:
> 
> This is a bug in std.json that can/should be fixed.
> 
> https://issues.dlang.org/show_bug.cgi?id=20527
> 
> I'll whip up a PR.
> 
> -Steve

Steve, thanks for addressing. This kind of ergonomic friction (writ large) hampers adoption of the language overall IMO. You are doing great work to make D accessible.

James
January 30, 2020
On Saturday, 25 January 2020 at 15:53:28 UTC, James Blachly wrote:
> On 1/23/20 8:00 AM, Steven Schveighoffer wrote:
>> 
>> This is a bug in std.json that can/should be fixed.
>> 
>> https://issues.dlang.org/show_bug.cgi?id=20527
>> 
>> I'll whip up a PR.
>> 
>> -Steve

Hi Steve,

Thanks for the fast bug fix!

cheers,
rbscott