V: cannot define recursive struct (eg binary tree's node)

Created on 26 Apr 2020  路  16Comments  路  Source: vlang/v

For example, a leaf node of binary tree should store its left and right nodes as 'empty'.

struct Node {
    value int
    left &Node
    right &Node
}

In C we use NULL, in CPP we use NULL or nullptr, in go we use nil. How about V?

Most helpful comment

I prefer ?Name to solve this. It is more V than &Tree(0) (regardless of backend implementation).

All 16 comments

?Node and none

@medvednikov Thanks. Like this?

struct Node {
    value int
    left ?&Node
    right ?&Node
}
fn main() {
    tree := Node{value: 10, left: none, right: none}
    println(tree.left == none)  // should print true?
}

But it gives C error. 馃槀

struct Node {
    value int
    left ?Node
    right ?Node
}

@medvednikov
This time it gives cgen error: cgen.sort_structs(): the following structs form a dependency cycle: * Node -> Node.

Will have to fix this compiler bug.

You can try:

struct Node {
        value int
        left &Node
        right &Node
}

fn (n &Node) str() string {
        return 'Node {\n' +
    '   value: $n.value\n' +
    '   left: 0x${ptr_str(n.left)}\n' +
    '   right: 0x${ptr_str(n.right)}\n' +
    '}'
}

fn main(){
        x := &Node{ value:123 left: &Node(0) right: &Node(0)}
        y := &Node{ value:456 left: x right: &Node(0)}
        z := &Node{ value:456 left: y right: x}
        eprintln('node x: $x.str()')
        eprintln('node y: $y.str()')
        eprintln('node z: $z.str()')
}

... which produces:

0[20:56:14] /v/nv LINUX $ ./v run node.v
node x: Node {
   value: 123
   left: 0x0
   right: 0x0
}
node y: Node {
   value: 456
   left: 0x625050
   right: 0x0
}
node z: Node {
   value: 456
   left: 0x625070
   right: 0x625050
}
0[20:56:15] /v/nv LINUX $

@spytheman Thanks. It does work, but assigning 0 to &Node is somewhat like C's ptr = 0, which I guess is not a good style in V. Maybe V should have a keyword doing this (e.g. like C++'s nullptr)?

which I guess is not a good style in V.

I think this is still an open question - see https://github.com/vlang/v/commit/153ac230ec69bdd068512d59ef79aa20e8f38876#r38768546 . @medvednikov thoughts?

@dumblob I just read that discussion and support your view. Playing with addresses should only be allowed in unsafe.

I tried to implement BST in V language, which no null types exist in this world.

Firstly, I initialized node struct like this

struct Tree {
    value int
mut:
    left &Tree = &Tree(0)
    right &Tree = &Tree(0)
}

And, exist() function will check whether left or right of the node is "null (0x0)"

fn (t &Tree) exist() bool {
    if t == &Tree(0) {
        return false
    }
    return true
}

then in insert() function, I used it like this,

if val < t.value {
    if t.left.exist() {
        return t.left.insert(val)
    } else {
        t.left = &Tree{value: val}
    }
} else {

you can check the full source code at here

@Alfex4936 good example! but I guess we still need to think about the right way to express nullptr in V. The easiest version would simply be

struct Tree {
    value int
mut:
    left &Tree = 0
    right &Tree = 0
}

because memory address won't be zero. Some languages use an explicit keyword, null, nil, nullptr, etc, but to me they're just new "appearances" of zero.

left ?Tree most likely

@medvednikov it would be nice to have a final decision, otherwise code for trees won't be stable

@SleepyRoy oh yeah I hope we can simply use ?Name or "zero" value in struct to make nested struct, as I get cgen error: cgen.sort_structs(): the following structs form a dependency cycle: for now

I actually find the solution from @Alfex4936 (left &Tree = &Tree(0)) explicit and clear unlike "playing with zeros or nulls or stuff".

I prefer ?Name to solve this. It is more V than &Tree(0) (regardless of backend implementation).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

radare picture radare  路  3Comments

choleraehyq picture choleraehyq  路  3Comments

medvednikov picture medvednikov  路  3Comments

cjmxp picture cjmxp  路  3Comments

oleg-kachan picture oleg-kachan  路  3Comments