Type Checking and Inference for Dynamic Languages