|
I've always been blessed by being able to quickly produce and visualize even complex designs without writing them down, which I primarily do for the benefit of others.
And I can do it in tandem with coding. It's a gift. I was a software architect for a time, so I understand design principles, and the rules of engagement. I just break them because I can get away with it and still produce solid designs.
https://honeythecodewitch.com/gfx
I've been adding to this for over a year without fundamentally changing the architecture. I started with gfx_pixel.hpp and went from there, building up bitmaps, and then drawing functions, and then on to more complicated things. And I future proofed it for the most part. It hasn't had a major refactor because aside from some necessarily grotty internals I'm not sure *how* to refactor, it doesn't need one.
But I am abysmally bad at defensive coding, or coding to a precise specification, like you find with bare metal embedded sometimes, or medical or bank software.
To err is human. Fortune favors the monsters.
|
|
|
|
|
Heh, bare metal embedded design/coding is exactly what I've been doing for most of my career (retired now). It's what I enjoyed the most. And yes, after a number of years in the business, the overall design of a project just seemed obvious after reading a spec.
|
|
|
|
|
Mostly ditto.
I do a little more up front designing but it's mostly a research of previously written applications. I do try hard to be consistent with naming, etc. for my future benefit and the benefit of those who might have to maintain it. BTW it's all various generations of ANSI C.
Honey's approach is a gift many of us do not have.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
You don't write code for yourself, or even for the compiler; you write it for the poor soul who has to maintain your code when you have moved on. Therefore:
- The code should, as far as possible be self-explanatory - meaningful variable /function / ... names, etc.
- Where the code is not self-explanatory, it must be commented sufficiently to explain what you have done.
- Ideally, all functional blocks should appear once, and once only, in the module. This implies refactoring common code into functions, etc.
- A design document is typically necessary in order to explain your decisions. This cannot be replaced by comments in the code!
Anything and everything else (code formatting etc.) is a matter of personal taste. Many companies have guidelines that might clash with your preferred style, but this is not a hill to die upon.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
An upvote despite (a) after I've moved on, I no longer care; (b) formatting guidelines that clash with my style are simply wrong.
|
|
|
|
|
You italicized “wrong”. It should be in bold!
If you can't laugh at yourself - ask me and I will do it for you.
|
|
|
|
|
Greg Utas wrote: after I've moved on, I no longer care
IMO, as professionals, we have a duty of care to ensure that software we write for hire is maintainable. Software we write for ourselves can be as messy as we like.
Greg Utas wrote: formatting guidelines that clash with my style are simply wrong
I didn't say that they aren't wrong; I said that it's not a hill to die upon.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
I didn't write this post about what I'm supposed to do. After 30+ years of development, most of that time professionally, I know how I'm supposed to write code.
I wrote this to talk about how I *do* write code, warts and all.
To err is human. Fortune favors the monsters.
|
|
|
|
|
honey the codewitch wrote: After 30+ years of development, most of that time professionally, I know how I'm supposed to write code.
After 30+ years of code development, what you should do should be the same as what you do! Not following accepted practice may be acceptable in an inexperienced developer (that's why we have code reviews - to help them learn), but is inexcusable in one as experienced as you.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
There's a difference between less readable and not readable, and I code on IoT. I don't have the RAM or CPU for your abstractions.
To err is human. Fortune favors the monsters.
|
|
|
|
|
You say that you write "less readable" long functions. Breaking that down into smaller, meticulously named functions, would hardly lead to a significantly heavier footprint, methinx. If nobody else ever needs to dive into your code then
either is fine. But... As others already say: If other folks need to modify your code then it is reasonable to make it easier for them.
And, if one day - by some weird unearthly accident - you would happen to end up in a project with much more people and RAM, would you then write "more readable" code?
"If we don't change direction, we'll end up where we're going"
|
|
|
|
|
I can't remember something if it's offscreen for even a few minutes - my short term memory is shot. That's why my functions are longer. On the other hand, functions that have high "cognitive load" attached to them don't bother me. So for me, longer functions makes it possible for me to navigate my own code.
When I wrote business software, I usually stuck to patterns so closely that my code could pretty much be generated. Then I often generated it.
Nowadays there are entity frameworks and ORM things out the wazoo so I don't even know what people are writing these days, other than sticking business rules into a repository like an RDBMS or something.
I'm happily so far removed from that stuff these days it's a different world.
And I really have no desire to develop desktop or even phone apps.
To err is human. Fortune favors the monsters.
|
|
|
|
|
I am no longer a desktop kid either. But I work on servers. Beeeg video servers.
I like to say: "I write code [so readable] that if I get hit by a bus, the bus driver can continue my work."
"If we don't change direction, we'll end up where we're going"
|
|
|
|
|
A wise man once said “Programs are for people to read and only incidentally for computers to execute”.
Mircea
|
|
|
|
|
It's interesting than neither you nor Daniel mentioned anything about code being for the user.
|
|
|
|
|
Looks like I feel somtehing in the same way.
One does discuss about patterns, refactroring, writing clean code...
... but nobody takes into acount that we should program good programms for the user.
Meanwhile it looks more, that programmers are busy to write code that satisfy themeselve.
|
|
|
|
|
Users don’t care about the code, only the compiled result.
…and your ability to react to their new enhancement requests.
It is primarily for the second reason that developers worry about code structure.
If it is a write once/run once type program, then neither party cares about the structure very much.
|
|
|
|
|
With the possible exception of libraries targeted at other developers, the code is not for the user; the finished application is.
UX design is an esoteric art in itself, that has its own experts. It is possible to write a program that meets every detail of the technical specification, follows the best design practices, etc., but is unusable.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
He was one of my instructors at MIT. Very wise in the ways of coding and software engineering in general. It's far too easy to create write-only code and at the time he made his statement about programs being for people to read many languages simply didn't support readable coding as a default. At the time I was at MIT, Ableson and Gerald Sussman taught the introductory software class (6.001) and on the very first day the first thing they did was:
If you've ever programmed before, raise your hand (I remember looking around and there were close to 700 hands raised, including mine).
If you've programmed in any language other than BASIC, lower your hand (I lowered mine as I had Assembler, APL, and FORTH experience.)
For those of you with your hands still up (close to half the class), you will need to unlearn everything you thought you knew about programming.
|
|
|
|
|
Very nice story! Thanks for sharing.
Mircea
|
|
|
|
|
Well, there's style and then there's style.
I am generally pretty set in my style, so I'm unlikely to change it and also I don't try to force my style on others.
BUT, when the "style" can affect performance, I think attention should be paid.
I prefer to have single-return functions -- others prefer multi-return.
I'm not above putting a try/catch in a catch -- others have freaked the out at the sight.
A few months ago, I was looking into a function which has both features.
This function gets called for every character in a text file (CSV or JSON for the most part), so performance is important. (I was testing with a 28GB CSV file.)
Which meant I had a good opportunity to test the relative performance of different "styles" of the function
single- vs multi-return
try/catch in a catch vs not (not having the try/catch in a catch required multi-return as well)
So I had six test versions to compare. The results were inconclusive.
On the plus side, I did wind up with a text reader which supports only UTF8 and performs better than the built-in .net Stream Reader (which has to support other encodings).
I may add more to this response later.
(Later)
OK, I want to add a bit. You mentioned having functions with many lines.
Yes, having shorter functions which have a more limited functional scope can be a benefit in most circumstances.
But it can also lead to performance degradation in others. As I worked on the code I mentioned above, this was something I had in mind.
My text file reader needs to be able to replace certain non-ASCI characters (NPSP, "smart"-quotes, etc.) with their ASCII equivalents.
I began with using the built-in StreamReader -- it can read and decode ASCII, UTF8, UTF16, and other encodings (I assume).
ASCII being a subset of UTF8, I need only UTF8. Additionally, using the StreamReader, once I read a character, I lose any information the reader had about its ASCII-ness, which meant that I then needed to test each and every character again to determine whether or not it is ASCII.
But by writing my own reader, I was able to test the ASCII-ness of each character only once and then test only the non-ASCII characters (which are less than 1% of the total characters in the file) for whether or not they are ones I want to replace.
In the real world, FandG ( x ) often out-performs F ( G ( x ) ) -- smaller single-purpose functions are not always better.
Consider how performance suffers when each function in A ( B ( C ( D ( ... ) ) ) ) has to check its input for NULL, or range, or whatever, when we know that the previous function already did that.
modified 18-Sep-22 22:44pm.
|
|
|
|
|
My desk may be a mess, but my code is always clean; no matter how trivial. Engineers don't build ugly structures even if they meet specifications.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
"clean" is a slippery concept. I think what constitutes clean is very subjective.
I am a stickler about the APIs I produce being concise, flexible and intuitive. That's what I consider clean.
The code behind it tends to be (I think) elegant. More elegant than it used to be from me, at the expense of readability sometimes.
One of the reasons I focus on IoT these days is because of that. In this arena, projects are necessarily smaller because they have to fit, and CPU cycles and RAM matters. Abstractions don't add as much value given the above, and project lifespans tend to be shorter simply by virtue of the devices being simpler.
There, elegant code with a clean API carries the day. The API sort of buttresses the internals, making them sensible to use, so some amount of maintenance is possible.
The code behind it isn't usually impossible to maintain, but it is more difficult than say, a business application or an application with a large team behind it, at least as I write it.
To err is human. Fortune favors the monsters.
|
|
|
|
|
honey the codewitch wrote: I wonder how many of us do it? I do. Your coding style is just that; and if you in a team, you adjust to the team and do as they do.
One of my employers demanded that SQL statements be in a string without line breaks. He was fed up with people reformatting statements. From that point on, all SQL commands were a single-line string, without formatting. You'd be scrolling a LOT just to read the damn thing. So I made a VS plugin that shows the formatted version (rather simple, need just a CRLF and some spaces after some keywords). Saved a lot of time when reading the command.
I don't care how you choose to format your code; I can simply reformat the existing code and commit it, and I will. The stuff I'm not allowed to touch, I'll make readable.
You go ahead and put time and effort into formatting your code; I'll correct it by placing a single character
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
I guess what I'm talking about is deeper than style - deeper than things you can really have standards for. More, it's about how we attack problems. How we dissect and solve them, which you can't exactly standardize beyond say GoF patterns and such.
Edit: The title of my post is sort of misleading but I don't know how to express it concisely.
To err is human. Fortune favors the monsters.
|
|
|
|
|