To build upon your comment, I really like the way Rust does things (they do it for coherence and major-minor versioning changes not breaking inference) - you declare types in functions (you have to) & structs, and everywhere else is optional (unless the type checker can't infer the type).