Yasser Sheikh · MSc BEng AMIChemE RITTech

Writing · Apr 2026

Parse, don't validate, especially in a data-science repo.

Data-science codebases are known as the untyped corner of software engineering. I think that gets the economics backwards. When a web app has a type error you usually get an exception and a stack trace within seconds. When an ML pipeline has one, the model trains happily on nonsense and produces predictions that are silently wrong. In my work those predictions are recommendations for a running chemical plant. Data science needs types more than product code does.

Parse at the boundary

The most valuable habit I know is to parse external data into a typed structure at the moment it enters the code. An API response, a sensor feed or a dataframe from someone else's pipeline gets converted into a dataclass, aTypedDict or a schema right at the boundary, and from then on the type checker knows what it is. The alternative is waving it through asdict[str, Any] after a quick validation, which leaves every function downstream guessing. Units are the classic failure in plant data. Kilopascals look exactly like bars inside a float, and only a type can carry the difference through a codebase.

Fix errors, don't suppress them

Every type checker has escape hatches. In the codebases I look after the rule is to fix the error, not silence it, and never to switch off checking for a whole file. A file-level ignore does not remove type errors, it just removes your ability to see the next one. When a suppression really is unavoidable, it should name the specific rule on the specific line, so anyone reading it later can see it was a deliberate decision.

Refactoring is the payoff

Types catch bugs before runtime, and that alone would justify them. What convinced me is how cheap they make refactoring. In a well-typed codebase you can rename a concept, split a module or change a schema, and the checker walks you through every consequence until the change is complete. I have led large refactors of live model-serving code where the type checker did the work of a test suite for the plumbing, and the actual tests were free to test behaviour. Untyped code stops being refactored because nobody dares touch it, and that is how it rots.

Types are context for agents

Type discipline used to be for the humans on a team. It has turned out to matter just as much for coding agents. A signature tells the agent what a function takes and returns without any guessing from names, and unlike documentation it cannot go stale. The type checker also gives the agent the same fast feedback loop it gives me, where every mistake surfaces in seconds inside the session instead of days later in review. The agent rules I maintain lean hard on this. Parse at the boundary, no blanket suppressions. Agents follow type rules more reliably than they follow prose style guides, because a machine checks compliance. The type discipline we built for our own sake now pays a second time in every agent session.