haskell-jsonnet icon indicating copy to clipboard operation
haskell-jsonnet copied to clipboard

Cyclic imports

Open moleike opened this issue 4 years ago • 0 comments

Cyclic imports are valid and well defined:

$ cat a.jsonnet 
{
  a:: 'a',
  c: (import 'b.jsonnet').b,
}
$ cat b.jsonnet 
{
  b:: (import 'a.jsonnet').a,
}
$ /google/data/ro/teams/jsonnet/jsonnet a.jsonnet 
{
   "c": "a"
}

So are imports on self:

$ cat a.jsonnet 
{
  a:: 'a',
  c: (import 'a.jsonnet').a,
}
$ jsonnet a.jsonnet 
{
   "c": "a"
}

The problem in the code snippet in the description is that the object in "main.jsonnet" is recursively defined in a way where the recursion doesn't have a terminating condition (i.e. bottomless). It's equivalent to:

local a = a + {};
a

Which produces similar results:

$ jsonnet main.jsonnet 
RUNTIME ERROR: max stack frames exceeded.
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        main.jsonnet:1:11       thunk <a>
        ...

But there are plenty of valid ways to define a variable or set of varibles recursively that do bottom out. For example:

{
 x: {
   a: 1,
   y: $.y,
 },
 y: {
   x: $.x,
   a: 1,
 },
}.x.y.x.y.x.y.x.a
{
  a: 1,
  b: 1,
  fib: self {
    a: super.b,
    b: super.a + super.b,
  },
}.fib.fib.fib.fib.fib.a

Are both valid, terminating programs.

Originally posted by @mikedanese in https://github.com/google/go-jsonnet/issues/353#issuecomment-571914021

moleike avatar Apr 09 '21 10:04 moleike