AI Code

Code should be self-documented

How you break up the logic into functions and shape the data passed to them determines how well the codebase holds up over time.

semantic work

Semantic functions are the building blocks of any codebase, a good semantic function is a must as minimal as possible For prioritize accuracy In this. A semantic function must take all necessary inputs and directly return all necessary outputs to accomplish its goal. Semantic functions can wrap other semantic functions to describe the desired flow and usage; As building blocks of the codebase, if complex flows are used everywhere that are well defined, use a semantic function to codify them.

Side effects in semantic functions are generally undesirable unless they are the explicit goal because semantic functions should be safe to reuse without understanding the internal aspects of what they say. If the logic is complex and itIt’s not obvious what it does in a larger flow, a good pattern is to break that flow into a series of self-describing semantic functions that take what they need, return the data needed for the next step, and no more.Don’t do anything else. Examples of good semantic functions are from quadratic_formula() To retry_with_exponential_backoff_and_run_y_in_between<Y: func, X: Func>(x: X, y: Y). Even if these functions are never used again, future humans and agents will appreciate the indexing of information by visiting the code.

Semantic functions should not require any comments around them, the code itself should be a self-describing definition of what it does. The semantic function should ideally be extremely unit testable because a good semantic function is a well-defined one.

practical work

Pragmatic functions should be used as wrappers around a series of semantic functions and unique logic. They are complex processes in your codebase. When creating a production system itIt is natural for their logic to go wrong, practical tasks are the organization for them. These should generally not be used in more than a few places, if they are, consider breaking up the explicit logic and moving it into semantic functions. For example provision_new_workspace_for_github_repo(repo, user) Or handle_user_signup_webhook(). Testing practical functions falls within the scope of integration testing, and is often done in the context of testing entire app functionality. Practical functions are expected to change over time, from their inner workings to their function as a whole. To help with this, thisIt’s good to have document comments on them. Avoid repeating function names or obvious features about them, instead focus on the unexpected. Fails quickly on balance less than 10Or combating other misconceptions that come from function names. As a reader of the doc comments take them with a grain of salt, the coders working inside the function may have forgotten to update them, and thisIt’s good to fact check them when you think they might be wrong.

model

The size of your data should make wrong positioning impossible. If a model allows combinations of fields that should never exist together in practice, then the model isHe is doing his work. Each optional field is a question the rest of the codebase has to answer every time it touches that data, and each loosely typed field is an invitation to callers to do something that sounds right but isTea. When models enforce correctness, bugs emerge at the point of construction, not inside some unrelated flow, where assumptions eventually collapse. a modelThe name should be precise enough that you can look at any field and know whether it belongs or not – if the name does notLet me tell you, the model is trying to be a lot of things. When two concepts are often needed together but are independent, write them down instead of merging them – for example UserAndWorkspace { user: User, workspace: Workspace } The workspace in the user retains both models instead of flattening the fields. like good names UnverifiedEmail, PendingInviteAnd BillingAddress Tell you what the fields actually are. if you see one phone_number on the field BillingAddressYou know something went wrong.

Values ​​with similar shapes may represent completely different domain concepts: { id: "123" } could be the one DocumentReference a place and a MessagePointer In the second, and if your actions simply accept { id: String }The code will accept either one without complaint. Brand types solve this by wrapping a primitive in a specific type so that the compiler treats them as different: DocumentId(UUID) instead of a bare UUID. With branding in place, accidentally swapping two IDs becomes a syntax error rather than a silent bug that surfaces three layers deep.

where things break

Breaks usually happen when a semantic function is changed to a practical function for ease of use, and then other places in the codebase that rely on it do the same thing they did.Not intended. To solve this, be specific when creating a function by naming it not just what it does, but where it is.is used. By the nature of their names it should be clear to other programmers that their behavior is not tightly defined and should not be trusted internally to perform any precise task, and they should make debugging regressions easier.

Models break down in the same way but slower. They start to concentrate, then someone adds just one more optional field because itThis is easier than creating a new model, and then someone else does the same, and ultimately the model is a loose bag of half-related data where each consumer has to guess exactly which fields are set and why. The name ceases to describe what the data is, the fields cease to be united around a single concept, and every new feature that touches the model has to navigate situations it was never designed to display. When a modelThe fields of no longer correspond to its name, i.e.This is a sign of dividing it into different thingsJoining together.



<a href

Leave a Comment