A good compromise can be for example: Have your type annotations in the head of the procedure you are writing. That includes types of arguments and return type. You write it once at the head, and when you need to know you can look it up there, but you don't need to clutter the whole rest of the code. If you write well composing functions, then this will be all you ever need. If you write procedures 300 LoC, then well ... you shot yourself in the foot.