← Back to context

Comment by AnimalMuppet

5 years ago

There can be a stage between "I have kind of an idea of what this is supposed to be" and "I'm ready to code this", where you think carefully about what this thing is actually supposed to be, and how it's supposed to behave and interact. It's not amiss to think for a bit before creating the code.

I'd rather spend some time making sure I'm building the right thing, rather than testing that what I built correctly does the wrong thing.

On the other hand, if you want to argue that UML is not the optimal way to do that, you could make a case. It makes you think through some questions, but those may not be the only questions, and there may be other ways of thinking through those areas than drawing diagrams.

And if you want to iterate your designs, UML is a painful way to do so. You'd want to design in some other medium that is easier to change. (Maybe something text based?) But if you're thinking through all the design issues in another medium, and iterating the design in that other medium, then why produce the UML at the end? To communicate the design to other people - that's the point of UML. But if you can communicate the design better using something else (like maybe the medium you actually design in), then why produce the UML?

That assumes that before you have a thing in your hand (a working program with expected input, and output), you can exactly describe how that thing should act, what it should look like, what the input and output should be (and not be) and have that be successful - and structured correctly internally the first time.

In my 25ish years of experience writing code? That has happened for a non trivial task exactly zero times.

If the idea is you could refactor the UML (and hence generated code) to adjust, since none of the tools are able to generate functional code (stubs and simple templates yes, but not much more than that), that means it would need to refactor a bunch of human manipulated and generated code without breaking it. Which I think is well beyond even our current capabilities.

  • It's weird to read this because building's architects and designers do exactly that: they have to make tremendous efforts to design complex systems (think an airport or a hospital) before they lay down a single brick. Somehow this idealization and planning step is impossible for software developers.

    • Those engineers have the good fortune to be working in a fairly constrained space. New materials and building techniques become viable slowly over time.

      Software developers are able to build abstractions out of thin air and put them out into the world incredibly quickly. The value proposition of some of these abstractions are big enough that it enables _other_ value propositions. The result of that is that our "materials" are often new, poorly documented, and poorly understood. Certainly my experience writing software is that I am asked to interact with large abstractions that are only a few years old.

      Conversely, when I sit in a meeting with a bunch of very senior mechanical engineers every one of them has memorized all of the relevant properties of every building material they might want to use for some project: steel, concrete, etc. Because it's so static, knowing them is table stakes.

      I'd say this difference in changing "materials" is a big source of this discrepancy.

      1 reply →

    • Decades of coding here.

      Buildings neither are Turing complete, nor do the building blocks become obsolete every few years.

      The closest analogue to software development is legislation.

      Even the best written rules can have unintended consequences, and so we have tools to make the behavior ever more precise and less error-probe. But it’s never fool proof.

      Also and like legislation, it’s the edge cases that balloon a proof of concept into monstrous sizes.

      In some respects, for software to advance some components need to be less powerful. But we have this fetish for inventing yet another Turing complete language in the pro space, just because, and bolting on a million features.

      It’s unnecessarily tiresome.

    • Hah! The funny part is, you think they don’t mess this up all the time, but they do! We all have experiences with buildings that are impossible to navigate, have weird maintenance issues (toilets always backing up, A/C a nightmare, rooms too small, rooms too big, not enough useful space, etc). Buildings get redrawn constantly during construction, and they rarely match the plans. Cost overruns are endemic, as are scheduling issues.

      They’re also using literally thousands of years of deeply ingrained cultural rules and expectations focusing on making living in and building structures effective (it’s one of the core tenets of civilization afterall), supported by an army of inspectors, design specialists, contractors (themselves leveraging thousands of years of passed down and deeply baked in expertise in everything from bricklaying, to concrete work, to framing).

      All that for what, functionally, is a box we put things in, including ourselves, that we prefer provides some basic services to a decent standard and isn’t too ugly.

    • I remember watching a documentary on architecture, and the speaker, who offering a different approach, said that for much of architecture, the never-look-back mantra was the unspoken rule of the day.

      You'd design and build a building, and that was it. If the roof leaked (common on building-like pieces of art), you didn't want to know about it. If the interior was changed to actually work for the buildings occupants, you didn't want to know -- that'd mean that your beautiful design has been marred.

      All this suggests to me that some of these designs are done without deeply considering the needs of the people affected, and realizing that those needs change, and worse, without learning from the mistakes and successes of the past.

      [Note that I am not arguing about the merits of how software is, was, or should be designed.]

      2 replies →

    • A ways back, the president at a multi-discipline engineering consulting firm I worked in made an interesting point. If you give ten EEs a hardware task, they will come back with something that looks similar. If you give ten software engineers a software task, they will come back with ten completely different things. I think this is because in software there are so many possible ways to do something, and so much richness, that writing software is a very different from making hardware, or architecting a building, to go along with the parent comment.

    • It's not that software engineers are not capable of doing the same when required (e.g. in the firmware for NASAs mars rovers, etc.) but that usually software engineers don't do that because there is a better alternative.

      If architects could build a house multiple times a day while slightly rearranging the layout every time they'd do that in a heartbeat.

      1 reply →

    • There are quite a few responses, but I still want to point out a main difference more clearly:

      There are natural-intelligence (human) agents translating the diagram to "code" (bricks).

      There is a lot of problem fixing going on done by the construction crews, cursing at the architects (sometimes, or just going with the flow and what comes with the job).

      That is the same with software:

      If you give good developers diagrams those human agents too will be able to produce useful software from it, no matter the flaws in the diagrams, as long as they understand the intent and are motivated to solve the problems.

    • The constraints are different. If compilation took 3-5 years to complete, software would look more like civil engineering.

      The goal of 3d printing and the like is to make mechanical engineering more like software so you can get a tight iteration loop

      1 reply →

    • The interesting question is how they organize these tremendous design efforts before laying the first brick. In software, there just is no construction phase after the design phase.

      1 reply →

    • I suspect it probably is possible, if you're willing to spend enough time. However, it's also true that the cost of a building's architect changing his mind in medias res is far higher than the software developer's. It is not necessarily the case that the best way to approach one discipline is also the best way to approach the other, just because we happen to have decided both should be called "engineering."

    • They do however make computer models and simulations to understand the problem. Programmers do that as well by coding parts of the problem, running it to simulate usage and see how it works and adjusting accordingly. No bricks needs to be laid for software engineers to work either.

    • I start to think that this step is actually the code. An architect has to specify things because the drawing is not the building, while for programming the 'drawing' actually is already the program.

    • Buildings are naturally described by drawings, logic is naturally deacribed by notation. We wouldn't ask a civil engineer to design a building using prose, and so we should not ask a computer engineer to describe logic using boxes and arrows.

    • On the contrary, not only is this planning step not impossible in current programming practice, it's universal, or very nearly so. Almost nobody programs by hex-editing machine code anymore. We just edit the design, often in a language like Golang or C++, and then tell the compiler to start "laying the bricks," which it finishes typically in a few seconds to a few minutes. If we don't like the result, we change the design and rebuild part or all of it according to the new design.

      More modern systems like LuaJIT, SpiderMonkey, and HotSpot are even more radical, constantly tearing down and rebuilding parts of the machine code while the program is running. Programs built with them are more like living things than buildings, with osteoclasts constantly digesting bones while osteoblasts build them. In these systems we just send the plans—our source code, or a sparser form of it—to the end-user to be gardened and nurtured. Then, just as osteoblasts build denser bone where its strength is most needed, the JIT builds higher-performance code for the cases that automatic profiling shows are most performance-critical to that user.

      — ⁂ —

      Soon architects will be able to do their work in the same way.

      Like Microsoft programmers in the 01990s, they'll do a "nightly build" of the current design with a swarm of IoT 3-D printers. Consider the 10,000 tonnes of structural steel that make up the Walt Disney Concert Hall in Los Angeles, which seats 2265 people. After the 16-year construction project, it was discovered that reflection from the concave surface was creating deadly hot spots on the sidewalk and nearby condos, requiring some expensive rework.

      If each assembler can bolt a kilogram of steel onto the growing structure every 8 seconds, then 2000 assemblers can rebuild it from source in a bit over 11 hours. In the morning, like programmers, the architects can walk through the structure, swing wrecking balls at it to verify their structural integrity calculations, and see how the light falls, and, importantly, notice the sidewalk hotspots. Perhaps another 2000 printers using other materials can add acoustic panels and glazing, so the architects can see how the acoustics of the space work. Perhaps they can try out smaller changes while inside the space using a direct-manipulation interface, changing the thickness of a wall or the angle of an overhang, while being careful not to stand underneath.

      In the afternoon, when the architects have gone home, the assemblers begin the work of garbage collection of the parts of the structure whose design has been changed, so the next nightly build reflects the latest updates. As night falls, they begin to rebuild. The build engineer sings softly to them by the moonlight, alert for signs of trouble that could stall the build.

      — ⁂ —

      Today that isn't practical—the nightly build machine for a single architectural firm would cost several billion dollars. But that machinery itself will come down in cost as we learn to bring the exuberant living abundance of software to other engineering disciplines.

      To do ten "load builds" in the 16 years the Walt Disney Concert Hall took, you'd only need two assemblers, perhaps costing a couple million dollars at today's prices; they'd be able to complete each successive prototype building in 15 months.

      Suppose prices come down and you can afford 32 assemblers, each placing a kilogram of steel every 8 seconds. Now you can do a "monthly build", which is roughly what I did when I joined a C++ project in 01996 as the build engineer. Or you can build 10:1 reduced scale models (big enough to fit 22 people, in this case) a thousand times as fast. Incremental recompilation on the C++ project allowed individual developers to test their incremental changes to the design, and similarly this kind of automation could allow individual architects to test their incremental changes to the building, though perhaps not all at the same time—the full-scale building would be like an "integration test server".

      Suppose prices come down further and you can afford 512 such assemblers. Now you're not quite to the point of being able to do nightly builds, but you can do a couple of builds a week, and you can rebuild a fourth of the Walt Disney Concert Hall overnight.

      Suppose prices come down further and you can afford 8192 assemblers. Now you can rebuild the building several times a day. You can totally remodel the concert hall between the morning concert and the afternoon concert.

      Suppose prices come down further and you can afford 131072 assemblers. Now you can rebuild the concert hall in 10 minutes. There's no longer any need to leave it built; you can set it up in a park on a whim for a concert, or remodel it into a cruise ship.

      Suppose prices come down further and you can afford 2097152 assemblers. Now totally rebuilding the concert hall takes about 30 seconds, and you can adapt it dynamically to the desires and practices of whoever is using it at the moment. This is where modern software development practice is: my browser spends 30 seconds recompiling Fecebutt's UI with SpiderMonkey every time I open the damn page. At this point the "assemblers" are the concert hall; they weigh 5 kg each and link their little hands together to form dynamic, ephemeral structures.

      Suppose the assemblers singing kumbaya shrink further; now each weighs only 300 g, and they are capable of acrobatically catapulting one another into the shape of the Walt Disney Concert Hall, or any other ten-thousand-tonne steel structure you like, in a few seconds.

      (Wouldn't this waste a lot of energy? Probably not, though it depends on the efficiency of the machinery; the energy cost of lifting ten thousand tonnes an average of ten meters off the ground is about a gigajoule, 270 kWh; at 4¢/kWh that's US$11. In theory you can recoup that energy when you bring the structure back down, but lots of existing technology loses a factor of 10 or 100 to friction. Even at a factor of 100, though, the energy cost is unlikely to be significant compared to construction costs today.)

      — ⁂ —

      But tell me more about how programmers need to plan more to reduce the cost of construction mistakes?

  • Enterprise UML modelling tools certainly allow for complete development not only stubs.

