nickel icon indicating copy to clipboard operation
nickel copied to clipboard

Accessing late-bind field fails

Open suimong opened this issue 9 months ago • 4 comments

Describe the bug I apologize for the over-generic & cryptic issue title, as it is really hard to summarize the issue in words, so here's the MRE.

To Reproduce

The program looks like this:

# main.ncl
{
  FeatureFile = {
    inputs = {
      a | Number,
      b = a + 2,
    },
    bar,
    baz,
    zab | optional,
    cux = inputs.b * 10
  },
  Feature = {
    inputs = {
      a | Number,
    },
    inputs' = let a = inputs.a in {inputs.a = a},
    files | Array (FeatureFile & inputs')
  },
  feats = {
    x | Feature = 
    {
      files = [
        { 
          bar = 2, 
          baz = 3, 
          zab = x.inputs.a + 10,
        }
      ]
    }
  },
  prof1 = {
    inputs = {
      a,
    },
    features | Array Feature 
    = let a = inputs.a in [
      feats.x & {inputs.a = a}
    ]
  },
  prof1_ = prof1 & {inputs.a = 5},
}

Evaluating the program, providing inputs to the prof1 field, we get the following error:

> nickel eval main.ncl --field=prof1_

error: missing definition for `a`
   ┌─ /tmp/main.ncl:26:26
   │  
13 │       inputs = {
   │ ╭──────────────'
14 │ │       a | Number,
15 │ │     },
   │ ╰─────' in this record
   · │
26 │             zab = x.inputs.a + 10,
   │                   ---------^
   │                   │        │
   │                   │        required here
   │                   accessed here

note: 
   ┌─ /tmp/main.ncl:14:11
   │
14 │       a | Number,
   │           ^^^^^^ bound here

Commenting out line 26, prof1_ evaluates as intended:

{
  features
    | Array Feature
    = [
        {
          files
            | Array (FeatureFile & inputs')
            = [
                {
                  bar = 2,
                  baz = 3,
                  cux = 70,
                  inputs = { a | Number = 5, b = 7, },
                }
              ],
          inputs = { a | Number = 5, },
          "inputs'" = { inputs = { a = 5, }, },
        }
      ],
  inputs = { a = 5, },
}

Expected behavior

prof1_ evaluates to:

{
  features
    | Array Feature
    = [
        {
          files
            | Array (FeatureFile & inputs')
            = [
                {
                  bar = 2,
                  baz = 3,
                  cux = 70,
                  zab = 15,                                # <- `zab` gets the input value correctly
                  inputs = { a | Number = 5, b = 7, },
                }
              ],
          inputs = { a | Number = 5, },
          "inputs'" = { inputs = { a = 5, }, },
        }
      ],
  inputs = { a = 5, },
}

It feels like zab should be able to access the defined inputs.a.

Environment

  • OS name + version: NixOS 23.11
  • Version of the code: nickel-lang-cli nickel 1.6.0 (rev 3441781)

Additional context Add any other context about the problem here.

suimong avatar May 13 '24 04:05 suimong