Hacker News new | past | comments | ask | show | jobs | submit login

Except at the highest level of abstraction, my Lucidchart diagrams and Google docs never survive their first encounter with the compiler. There always turns out to be some fatal flaw that's obvious in an editor but totally escaped me in the word processor. My (limited) experience has been teaching me the opposite: dive in as quickly as I can and write some code to explore the problem space, then go think harder about a design after getting my feet wet.



I once worked on a Finance project which had grand aspirations and decided it was going to Do Things Right by starting with extensive specifications.

The developers insisted on all behaviour being specified and documented before they would start coding. Of course, a truly exacting specification is equivalent to code. So the users who had been tasked with describing the required functionality ended up inventing their own DSL and “coding” the entire system in Microsoft Word.

Needless to say, they were the only ones who understood the spec. IT cried foul. Business cried “this is what you asked for!”

Cue months of arguments over what constituted a proper spec, during which the users essentially taught themselves how to code. The software eventually ended up being written by transliterating the DSL into actual code.

It worked, but remains to this day an unmaintainable mess.


So the documentation was simply incomplete, because the DSL, as a language, was not documented properly. This is why the initial developers were unable to have it maintained by others.

Essentially the same problem, just on a higher level of abstraction.

Oh, and failing to document DSLs is really a common mistake: No docs, no spec, no helpful error messages, and so on. Just like the very early parsers or compilers. But DSLs are really the most important thing to document, as these are so much harder to get into ... the "simpler" parts of the program are usually readable and understandable with less effort, even with pure code and no docs at all.


To those who downvoted: Do you care to elaborate?

What's wrong with demanding to document a DSL?


Well, the DSL flowed out of documenting the problem. Having non-technical people write a DSL, and then proceed to document that DSL, is not really addressing the core problem which was knowledge transferrence. Why do you feel they'd be better able to document a DSL than they were documenting the domain?


The whole purpose of a DSL is to make the whole system simpler, by separation of concerns.

That is, the DSL as a language is still much simpler (fewer data types, fewer elements, fewer rules, etc.) than the whole application, which is built using that DSL.

So I'd expect the DSL's documentation to be short and targeted at the people writing within that DSL.

If the DSL's documentation is more complicated than the original problem (spec), it failed at its purpose.

BTW, ultimately you have a chain of languages, such as:

    Spec <- DSL <- Meta-DSL <- ... <- programing language
But in the end, that chain goes from complex/specific to simpler/generic. So the documentation effort should shrink dramatically from one step to another (or your system design is seriously flawed). Usually, the Meta-DSL or Meta-Meta-DSL is already the plain, generic programming language you are using. And that one requires no documentation writing at all, because is already documented and widely understood.


> It worked

Congratulations!


Indeed, usually these approaches are abandoned due to reaching a point where arguments over specifications consume years and nothing happens. The project is killed and everyone involved are reassigned elsewhere, hopefully having learned something, but usually there's no such evidence of learning.


This is truly a great anecdote. I wish I could bookmark comments on HN, because I want to dig out this one when the time comes.


> I wish I could bookmark comments on HN

You see that "X hours ago" to the right of the username? Yeah, click that...


In all fairness, it's not entirely obvious that this is how to do it.

But it's a good tip nonetheless. Once you click the "x minutes/hours/days ago" link, besides bookmarking the resulting URL in your browser or elsewhere, you also have a few more options that show up at the top of the comment page. One of them is to "favorite" the comment. You can also favorite a submission in a similar way.

Just be advised that your favorite submissions and comments lists are public.


> it's not entirely obvious that this is how to do it

I totally agree that this is an example of insane, hidden functionality. How could anyone know that "click timestamp" = "view details"? Makes no sense.

However, seemingly every site/app has adopted this, from Twitter to Facebook to several PM services.


It's the only real 'title' of a comment beyond the user name, and the user name is already a link.


OK, so on HN, it's clickable. But "gray text without underline" isn't always clickable on HN. This is true of other sites: it isn't even clear that the timestamp is clickable at all, let alone what'll happen if you do click it.

Why not acknowledge that this is a problem and just add a little "Permalink" link, which some sites used to have? Or at least a permalink icon?

Surely the combined design talent of Google, Facebook, and Twitter can solve this problem better.


