|
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.
|
|
|
|
|
honey the codewitch wrote: I guess what I'm talking about is deeper than style I guess it not worth the money.
honey the codewitch wrote: deeper than things you can really have standards for. I can reformat code in VS without much ado. It's just the crap in strings that doesn't get formatted, because, well, it's a string and not code.
Show me ONE real life example where you doubt over formatting?
If someone else doubts; just reformat using VS using the default settings - as THAT is what is expected and preferred
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.
|
|
|
|
|
Nothing I wrote had anything to do with doubt? I think you misunderstood me.
To err is human. Fortune favors the monsters.
|
|
|
|
|
I keep misunderstanding you; what do you mean nothing you wrote had to do with doubt? I'm not interested in your style, I'm interested in deliverables.
Now; show me any example.
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.
|
|
|
|
|
Coming from the automation world I have noticed that my way to code usually differs a lot from other people that always coded in "high" languages.
Sometimes for the good, sometimes for the bad.
I do try to assimilate things in my own "style" when I find something that I like and / or surprises me in the good way. But I am not always successful with that on the long term.
So far, all the people that read my code could understand it and that was / is the most important to me. Sometimes I do things complicated, sometimes I do things way simpler than others.
At the end of the day, as long as it does what it has to do and how it has to do it... I don't really care.
[Addition] Something people have often told me: "Why didn't you use XXXXX for that?" because I tend to reinvent the wheel. Sometimes because I don't know that other function even existed, sometimes because I don't like how it works / performs.
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
I completely agree, but I would equate it to a major net win.
If you give me one big function, that attacks a part of the problem efficiently, I never need comments or documentation to figure out what it does or why.
If you give me a composite design, I need proper documentation and comments beforehand, and I will need to trace your code while debugging, to:
A) figure out which part is fluff, and which part is functional necessity
B) compare it to common patterns, to distill the overall intent of the initial design
C) align the actual problem set with a stripped down version that discards most if not all of the design, before I will commit to maintaining it
23 years of higher level programming has lead me to the conclusion that design is not an artform, it's a tool that can be used to remove friction prior to replacing a component, or to promote form-over-function for selfish reasons.
In general, everything is overdesigned for selfish reasons.
|
|
|
|
|
I didn't start coding this way until my first psychotic event - meaning after I started seeing things that weren't there. That was in 2018. I went manic for a week, and I haven't been the same since.
I'm still dealing with the fallout to my brain, yet fascinated by it, while frustrated with living with it sometimes.
I started coding in 1986 when I was 8. I haven't really put it down for any serious length of time, so a lot of how I code is probably experiential but it did change significantly for me after I went over the high wall.
I can't code the way I used to anymore. I wouldn't be capable of it. It reminds me of whenever I go to order coffee and the fact that I could never do a barista's job is thrown into stark relief.
So part of it is a crutch, but it has its advantages, I think too, as you've reiterated above.
To err is human. Fortune favors the monsters.
|
|
|
|
|
Depends on whose navel it is. Once you have decided which meaning of navel you would use, everything else is easy, funny and weird.
"It is easy to decipher extraterrestrial signals after deciphering Javascript and VB6 themselves.", ISanti[ ^]
|
|
|
|
|
I am always fascinated by the way people code. It's a bit of a window into their minds - or a snapshot, really, since, as you say, we evolve.
I recently switched from 'readable' code to maximized use of the language after reading an article about the same. I enjoy putting a chunk of logic all in 'one line' of code where the language allows, and often it is much more readable that way for the one who knows the language well - for me it certainly is. One example is ternary operators. I also have begun to search for the most efficient way to accomplish a task when there are several, where "efficient" is measured in processing time. An example would be: when is it more efficient to use if-then instead of a switch (usually, sadly, since switch is so pretty in the code)?
Growth comes with much navel gazing
|
|
|
|
|
My guilty pleasure is complicated chains of template specializations - the ultimate in write-only code.
It's sooo powerful though. I am constantly drawn to the dark side. They have cookies.
To err is human. Fortune favors the monsters.
|
|
|
|
|
I swing the other way, so to speak. My code gets more modular, more factored as I age/gain experience. I too can now usually begin coding without much up-front thought, but I can do this because I explore the design in the language of code instead of some other language like diagrams, lists, etc. Abstraction is part of my design process. When I don't abstract, I get lost in the weeds.
|
|
|
|
|
I like the way you think. I'm not in IoT or embedded but videogames are similar (and it's rare that the code ever gets revisited after a year of patches).
As to readability, we had a saying some years ago "If you can't figure out what the code is doing, leave it alone, it's doing fine...a more worthy engineer will figure it out someday"
|
|
|
|
|
I haven't gotten any team I've worked with to buy in, but IMHO it depends what kind of coding style issue we're talking about:
1- Class, method, variable, function names... Identifiers should be logical and predictable. If your project uses getX() and setX(newX), or if it uses x() and x(newX), just do the same thing across the board! Rules like methods and functions should be verb expressions, etc.. Even whether or not to CamelCase acronyms -- is it convertToPdf() or convertToPDF()?
2- Layout: my feeling is more "Hell no!" Allow any sane code layout. The cost to the author to think about such things is too much higher than the cost to the reader to put up with them for such standards to make sense. (That said, my current team uses a plugin for Eclipse, Intellij and Jenkins to enforce the layout standard.)
Code complexity is somewhere in between, and I haven't really thought about as much as those two extremes. Code has to be maintainable. If your logic is hard to follow, the next developer to touch it is more likely to introduce a bug. Maybe I would be comfortable with longer methods IFF it means more comments are there as well.
|
|
|
|
|
#include <stdio.h>
template<int Pin> class foo {
constexpr const static int pin = Pin;
public:
constexpr inline static char test() __attribute((always_inline)) {
if(Pin==-1) {
return 'A';
} else {
return 'B';
}
}
static_assert(test()!=0,"test");
};
int main(int argc, char** argv) {
printf("%c\n",foo<-1>::test());
printf("%c\n",65);
return 0;
}
I'd like someone smarter than I am to explain to me why the first printf does not generate a mov esi, 65 or even movsx esi, 65 , but rather, 3 instructions that are seemingly redundant and yet don't get removed by the peephole optimizer, but I don't think that's going to happen.
The worst part is, I have a dozen libraries using a bus framework I wrote that relies on my bad assumptions about the code that is generated.
The upshot is the code is slow, and the only way to speed it up is to
A) rewrite it to not use templates
B) nix the ability to run multiple displays at once
But IT SHOULD NOT BE THIS WAY. I feel misled by the C++ documentation. But it was my fault for not checking my assumptions.
To err is human. Fortune favors the monsters.
modified 18-Sep-22 4:19am.
|
|
|
|
|
Is it because printf returns a value which has to be moved somewhere?
|
|
|
|
|