Now
DataClass(:a, b: nil) # A default
Then
All cases not matching the patterns described below remain default declarations
DataClass(:a, b: C(String)) # C is Kernel::C -> DataClass::Constraint.new, should C(String) imply a default too?
DataClass(:a, b: C(String, "")) # Second parameter of C is default
DataClass(:a, b: -> { _1 > 0 }) # Proc is **always** a constraint
Maybe better
DataClass.constrained(:a, b: String)
DataClass.