14 Comments

> I succeeded by getting the ontology right.

What I am about to expand on may be too much rationality.

Let me explain.

Getting the ontology right doesn't mean I have to get the cardinality 100% foolproof right.

Example, after speaking with all stakeholders, I decide that a relationship between entity Project and entity Task is the right ontology. However, I receive conflicting information from different people whether it should be one to many (i.e., 1 Project has many Tasks and each Task can ONLY belong to 1 Project) or many-to-many. This uncertainty over whether a relationship is 1 to many or many to many is uncertainty over cardinality.

I used to let this stop me from proceeding.

I also used to be very upset when the stakeholders gave me new information that they should have told me right from the start or they changed their mind, because the new info or change of mind resulted in a chnage of cardinality.

A change in cardinality isn't a big deal, but it does require rewriting code. And the amount of rewrite may be extensive depending how low or high in the hierarchy of things. E.g. if the change is something deeply fundamental, the resulting changes will be extensive.

Not caring about ontology is also not correct just because certain details about the ontology are more subject to changes or mistakes.

Basically, I have found not to let the perfect be the enemy of the good. Cardinality != Ontology and even then not all cardinalities are equally important. The more fundamental ones tend to lead to more extensive refactoring when they change *AFTER* code is written.

Trying to get the ontology right is still very important, but I think if there's more improvements in terms of making it less expensive to change things that cannot be decided early on, that would be even better.

Expand full comment
author

> if there's more improvements in terms of making it less expensive to change things that cannot be decided early on, that would be even better.

Yes, definitely!

Many approaches to software design, language features, and framework features have flexibility of this general sort as a goal. Often that hasn't worked as well as hoped.

Long ago (late 80s) I sketched a framework that would make ontology explicit, with much of an app then flowing automatically from that. The product I led in the 1990s took ideas from that, which I think also helped make it a success.

I considered pulling out the framework and making it more general—it was somewhat specialized for the application—and making that a product, which would have much greater scope. I was too burned out by then to do it, although I still think it would have been a good idea.

MVC architectures in frameworks like Django do part of what is needed, I think. Just changing the cardinality declaration on the model can automatically change the UI and database schema and so on, updating in the right ways without your having to write any code.

There's still a lot more that is possible, I think!

Expand full comment

I'm probably digressing from this article, but I cannot help share my own nerdy thoughts on this.

> flexibility of this general sort as a goal. Often that hasn't worked as well as hoped.

I am working towards this in my own small way.

Basically to help me with my daily work, i.e. writing web apps for enterprise software.

My current approach (and hypothesis) is:

- use a formal, text-based notation perhaps taking from systems engineering to describe problem specs and logical design,

- then use that as input into generative AI to output the code build and improve web app of a specific framework

I bought your book, "Better without AI", and followed some of the people you recommended in that book. So I'm aware of, and agree with you the objections you have with generative AI.

So this is experimental at this point.

> I considered pulling out the framework and making it more general—it was somewhat specialized for the application—and making that a product, which would have much greater scope.

It would be good even if you pull it out without making it more general at the moment.

> Django

Coincidentally, that's the framework I am focusing my experiment on.

So in short, purpose-wise, web forms for enterprise software. Tech stack is Django, or at most Django as backend + React as frontend.

Input would be some kind of higher order, formal notation as problem specs, and logical design.

Using my own example in the earlier comment, imagine changing the cardinality in the text-based formal notation from

one-to-many

```

// Objects

Project

Task

// Structural Relations

Project includes Task.

Task is part of Project.

```

to many-to-many

```

// Objects

Project

Task

// Structural Relations

Project is associated with Task.

Task is associated with Project.

```

Then, the generative AI that's trained on the specific target tech stack will generate the files and code accordingly.

> Just changing the cardinality declaration on the model can automatically change the UI and database schema and so on, updating in the right ways without your having to write any code.

Yes, that's what I am thinking as well in my own experiment. Precision and rigor still matter, but I am thinking if it's possible to do so at some higher-order level and leave it to machines (be it gen AI, or something else) to do it.

I don't rule out doing something deterministic like how Django does it with migrations for example. But, right now, I don't feel I'm smart enough to figure that out.

> There's still a lot more that is possible, I think!

Strong agree.

Just to circle back to your article, even if machines handling code changes turns out to be true and available in the future, your points about getting ontology right, and that software development is an activity teeming with nebulosity are not diminished.

In fact, I suspect your points will be more explicit and obvious.

If much of what's currently done by human junior developers can be done by machines (i.e. writing code to specs, writing unit tests, etc), then what defines the job of a software developer in that reality will be mostly figuring out the nebulosity and its implications.

I personally prefer that kind of reality frankly. Writing code is getting tedious for me now. I prefer solving problems and that usually means confronting inevitable nebulosity.

Expand full comment
author

Code writing is one application for GPTs that seems to work well (for many people; opinions about this are strangely bimodal!). So your approach may work!

There's a long-standing objection to code generators (old-fashioned not-AI ones), which is that they may produce code that's great but if you need to modify it (for whatever reason) then you've decoupled the code from the spec that you initially gave to the generator. So either you need to never touch the generated code and do all maintenance by changing the spec and re-running the generator, or else you are stuck maintaining the code it output and never re-run it.

This problem seems like it would be at least as bad with code generated by an LLM.

> If much of what's currently done by human junior developers can be done by machines (i.e. writing code to specs, writing unit tests, etc), then what defines the job of a software developer in that reality will be mostly figuring out the nebulosity and its implications.

Yes, this seems a good insight!

> Writing code is getting tedious for me now. I prefer solving problems and that usually means confronting inevitable nebulosity.

This is a sign of maturation as a developer/engineer!

Expand full comment

I was never sure if RUP was an actual thing that companies used and believed in 30+ years ago, or if it was a Boogeyman exaggerated by the Agile stories... 🤣

Expand full comment
author

I had a friend who worked at Rational ~30 years ago, so I can testify that it existed then!

It was bought by IBM ~20 years ago, and you can still buy Rationality from them: https://public.dhe.ibm.com/software/rational/web/datasheets/RUP_DS.pdf

It doesn't come cheap, though!

Expand full comment
Jun 30Liked by David Chapman

Really liked this.

Typo: "It might buggy software"

Expand full comment
author

Glad you liked it, and thanks for pointing out the typo! I've fixed it now.

Expand full comment

Love it. I know you weren't impressed with the Domain Driven Design book but contemporary DDD practices are exactly for this kind of nebulosity and getting the ontology right.

Expand full comment
author

Yes, I'll be covering DDD in the next section (coming after the second half of this section on requirements/purposes)!

Can you recommend anything to better and more current to read about it?

Expand full comment

Its hard because ironically subtleties of DDD are very tacit.

"Learning Domain Driven Design" by Vlad Khononov has way clearer language.

If you want get an overview of what contemporary practices exist (with the danger of intepreting them as a rationalist approach): https://github.com/ddd-crew/ddd-starter-modelling-process

An experience report from a couple of weeks ago about how Evan himself teaches DDD:

https://read.ceilfors.com/p/unspoken-secrets-of-ddd-lessons-from-eric-evans

https://read.ceilfors.com/p/concrete-examples-to-deepen-understanding

Expand full comment
author

Thank you, this is very helpful! I will read all of them before writing the ontology/DDD section.

Expand full comment

Wish I had this to read when I started my career "gathering requirements" would have saved a few projects.

This feels like a long argument for agile (or just the build, deploy, learn, iterate cycle) - is it more inherently meta-rational then? Would be interesting to hear that explored!

Expand full comment
author

Glad you like it! Yes, there’s a second half coming “soon,” which will explain how one can engage with purposes meta-rationally when doing software development.

Expand full comment