I'm new in Racket language and I bumped into an issue. I'm now trying to implement Binary Search Tree using cons(list).
This is a simple BST I tried to make:
For this BST, if I convert this into Racket list, this can be one possibility: '(6, (4, (), ()), (7, (), ())
To produce this format of list, I used this code:
(define x3 (cons 6 (cons (cons 4 (cons null (cons null null)))
(cons 7 (cons null (cons null null)))
And for this code, the result is below:
'(6 (4 () ()) 7 () ())
As you see, this is not what I wanted. The second child node 7 () () is not inside the bracket, which means it doesn't exist as an list. It acts as individual 3 elements, not single list. So I changed a bit:
(define x2 (cons 6 (cons (cons (cons 4 (cons null (cons null null))) null)
(cons (cons 7 (cons null (cons null null))) null)
)
)
)
And for this 2nd code, the result is as following:
'(6 ((4 () ())) (7 () ()))
And this is not what I wanted either. The first child node ((4 () ())) now is inside and inside the list. So I did the final try, and the code is like this:
(define x3 (cons 6 (cons (cons 4 (cons null (cons null null)))
(cons (cons 7 (cons null (cons null null))) null)
)
)
)
And the result looks like this:
'(6 (4 () ()) (7 () ()))
Now it works! The question is, why these things happen? I kind of realized that the rule is different between the last element of list and the other when cons is used, but after all, aren't they same kind of list?
First of all:
cons
creates actually a cell, a cons cell.
You can append using cons several cons cells to each other.
(cons 'a 'b) ;; (a . b)
(cons 'c (cons 'a 'b)) ;; (c . (a . b))
The lisp notation says, ' . ( ' is ' ', so the last example simplifies to:
(c a . b)
What is a list? Such cons cells or chain of cons cells with last element being ' . ()'. In this case, you are allowed to make it invisible.
(cons 'c (cons 'a null)) ;; or
(cons 'c (cons 'a 'null)) ;; or
(cons 'c (cons 'a '())) ;; which are the same!
;; in common lisp even (cons 'c (cons 'a ())) in addition
Is thus simplified to:
(c a) ;; actually (c . (a . null))
These syntax simplification rules and the fact that cons takes only exact 2 arguments but you need 3 slots for the binary tree, makes the cons-constructs more complicated than the problem looks at the first sight.
Your BST should be expressed as lists:
(list 6 (list 4 null null) (list 7 null null))
which is already very complicated to express only with conses manually ... (as explained by assefamaru)
As you see, list
is an abstraction over the nesting of conses with the innermost cons - cell consing to a null, and more adapted to the simplication rules of the syntax. Thus much more brain-friendly.
But more elegantly, you should use structs (as explained here https://learningtogetolder.wordpress.com/2013/08/14/creating-a-binary-search-tree-in-racket/) by defining that each node expects a value and a left and a right node. Thereby, construction errors are made impossible.