Years ago, I created a proprietary commercial program that was character based and strictly modal. Now, no one saw my code but me, and so I pretty much developed my own coding style. One of the standards was that every function have one entry and only one exit. I never used a return statement anywhere except at the very bottom of a function. My usual practice was to start every block of code with a “while true”, write the code and if it needed to stop due to an error or user pressing the Oh S key or whatever, I could issue a break statement that would drop me to the bottom of the while loop and allow me to clean up any things that needed to be done before the return. Of course the last statement in the loop was a break, so the code wouldn’t loop. The loop was strictly to allow me to have one exit point.
I am now creating a GUI application in C++ and am up to my ears in How To books. Nowhere do I see an example of using a single exit point for a function. There seems to be no concern for cleaning up, and that worries me especially using a language with no garbage collection.
So, I’m asking: What is/are the accepted methods of writing functions that will allow me to keep things clean?
In other words, a style where you minimize or eliminate changing variables with the expectation that the result is highly predictable.
I don’t know that there is necessarily only one way to write code…
As long as you don’t violate fundamental practices like writing structured, easily understood code.
You may be correct. That’s not an easy document to grasp at first read. One of the reasons I coded the way I did was when I took a job supporting a project written by another. Each afternoon, around 2:00, the whole system came crashing down. I started looking at the code to see what time functions were being used only to find many, many instances where the original programmer simply used block copy instead of creating functions. He also left in the middle of procedures and functions creating a memory leak situation. It was sickening to read and obviously didn’t work.
I have to wonder if using a goto and label at the end of each code block wouldn’t be a better method. Guess I’ll have to try it and see what it looks like. I just can’t seem to be willing to quit halfway through.
Well memory leaks are a large part of it, but, resetting labels, colors, menu items, all sorts of thingies that change when you add or remove messages and titles and the like. That’s really what I meant. Going in to a user input function or procedure I can save titles, positions of things, which procedure called this function, which files are open (depends on the database manager) and a lot of other things. If the user decides he’s in the wrong area or just changes his mind and hits the esc key part way through the entry process, I need to drop through the entry screen and reset all the things I changed when I entered. That’s what I meant by cleanup.
In opensuse.org.help.programming-scripting, you wrote:
> Well memory leaks are a large part of it, but, resetting labels, colors,
> menu items, all sorts of thingies that change when you add or remove
> messages and titles and the like. <SNIP> I need to drop through
> the entry screen and reset all the things I changed when I entered.
> That’s what I meant by cleanup.
I don’t think a functional programming paradigm will work well for this kind of cleanup. Since you’re coding in C++, I
think you’re best bet for avoiding memory leaks by inheriting your GUI objects and coding explicit destructors or using
smart pointers: https://en.wikipedia.org/wiki/Smart_pointer . If you need to GUI objects to reset, I can’t see any
reason why you code this.reset() or this.cleanup() member functions for each of your objects.
I also can’t see much advantage of avoiding mid-function return statements. In C++, it certainly doesn’t improve code
readability since it necessitates introducing additional but avoidable branch statements. It also makes the code less
robust and vulnerable to silent bugs if the memory contents of the pointer/reference arguments are unintentionally
modified in the code following where the return statement should be. But I think the worst problem about avoiding
mid-function returns in C++ is that it makes returns from base class member functions far less readable compared to the
intuitive version e.g:
int InheritingObject::memberFunction(bool useBaseFunction = false) {
if (useBaseFunction) {
return BaseObject::memberFunction()
}
// InheritingObject version of the function begins here
}
vs the version avoiding a mid-function return:
int InheritingObject::memberFunction(bool useBaseFunction = false) {
int returnFlag;
if (useBaseFunction) {
returnFlag = BaseObject::memberFunction()
}
else {
// InheritingObject version of the function begins here
}
return (returnFlag);
}
Point taken! Never had access to .reset objects before! I’ve got to completely change my old ways! This has put the fun back into programming. I’ve missed that. Thanks for you reply.
Object-oriented code; readability of code; execution stability.
IMHO the (formal) bottom line is: “Code inspection; Module Test; Integration Test; System Test.”
Given that, the testing environment includes tools such as “Valgrind” – see “Dynamic program analysis” in Wikipedia.
BTW, by “Code inspection”, I mean the formal process first suggested by Michael E. Fagan and further pursued by Tom Gilb and Dorothy Graham.
Is “Agile development” better?
IMHO if and only if “Agile testing” is used to confirm that “done is done” but, even then I’m not convinced – even if a portion is “done”, how does that portion interact with all the other portions which are also “done”.
The “daily crash at 2 pm” is a good example – something happens at 2 pm every working day which causes the system to misbehave despite, every portion of the system behaving perfectly, individually, at 2 pm.
Ask people who work in the automotive industry: the code executes perfectly in the software laboratory – under the bonnet it falls apart …
[HR][/HR]Someone said: "Everything should be as simple as possible but, no more simple than that … "
Someone else said: "Software development is the most complex and difficult task that mankind has foisted on itself … "
I was poking around, I think youtube, and in the comment section of a video clip about how to do something, one of the commenters remarked that the author went to excess with the code. Her reply was that she worked in the automotive industry and they had a hard fast rule about having only one exit point to any block of code. Then, I see your remark. Perhaps I should do a 6 month stint for one of the big three, I’ll bet I’d be good when I came out!
You give in too easily.
There are many acceptable styles of programming and Functional Programming definitely has its points.
It might not be the best for all scenarios, but in the hands of a real Code Warrior, even this can be pretty impressive coding (I’ve seen some).
And, in some situations like inaccessible situations you want the code to be as bullet-proof as possible.
Or, you want each code block to never or hardly ever need to ever be modified after creation.
Or, you’d be surprised how clear the code can be if the code is uncomplex and certain.
On 2018-03-12, tsu2 <tsu2@no-mx.forums.microfocus.com> wrote:
> You give in too easily.
> There are many acceptable styles of programming and Functional
> Programming definitely has its points.
Careful. The automotive industry has standards which include software coding practices and, they’re audited against those standards: you’ll need somewhat more than 6 months experience in there …
If I correctly recall, the standards used by the automotive industry have issues around Functional Programming and C++ – the two do not match at all well, which is why C++ is “difficult” in that industry.
[HR][/HR]@montana_suse_user:
A software tester usually doesn’t worry too much about coding standards; what really matters is the stability and functionality of the System under Test.
The only exception is “Testing against requirements” and a requirement that the code has to conform to a given, defined, set of coding practices – either, someone has to write the Test Case and prove that the code meets the required practice(s) or, the requirement has to be ditched …
One of the standards was that every function have one entry and only one exit. I never used a return statement anywhere except at the very bottom of a function.
“Forget the “one return per function” rule. This is a good C advice to avoid leaks, but it is outdated in C++ because of its use of exceptions (use RAII instead).”
Of course when makes a statement like this, my first reaction is to run it through an Internet Search engine… Today’s search engines are pretty good at returning whatever might be considered most important within the past 6 years or so.
So, searched “automobile industry software coding practice functional programming” which even returned this Forum thread near the end of the second page.
Didn’t return anything that expressly discouraged Functional Programming for automotive industry software code (not too surprising to me).
Did return a few hits that described the importance of functional objects and related testing which are common sense and not related to Functional Programming at all.
Returned a few hits which mentioned both C++ and Functional Programming, none of which suggested that the two are exclusively incompatible (not surprising to me).
Returned hits that describe first steps in Functional Programming for several different languages.
Returned hits that describe why Functional Programming is not seen more often.
Personally, I am not or prefer to write code in the style of Functional Programming, but feel that it’s a worthwhile approach that has no language bounds including in C++. That’s because Functional Programming is a <coding style> that can be practiced in many situations and has no requirements that would prevent it from being used by any specific coding language
And, of course more broadly anyone who is interested in exploring C++ and Functional Programming can simply search on those two and find plenty of blogs, libraries, books and discussions about the subject.
On 2018-03-14, tsu2 <tsu2@no-mx.forums.microfocus.com> wrote:
> Personally, I am not or prefer to write code in the style of Functional
> Programming, but feel that it’s a worthwhile approach that has no
> language bounds including in C++. That’s because Functional Programming
> is a <coding style> that can be practiced in many situations and has no
> requirements that would prevent it from being used by any specific
> coding language
Agreed. But I suspect some languages are better suited to functional programming compared to others.
Given a programming language which is “better suited” to Functional Programming, I’m convinced of only one thing:
The runtime code could be more stable and efficient than an equivalent “non-Functional” implementation if, the Functional Programming paradigm resulted in the programmer writing a logically better execution flow and, the compiler did all the right things.
The converse is also true: the “non-Functional” implementation will win if, the programmer writes an execution flow which is more efficient than that implemented with the “Functional” paradigm.
[HR][/HR]There’s also the issue of the “compiled code size and complexity”: if the compilers of the (more modern) languages “better suited” to Functional Programming are not as mature as the compilers of languages “better suited” to non-Functional Programming then, the runtime image will be at a disadvantage.
Without putting to practice (C++ is one of the languages I don’t code, only read…),
I’d guess that Functional Programming would likely have a substantial C++ benefit if you don’t pay as much attention to environmentals and stuff like garbage collection because there would be more enforcement of re-usable code stored in memory… by eliminating variables, functions will always have the same result which would mean re-usability whereas variables would have varied results which means no re-usability.
As I posted above, there seems to be a pretty large published knowledge base of C++ and Functional Programming to get ideas from.
I personally think that while(true) → break paradigm is horrid.
But it’s true that having cleanup code while using return statements is annoying.
Grub2 for instance uses goto statements a lot.
I’m no C++ expert so I can’t say, but in Java what you describe is mirrored by the recent “try-with-resources” statement.
However (in Java) that only works with objects that implement some “autoclosable” interface.
Since C++ also uses exceptions, maybe it works the same.
Regardless when you talk about GUI input my first thought is:
**why do you not collect the changes in an operation object?
**Maybe that’s a little strange but having a transaction that you can apply or cancel seems to me the “real” solution to the problem.
Then, you automatically gain an undo facility etc. (just save transactions in a list).
You could use standard introspection (again no familiarity with C++ here) to define common operations on objects (ie. change property of type this to that) and even add methods to invoke (like some common ‘apply’ method).
I am sure all of this has already been done before and that there exist common libraries to do this.
But the only thing I am reminded of is Java’s Hamcrest library, but it is only used for UI validation, not execution.