2
votes

I am trying to build a binary search tree in common lisp. I have defined the binary search class using the CLOS like this:

(defclass bst ()
  ((root :type node
         :accessor tree-root
         :initform nil
         :initarg root)))

I am trying to define a generic function that takes in the tree object and a key and returns a boolean true if the tree contains the key and nil if the tree does not contain the key.

Right now I have the following definition of a generic function:

(defgeneric contains ((tree bst) (key))
   (:documentation "returns boolean of whether the given tree contains a particular key)

I get the following error when I load the file into the REPL (I am using SBCL):

Required argument is not a symbol: (TREE BST)

Am I misunderstanding how generic functions work? I can't seem to define the function properly.

1
The type signatures should go to the methods, not the DEFGENERIC. - jkiiski
Just a little side note: <...> :initarg root should be <...>:initarg :root: :root should be a keyword here. - mobiuseng
@mobiuseng and just to play the pedant :) it's very common for initargs to be keyword symbols, but it's not necessary. Non keyword symbols can help avoid name clashes, and internal symbols can help indicate "don't use this unless you know what you're doing". - Joshua Taylor
@JoshuaTaylor Fair point. I also thought for a moment that nothing really stops one using a symbol as an initarg, although I haven't seen it before. This is why I've put "should" :) - mobiuseng

1 Answers

9
votes

Yes, defgeneric defines a generic function. You can either specify methods in the call to defgeneric or by using defmethod.

You need one of:

(defgeneric contains (tree key)
   (:documentation "returns boolean of whether the given tree contains a particular key")
   (:method ((tree bst) key) ...))

or:

(defgeneric contains (tree key)
   (:documentation "returns boolean if a given tree contains a given key"))

(defmethod contains ((tree bst) key)
  ...)