>Sure you can. DEFTYPE accepts arguments, defining the type "list of A, where A is a type" is left as an exercise to the reader.
I don't think you understand how a generic works.
Let me write it out in full:
identity :: forall a . a -> a
Now here's what you can do in CL:
identity :: (forall a . a) -> (forall a . a)
Notice that the outer qualification is not preserved.
The only expressible generic type is Any.
(deftype id-type (a) `(function (,a) ,a))
;; error: wrong type
(declaim (ftype (id-type number) num-identity))
(defun num-identity (a) 'li)
;; no error, but should be since it doesn't give you what you put in
(declaim ((ftype (identity-type *) id)))
(defun id (a) 3)
This is because:
* :: (forall a . a)
(λ a . (a -> a))(forall a . a) = (forall a . a) -> (forall a . a)
There's no way to preserve an outer qualification, such as:
forall a . (a -> a)
Which specifies that a function returns the same type it takes as input.
>CL has an unrelated facility called defgeneric and defmethod that does this.
It is unrelated, but it also doesn't do what you think it does.
I'm thoroughly confused by what you meant here.
>In Lisp, a function can return any value so generics are useless.
So are type declarations by that logic. I'm not debating if CL types are useful, I'm debating if they are expressive.
I've always given dynamic type people the benefit of the doubt and assumed that they understood static typing, but had a good reason to prefer dynamic (e.g. decoupling the type system from the code like they do in Clojure).
You two are so obviously clueless about what a generic even is that I don't think you have the qualification to hold an opinion on the subject.
Just as a great many programmers do themselves a disservice by not learning about lisp and dynamic types, you do yourself a disservice by not learning about static types.