I think hidden is not quite the right word. It's a link, likely displayed in a hypertext browser.

A hypertext system that doesn't treat links as slightly opaque, explaining them in detail wherever they appear, sounds unpleasant to me.

I guess you could probably modify most such systems to have a flashing popup on every link that said "There is more information available if you click on the text here!!!!".


> It worked, but remains to this day an unmaintainable mess.

The question is: is it a worse mess than if you'd have started without the spec? My intuition says "no", and the experience the users gained regarding formal thinking is a huge net benefit that will be an asset for years to come.


I am not a programmer. I have done a lot of programming. Eventually, I was able to hire competent professionals. I have taken very few formal courses in programming and zero in what I'd call computer science. I programmed out of necessity. Computers were pretty useless if you didn't.

So, take this with a grain of salt.

I can't code without a diagram. I make a diagram and process the logic. I make lots of sub diagrams. I make notes and ask myself a lot of questions. I'll also ask other people, if I can.

I can't do it. I can't program 'on the fly.' My attempts have resulted in horrible results, not even qualified to be called results. If I don't process the logic, pretty much from start to finish, I can't do it. I use a notation system that isn't even a real programming language and leave lots of room to cram more stuff in and make corrections.

Most of this is past tense, I don't do much anymore. I'm retired and my efforts are just little automation tasks for my own needs.

Anyhow, I figured I'd offer another perspective/opinion. I envy you if you can do it off the cuff. I've tried, I can't.


I think it depends on thinking style and mental models. Personally I have "diagram blindness"; most diagrams look like visual noise. Usually I get better (fast, reliable, maintainable) results by just coding on the fly and then relentlessly refactoring as the optimal design gradually reveals itself.


I have a CS degree and a few years professional programming

I have coded on-the-fly and I have coded from diagram first approaches.

on-the-fly works for me when there is an obvious data structure to work to, otherwise it takes a lot longer than planning it out because of all the edge cases


Data structures and ADTs are the key in general.


If you consider the diagrams as a physical manifestation of abstractions that can eventually be converted into boolean logic, etc than it's the same thing. For many years I used to draw on paper a mix of non-standard diagrams with some pseudo-code to discuss slightly complex algorithm implementations with peers... the more coding experience you have, the less you need to do this and you usually make the connections just in your brains and start coding.

So my tip here is if you want to learn how to do it on the fly you should start with small steps by reducing the amount of stuff you need to see in a paper before start coding. In the other hand it's perfectly normal and there is no problem in doing what you do.


When I program 'on the fly' I either have the diagram in my head, or I'm working 'linguistically' such that things are correct-by-construction / facts about objects are true because-of-what-they-are rather than because of what they do. For example, using std::shared_ptr to manage a resource instead of trying to reason out all the cases to manually free the resource. I guess what I'm saying is that rather than thinking about all the cases to see that the code does work, I try to write code in a way that it is not possible that it does not work.


>>There always turns out to be some fatal flaw that's obvious in an editor but totally escaped me in the word processor.

This problem goes away once you gain some experience - both in writing specs and in programming.

Think of it this way: do engineers build bridges without design documents and diagrams? No. So why are you writing software without them? If you aren't familiar with the problem domain, fine, do it the agile way. But once you gain experience there is no excuse to not thinking problems through in advance before trying to solve them.


It's faster and more pleasant to write working code than to write prose descriptions of hypothetical code.

Documents are cheaper to create and easier to change than bridges. Code is just another kind of document.

I've a sneaking suspicion that bridge building would look more like software if we could drive over AutoCAD models. (Or that software would look more like bridge building if we were still compiling by hand).

EDIT: I should add that I certainly do write and communicate documents about "what business problem does this even solve" and "what does it do" and "what are the major components and what are they responsible for" and "did you consider X alternative design" but planning down to the level of function signatures has usually turned out to be a waste of time.


>>Documents are cheaper to create and easier to change than bridges. Code is just another kind of document.

That really depends on the type of code you are writting.

Writing code going into a space craft, or Nuclear Power Plant, or Encryption code that can be relied on by people to protect their actual life, or code going into a medical device or.... you get the picture

Yes if your writing code going into the next Pokemon time waste game sure you can be fast and lose, but to not presume all code is the same.

