jasim
Joined 16 years ago
Joined 16 years ago
They call a table definition - that defines a table at both the SQL level, and at the domain level - a DocType (see: https://docs.frappe.io/framework/user/en/basics/doctypes). When you declare a DocType you immediately get a working table, foreign keys transformed into combo boxes for lookups, forms, and a whole set of conveniences that are common to ERP-like applications.
Before seeing ERPNext I would've thought that such a declarative approach would fail to satisfy the critical remaining 20% of most requirements, but they've built around it in a way that has enabled them to ship a complex ERP system that thousands of businesses of different shapes use. I think it is one of those gems that are not in popular conscience among software engineers, compared to regular frameworks (but very much so in business-ERP adjacent circles), and is worth learning from.
I think frameworks would mutate to be agentic - they'll come with skills and documentation targeted to LLM agents, and they'll have far more breadth than anything we've seen, a certain lack of restraint, and will sacrifice composability and orthogonality because they are no longer useful for agents.
The framework I'm building - plug: https://sapporta.com - brings in a set of UI choices (datagrids for every table) and a set of API choices (everything exposed to agents) which is not typical to classical frameworks. If you're building database applications, it contains most of the things that a typical NoCode tool would have, but with complete code and the ability for agents to build upon it.
I think Sapporta is one of the first frameworks with this point of view, but it has only been a few months since Opus 4.8, and I think in the coming months we'll see a lot more vertically integrated horizontal frameworks (the solid base) that can get us malleable software with custom code.
These days I run a prompt of this shape to ensure that my code contains as much tacit knowledge as I have -- "I want to make sure all the implicit invariants and structures and concepts described in these plans, are present in the code comments, namings, comments around major types and modules. So even if the original plan file is not present, we should still be able to understand it (Peter Naur - Programming is Theory Building)"
However - I still need the type system as another preserver of invariants and intents. Coding agents still make subtle mistakes and miss very obvious things as the code gets more intricate and conceptually large.
A type error where an expected case is not handled - that is a feedback that can ground it back and force it to think through whether windspeed matters to is_dangerous or not. And the choice of is_dangerous in the article is a bit misleading, because anyone can at first read make the connection from windspeed to is_dangerous. It is a pretty bold variable name and attention grabbing situation.
However codebases are made of far more mundane but widespread and braided sets of tiny invariants that wouldn't catch either a human's or a coding agent's attention without needing a more firmer hand, and so I still do love my type systems despite my best laid comments.
I find Ruby a very beautiful language, and Rails is an excellent web framework, but I need typed functions, record types and sum types.
They help not just with correctness, but also as living documentation that lets me understand AI generated code. TypeScript provides discriminated union, but not exhaustive pattern-matching, and its syntax is a bit verbose, but since I'm no longer writing most of the code myself, I can live with it.
However I can't imagine using Python or any other dynamic language going forward. There is likely good reason for you to choose it, and I'm curious to know what that is.
https://twitter.com/jasim_ab
[email protected]