Is there a fundamental difference between putting things before or after the colon when defining inductive types? It seems to me that it's mostly a matter of syntactical convenience. For example, these 4 polymorphic list definitions are basically the same thing to me:
Inductive list1 : Type -> Type :=
| Nil1 : forall (X : Type), list1 X
| Cons1 : forall (X : Type), X -> list1 X -> list1 X.
Inductive list2 (X : Type) : Type :=
| Nil2 : list2 X
| Cons2 : X -> list2 X -> list2 X.
Inductive list3 {X : Type} : Type :=
| Nil3 : list3
| Cons3 : X -> list3 -> list3.
Inductive list4 : Type -> Type :=
| Nil4 : forall {X : Type}, list4 X
| Cons4 : forall {X : Type}, X -> list4 X -> list4 X.
The only difference is that some of them require being more explicit about X : Type
as seen in the following examples:
Compute Cons1 nat 3 (Nil1 nat).
Compute Cons2 nat 3 (Nil2 nat).
Compute Cons3 3 Nil3.
Compute Cons4 3 Nil4.
However, this can be easily fixed with Implicit Arguments
:
Implicit Arguments Nil1 [X].
Implicit Arguments Cons1 [X].
Compute Cons1 3 Nil1.
Implicit Arguments Nil2 [X].
Implicit Arguments Cons2 [X].
Compute Cons2 3 Nil2.
So these 4 definitions have no fundamental difference from my point of view, other than syntactical convenience. Is that correct? Are there use cases in which putting something before or after the colon has more dramatic consequences?