In this instance, code is going into devices that historically do not get updated properly, I think that warrants taking a more "bridge building" approach and less "Code is just a document" approach


I think for that argument to work, you'd have to show that the word processing activity actually yields fewer errors in the resulting software. I guess what I'm saying here is that I've found writing prose beforehand to have low to zero ROI in terms of resulting software quality. I totally believe that writing math and actually proving things about your ideas would.

The more important code is, the more I want to see it subjected to a realistic and comprehensive test suite, careful peer review, etc. Although you're right, I ultimately work on backend systems that can cause some downtime at worst, not industrial process control or crypto libraries. I also have the luxury of doing continuous delivery, incremental rollouts, feature flags, staging environments with shadow traffic, etc. so there are a lot of safeguards standing between a mistake and widespread impact.


This is not specifically only a reply to you, but it seems like the two camps of "detailed specification on paper/word processor" and "code on the fly, because the code is a document" are missing a third alternative, which is TDD (ie, the tests are the specification), and a fourth alternative, which is literate programming (the code and specification are written together).


One can also use executable models, either in same language as the implementation, another general language with nice libraries or a DSL. For instance finite state machines


> I've a sneaking suspicion that bridge building would look more like software if we could drive over AutoCAD models.

Why on earth would you want bridge construction to be more like software engineering? Bridges work. We know how to build them bug free, every time. We don't know how to make working, bug-free software. There's even an old, not very funny joke about exactly this comparison. (Spoiler: it doesn't flatter the code monkeys.)

You might want to look up the Cynefin model[1]. Bridges are complicated, software is complex. This supports your bent towards experimentation, sort of; when solutions are unknown, that's required. But documentation and planning are part of what turns complex in to complicated, and that's a big part of the trick to successfully delivering big chunks of relatively bug-free code.

[1] https://en.wikipedia.org/wiki/Cynefin_framework


We have the mathematical tools describe everything that might happen to a bridge and determine how it will respond. Obviously that’s immensely valuable. Such tools are not available for handwavy descriptions of software in Word.


Your last sentence is actually kinda close to relevant to what I was talking about, but for the wrong reason. I suspect as your career progresses, you'll figure it out - most engineers do.


Yeah, someone pointed this out to me once, and it is an interesting spin on the comparison of software engineering to other types of engineering. More succinctly:

We don't build our "bridges", our compilers/interpreters do.


The engineers don't build the things either, the construction workers do.


Sure, but it’s the construction work that you don’t start until you have exhaustive documentation.


Code is just a detailed specification. A better analogy is that you start with designing the nuts and bolts without knowing how the beige is supposed to look.


Programming is the design. Building is performed by a compiler (free part).

Also, flowcharts are less readable than most programming languages in non-trivial cases. Graphical programming languages are mostly useful as DSLs. Text is unbeatable in the general case.


> This problem goes away once you gain some experience

As will the need for planning beforehand.


People are very different it seems.

I enjoy both diagramming and early exploratory coding.

I have real problems when one of my (really smart) colleagues wants to discuss some code we have neither written nor diagrammed yet.

For her however that seems to be the natural way of doing it and when we started working together I had to point out that just didn't work for me.

It seems to me that knowing and being aware and accepting of the different learning styles can solve a number of problems in teams.


Thinking in state machines is not the same as design up front. Most languages lack a good way to describe state machines, but there are many libraries which do this and even produce the diagrams for you (which can be very helpful when trying to understand the code). I frequently write state machines in an incremental manner.


Enums (or named constants if you don't have enums) and switch statements (or if you don't have these, make a hashmap of state->method or something) are all you need. I'm not sure I get what you mean.


One of the primary features of state machines is that state transitions are well-defined. "Describing state machines", as the GP said, is typically done with tools like a reachability matrix or truth table. A looped switch statement will allow you to implement a state machine, but not describe it.

In other words, how would you express in code: "state Z can only be entered through either state W or X, but not through state Y", or "state V must be followed by state W, but only after condition A"? Sure, you can write a switch statement. But half the rules of a state machine can only be implemented by omission (i.e. by not coding it, instead of hardcoding the requirements).


Isn't this where formal specification languages like TLA+ are useful?


I sometimes describe TLA+ to people as "unit-testable flowcharts." It's pretty inaccurate but kinda gets the idea across?


yes




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: