Live data from Hacker News

How to Build Good Software

csc.gov.sg

241–247 of 247 posts

Re: How to Build Good Software

#241

Earlier quoted context omitted.

Documentation is essential. How things work is an important thing to document. Ideally it should be in version control and be generated from the code, because then it's less likely to go out of date. My solution to this is old and fairly unpopular, but I stand by it: anything in the codebase that's not obvious to a new maintainer should have a brief, explanatory code comment. Generally, this falls into two categories…

Why not: return nil if country_code==KERPLAKISTAN and day_of_week==MONDAY Then you don't need comments and the sync problem goes away?

This is admittedly a trivial example, but ideally you want developers who understand why we're doing this.

Is this a quick thing somebody hacked in for a special, one-off, tax-free month in Kerplakistan as the country celebrates the birth of a princess?

Is this a permanent thing? Will there eventually be more weirdo tax rules for this country? Will there be others for other countries?

Knowing the "why" would help a developer understand the business, and reason about how best to work with this bit of code... should we just leave this ugly little special case in place? Should we have a more robust, extracted tax code module, etc.?

Commit messages help to accomplish this too, and can offer richer context than inline comments. Each has their place. Sifting through hundreds of commit messages in a frequently-updated module is not a great way to learn about the current state of the module, as the majority of those commit messages may well be utterly stale.

Ultimately the cost of having some concise inline comments is rather low, and the potential payoff is very large.

Remember that the longer term goal (besides the success of the business) of software is to have your developers gain institutional knowledge so that they can make more informed engineering decisions in the future.

Re: How to Build Good Software

#242

> Reusing software lets you build good things quickly It also introduces unknown amounts of debt and increases the likelihood that you'll end up with intractable performance/quality/velocity problems that can only be solved by re-writing large portions of your codebase. This can be a dangerous cultural value when it's not presented with caution, which it isn't here. I think it's best to present it alongside Joel Spoe…

Yeah I think the OP article is great but doesn't pay enough respect to the costs of dependencies.

Re: How to Build Good Software

#243
post #7

Nice post! Agreed on keeping the initial stuff simple as possible. In python, I typically follow a pattern of keeping stuff in __name__ == '__main__' block and running it directly, then splitting to functions with basics args/kwargs, and finally classes. I divide into functions based on testability btw. Which is another win, since functional tests are great to assert against and cover/fuzz with pytest.mark.parameteri…

I prefer putting the main code into a "main" function (called from the __name__ == '__main__' block) fairly early, since otherwise the functions you extract might accidentally keep relying on global variables.

Re: How to Build Good Software

#244
post #243
post #7

Nice post! Agreed on keeping the initial stuff simple as possible. In python, I typically follow a pattern of keeping stuff in __name__ == '__main__' block and running it directly, then splitting to functions with basics args/kwargs, and finally classes. I divide into functions based on testability btw. Which is another win, since functional tests are great to assert against and cover/fuzz with pytest.mark.parameteri…

I prefer putting the main code into a "main" function (called from the __name__ == '__main__' block) fairly early, since otherwise the functions you extract might accidentally keep relying on global variables.

Good point

I like to do it early also, to make sure that the new script, if imported from by a sibling module, is inert.

An example would be a scripts/ folder and sharing a few functions between scripts w/o duplicating.

In some cases I don't have a choice. Initialization of a flask app/ORM stuff/etc has to be done in the correct order.

I think the general rule of thumb I follow is: avoiding keeping code that'd "run" in the root level. Keep it in blocks (normally to me functions) has the added effect of labeling what is does.

What I don't do: I don't introduce classes until very late. In hindsight, every time I tried to introduce a complicated object model, I feel I tended to overengineer / encounter YAGNI

Re: How to Build Good Software

#245

Earlier quoted context omitted.

Have you read "Introduction to Cybernetics" by Ashby? (PDF available here: http://pespmc1.vub.ac.be/ASHBBOOK.html ) Cybernetics might be the "missing link" for what you're talking about.

I didn't dive to deep into this so I could be wrong but this looks like control theory with elements of category theory. I'm looking more for a theory of modules and relationships. Something that can formalize the ways we organize code.

From my POV control theory is rediscovering cybernetics, but yeah.

It sounds like CT is what you're after (to the extent that we have it at all yet...)

Re: How to Build Good Software

#246

Earlier quoted context omitted.

In Scrum, you don’t write code based off User Stories. The scrum team agrees to a set of Stories for the sprint, and then the scrum team breaks those stories into a set of Tasks which are the actual work that must be done. The User Stories are just something the product owner uses to show stakeholders that the project was successful.

1) In the Hermes Conrad sense, this is technically correct. 2) In my experience, this basically never happens. Your comment encapsulates a lot of what I have come to call "Scrumbutt." It's Scrum, but . And while I have no idea if it's intended on your part, the sentiment is a fantastic way for a Scrum consultant--only some shade thrown; I've been a "DevOps consultant" before, after all--to come in and pull from deep…

You’re projecting “shade thrown”.

People might be interested in what Scrum is. I know I am. That’s why I pointed out the error. It was a shock to me to learn I wasn’t doing anything close.

Readers can do with the info what they want.

I’m not sure if I can say the same of your comment. You seem to be trying to make me feel bad for commenting? Or accusing me of hawking pointless info for consulting fees? I really can’t tell.

Re: How to Build Good Software

#247

Earlier quoted context omitted.

> Does anyone have any suggestions on how to fix this? Have a product wiki (e.g. MediaWiki). Have documentation in source code that compiles to HTML code, which can be linked to/from the product wiki (e.g. JavaDoc in Java, Natural Docs for languages that do not directly support compilable documentation). Make building and publishing this documentation a part of the continuous integration. When you have this, make it…

> Have documentation in source code that compiles to HTML code, which can be linked to/from the product wiki (e.g. JavaDoc in Java, Natural Docs for languages that do not directly support compilable documentation). Make building and publishing this documentation a part of the continuous integration. Are you referring to something like Knuth's Literate Programming (en.m.wikipedia.org/wiki/Literate_programming)? As a n…

No. I think one should organize the code as the code needs to be organized, and the documentation can either follow along (if it describes parts of code contained within the same file) or be placed separately (if it relates to multiple files), where "separately" could still be a package-level JavaDoc, or an external wiki.

I have never tried the Literal Programming, so perhaps I am out of my depth here, but I strongly suspect it only works after one has already mastered the usual ways of programming. That you do not have to structure the code qua code, because you can already do it in your head. But it's hard to imagine what one has never done before.

For example, if you never tried programming the usual way, how do you know when and why to put "Header files to include" in your Literal code? It's only because you can imagine the constructed code, you know where the header files go in the result, so you know where to place them in the Literal version. Otherwise, it would look quite arbitrarily.

I don't know about documentation in Python, but the JavaDoc (and Natural Docs) work like this: You put comments to classes and methods, or packages (and files), along with the code. So you can read them and write them while you are looking at the code. But then you run a "documentation compiler" that extracts the comments and builds a separate HTML website out of them. Here you can browse and read about what the individual classes and methods do. The idea is to make this a part of the continuous integration, so that whenever you update the source code and the related comment, the HTML website also gets updated.

Java supports this out of the box. When you install the Java compiler, you also install the Java documentation compiler. When you read the official documentation to the standard Java classes, those were made using exactly the same tools you are encouraged to use.

I don't know whether Python has something like this. If yes, go ahead and use it. If not, look at Natural Docs -- it is a system to provide this functionality to languages that do not support it out of the box. Just try it: document a part of your existing project, compile the docs, and see whether you can imagine any value in reading that.

Post reply on HN