> You'd want to design in some other medium

That's why I really like PlantUML [1].

It generates UML diagrams from a simple text markup language.

Much quicker to iterate on, easy to put into a repo and share or collaborate.

Still not something you would use to design your whole code structure, but great for brainstorming or drafting once you internalized the language a bit.

[1] https://plantuml.com/

  • Completely agree with this sentiment: Don't include every detail in your UML, but use it instead to straighten out your high-level ideas. PlanUML is also my go-to for this.

    • I want to add an important affordance of PlantUML: accessibility.

      Using visual diagrams is shutting out vision-impaired developers from ever participating in your process. Maybe you don't have any on the team now, but that could change.

      PlantUML is screen-reader compatible, and it does a pretty good job of laying out the content of a diagram in a way that "reads right".

      I don't think purely-visual diagrams are an appropriate part of modern development for this reason, not without a diligent effort to make an alt-text which conveys the same information. With PlantUML, you get the alt-text for free.

> > To hyperbole a bit, I'd rather spend time writing property based tests and a few types in haskell in a way.

> I'd rather spend some time making sure I'm building the right thing, rather than testing that what I built correctly does the wrong thing.

I don't believe the GP was saying to use tests instead of planning. They were saying to use the tests as planning.

They called out property-based testing in which you describe behavior of the system as a set of rules, such as `f(x) % 2 == 0`, and the test harness tests many inputs trying to find the simplest example that fails that criteria.

They also called out defining types (in their chosen language, not a step removed in a UML diagram), which allows you to think about how the data is shaped before you write an implementation that forces a shape.

I agree completely with your first two paragraphs, but UML, in my opinion, failed to support that approach. Its primary failure is that it neither captured nor communicated the rationale behind the requirements, the answers to "why this?", "why this, instead of that?" and "is this right? is it sufficient?" Answering these sorts of question is central to the production of requirements and also to understanding them, but with UML these questions and their answers are treated like scaffolding, taken away from the result before its delivery.

One might argue that UML could support the capture of such information, but what matters is that this rarely, if ever, was done. It is not the sort of information suited to being presented diagrammatically, or at least not by the sort of diagrams that made it into UML.

One might also argue that no other requirements specification method centered on these features has made it into mainstream software development. Some people here, for example, have argued that the code is a statement of requirements, and code also lacks these features. It does not follow, however, that therefore UML should have succeeded.

Ultimately, UML was an added layer offering insufficient benefits to justify its costs. Its benefits were insufficient because it was predicated on the false assumption that requirements can be adequately captured by a sufficient number of simple declarative statements about how things must be, and that the process of specifying requirements is primarily a matter of making such statements.

It certainly isn't the optimal way. Imagine the UML for a metaclass that creates classes, or for composition/trait based object definitions.

The good UML diagrams are sequence and maybe use case.

Why would you ever not want to iterate your design? Doing is the fastest way of learning. The details can drive a design, so that if you don't remove all ambiguity, you will create an architecture that won't actually work. The problem people who just jump in face, is that they do not abandon their bad prototype and begin again, instead clinging to faulty architecture which leaves them in the same boat as someone who made an architecture unaware of the details.

Agreed ... the thing that bothers me about UML is that it has displaced better, smaller-bore tooling in a significant way. The idea of thinking-before-coding work is of course completely necessary.