Recursive definitions are not bad at all. On the contrary, they are the best kind of definitions. It is important to note that recursive defintions are not the same as circular definitions - in a recursive definition there is a base case which will eventually be reached. For example, we can define the set of natural numbers recursively:

A number is a natural number if:
  a) it is 0, or
  b) it is the successor of another natural number
Do you see the recursion? We can use this definition to determine that 3 is a natural number:
3 is the successor of 2, so 3 is a natural number if 2 is a natural number;
2 is the successor of 1, so 2 is a natural number if 1 is a natural number;
1 is the successor of 0, so 1 is a natural number if 0 is a natural number;
0 is a natural number;
so 3 is a natural number
Recurive definitions can make writing recursive programs very natural. Consider the following definition of factorial:
factorial(n) = 1, if n = 0
factorial(n) = n * factorial(n - 1), if n > 0
This makes writing the factorial function very easy. Here it is (in Scheme):
(define factorial
  (lambda (n)
    (if (zero? n)
        1
        (* n (factorial (- n 1))))))