Skip to content

Bounded recursion example breaks on cue 0.6 #80

@iyefrat

Description

@iyefrat

The bounded recursion function works for cue 0.5, but breaks on cue 0.6. To reproduce.

To reproduce the issue, take the following cue code (copied from the website, presented here as one block for easy of reproducibility):

package r

import "list"

#RecurseN: {
	// this is the bound on our recursion
	#maxiter: uint | *4

	// This is the function list element
	// we generate this to simulate recursion
	#funcFactory: {
		#next: _
		#func: _
	}

	// this is our "recursion unrolling"
	for k, v in list.Range(0, #maxiter, 1) {
		// this is where we build up our indexed functions and the references between them
		#funcs: "\(k)": (#funcFactory & {#next: #funcs["\(k+1)"]}).#func
	}

	// our final value needs to be null
	#funcs: "\(#maxiter)": null

	// we embed the head of the list so that the values
	// we write this into can be used like other CUE "functions"
	#funcs["0"]
}

#DepthF: {
	#next: _
	#func: {
		#in:    _
		#basic: int | number | string | bytes | null
		out: {
			// if we have a basic type, we are at a leaf, depth is 1
			if (#in & #basic) != _|_ {1}

			// if we are not a basic type, then we are 1 + the max of children
			if (#in & #basic) == _|_ {
				// this is our "recursion" for each child
				let depths = [ for k, v in #in {(#next & {#in: v}).out}]
				list.Max(depths) + 1
			}
		}
	}
}

#Depth: #RecurseN & {#maxiter: 11, #funcFactory: #DepthF}

tree: {
	a: {
		foo: "bar"
		a: b: c: "d"
	}
	cow: "moo"
}

d: #Depth & {#in: tree}

and run (with recur.cue containing the above):

$ cue export --out json recur.cue

with cue 0.5, the result will be:

{
    "tree": {
        "a": {
            "foo": "bar",
            "a": {
                "b": {
                    "c": "d"
                }
            }
        },
        "cow": "moo"
    },
    "d": {
        "out": 5
    }
}

with cue 0.6 (or 0.7.1), the result errors:

d: cannot add field #maxiter: was already used:
    ./recur.cue:49:22

if I remove the #maxiter field, I get a result, but out is now missing:

{
    "tree": {
        "a": {
            "foo": "bar",
            "a": {
                "b": {
                    "c": "d"
                }
            }
        },
        "cow": "moo"
    },
    "d": {}
}

Not sure why any of this happens to be honest, haven't been able to find this issue or a lead anywhere.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions