Should functions always return something? I often write very basic functions which are used as shorthand to do things that happen a lot such as:
function formsAway() {
$("#login_form, #booking_form").slideUp();
}
Should this function exist - is there a better way, or is this fine?
They don't have to return anything. If you leave it blank it simply returns 'undefined' which in this case is fine because you never intend to use the return value. The Javascript syntax is pretty simplistic and as far as I know there just isn't any real distinction between functions that do and functions that don't return a value (other than the 'return' keyword)
All JavaScript functions return something. If an explicit return is omitted, undefined is returned automatically instead. When a function returns, its instance is wiped out from memory, which also frees all the variables in its scope to be wiped out if nothing else points to them. Without a forced return memory management would have to be done manually.
To my knowledge, unless you need it to return something, a function doesn't have to return anything.
It may be different in other languages, but I've never heard it being necessary or good practice in JavaScript.
Should functions always return
something?
I believe that totally depends on the usage of the function.
is there a better way, or is this
fine?
IMO writing these kind of functions is good when there are many occurrences of the reusable code which can be replaced by the function so that the code looks much cleaner. But only for a couple of occurrences you may just put the code as it is instead of replacing it with function. You should also take into account the chances of reuse of this function in other places in future.
Related
I'm just curious about why return ends the function.
Why do we not write
function Foo (){
BAR = calculate();
give back BAR;
//do sth later
log(BAR);
end;
}
Why do we need to do this?
function Foo (){
BAR = calculate();
log(BAR);
return BAR;
}
Is this to prevent multiple usage of a give back/return value in a function?
The idea of a function stems from mathematics, e.g. x = f(y). Once you have computed f(y) for a specific value of y, you can simply substitute that value in that equation for the same result, e.g. x = 42. So the notion of a function having one result or one return value is quite strong. Further, such mathematical functions are pure, meaning they have no side effects. In the above formula it doesn’t make a difference whether you write f(y) or its computed result 42, the function doesn’t do anything else and hence won’t change the result. Being able to make these assumptions makes it much easier to reason about formulas and programs.
return in programming also has practical implementation implications, as most languages typically pop the stack upon returning, based on the assumption/restriction that it’s not needed any further.
Many languages do allow a function to “spit out” a value yet continue, which is usually implemented as generators and the yield keyword. However, the generator won’t typically simply continue running in the background, it needs to be explicitly invoked again to yield its next value. A transfer of control is necessary; either the generator runs, or its caller does, they can’t both run simultaneously.
If you did want to run two pieces of code simultaneously, be that a generator or a function’s “after return block”, you need to decide on a mode of multitasking like threading, or cooperative multitasking (async execution) or something else, which brings with it all the fun difficulties of managing shared resource access and the like. While it’s not unthinkable to write a language which would handle that implicitly and elegantly, elegant implicit multitasking which manages all these difficulties automagically simply does not fit into most C-like languages. Which is likely one of many reasons leading to a simple stack-popping, function-terminating return statement.
Using return gives you a lot of flexibility regarding where, when and how you return the value of a function as well as an easy to read statement of 'I am now returning this value'.
If following your idea, you could have a situation where the function got evaulated to some value and you have to figure out if that assignment got changed somewhere later in the flow.
Let's say that I have a function that should only execute if some constant is defined. which of the following would be better
Option 1: wrap all the function calls in an if block:
if(defined('FOO_BAR_ENABLED')) {
foobar();
}
I figure this way the intent is more clear, but it requires checking the constant every time the function is called.
Option 2: check the constant in the function itself:
function foobar() {
if(!defined('FOO_BAR_ENABLED')) {
return;
}
//do stuff
}
This way requires less lines of code, and the constant is sure to get checked. However, I find it confusing to see calls to this function when it's not actually doing anything. Thoughts?
May I suggest renaming the function to FoobarIfEnabled(), then doing the check in the function?
Stealing liberally from a great language-agnostic answer to one of my own questions, when programming we have the following concerns:
Make it correct.
Make it clear.
Make it concise.
Make it fast. ... in that order.
If you do the check outside the function, you might end up missing it in one place. And if you want to change the behavior, you'll have to find all the places it gets called and fix it. That's a maintenance nightmare which violates principle 1. By adding "IfEnabled" or something like that to the name, now it is not just correct but also is clear. How can you beat that?
Performance is not to be worried about unless the final speed is unsatisfactory and you have identified this as the bottleneck (unlikely).
I recommend you follow the link above and read as it was a very useful answer that gave me much to think about.
Option 3:
void maybe_foobar() {
if(defined('FOO_BAR_ENABLED')) really_foobar();
}
void really_foobar() {
// do stuff
}
On a good day I'd think of better names than "maybe" and "really", but it depends what the function does and why it's turn-off-and-onable.
If there is no circumstance under which anyone could validly "do stuff" when FOO_BAR_ENABLED isn't defined, then I'd go with your option 2 (and perhaps call the function do_stuff_if_possible rather than foobar, if the name foobar was causing confusion as to whether calling it entails actually doing anything). If it's always valid to "do stuff", but some users just so happen do so conditionally, then I'd go with my option 3.
Option 1 is going to result in you copy-and-pasting code around, which is almost always a Bad Sign.
[Edit: here's Option 4, which I suspect is over-engineering, but you never know:
void if_enabled(string str, function f) {
if (defined(str + '_ENABLED')) f();
}
Then you call it with:
if_enabled('FOO_BAR', foobar);
Obviously there's some issues there to do with how your language handles functions, and whether there's any way to pass arbitrary parameters and a return value through if_enabled.]
Does the condition of the if fall within the function's responsibility? Is there a use case for calling the function without the if?
If the condition always needs to be checked, I'd put it in the function. Follow the DRY principle here: Don't Repeat Yourself. Another quip that might be helpful is the SRP - the Single Responsibility Principle - do one thing, and do it well.
In the header file, if foobar always takes the same number of arguments,
#ifdef ENABLE_FOOBAR
#define maybe_foobar(x) foobar(x)
#else
#define maybe_foobar(x)
#endif
Not sure how to do that in C++ or older C dialects if foobar can take a variable number of arguments.
(Just noticed language-agnostic tag. Well, the above technique is what I'd suggest in languages where it works; maybe use an inline function for languages which have those but lack macros).
Option 2, less code and it ensures the constant is defined, as you suggested.
Since this is apparently only used with the foobar() function, then option 2 should be your choice. That means the test is located in only one place and your code is more readable.
Let's say I have a method, Foo(). There are only certain times when Foo() is appropriate, as determined by the method ShouldFooNow(). However, there are many times when the program must consider if Foo() is appropriate at this time. So instead of writing:
if ShouldFooNow():
Foo()
everywhere, I just make that into one function:
def __name():
if ShouldFooNow():
Foo()
What would be a good name for this method? I'm having a hard time coming up with a good convention. IfNecessaryFoo() is awkward, particularly if Foo() has a longer name. DoFooIfShould()? Even more awkward.
What would be a better name style?
I think you're pretty close. Put the action/intent at the head of the method name, for easier alphabetic searching. If I were writing something like that, I'd consider
FooIfNecessary()
FooIfRequired()
Say, for instance,
ElevatePermissionsIfNecessary()
You could use EnsureFoo().
For example, the method EnsurePermissions() will take the appropriate action if needed. If the permissions are already correct, the method won't do anything.
I've recently started using the convention:
FooIf(args, bool);
Where args are any arguments that the method takes and bool is either expecting a boolean value or a Func of some kind that resolves to a boolean. Then, within that method, I check the bool and run the logic. Keeps such assertions down to one line and looks clean to me.
Example in my C# code for logging:
public void WarnIf<T>(T value, string message, Func<T, bool> isTrue)
{
if (isTrue(value)) _log.Warn(message);
}
Then I would call it with something like:
WarnIf(someObject, "This is a warning message to be logged.", s => s.SomeCondition == true);
(That caller may not be correct, but you get the idea... I don't have the code in front of me right now.)
Michael Petrotta's answer (IfNecessary or IfRequired suffix) is good, but I prefer a shorter alternative: IfNeeded.
ElevatePermissionsIfNeeded()
And if you want something even shorter I would consider a prefix like May or Might:
MayElevatePermissions()
MightElevatePermissions()
I don't see what's wrong with the original code:
if shouldFoo():
Foo();
is perfectly clear IMHO.
Not just that, but it clearly separates concerns of deciding about doing the action, vs the action itself.
Another option for a similar question with a slightly different approach to avoiding the postfix:
https://softwareengineering.stackexchange.com/a/161754/262009
One of the stylistic 'conventions' I find slightly irritating in published code, is the use of:
if(condition) {
instead of (my preference):
if (condition) {
A slight difference, and probably an unimportant one, but it occurred to me that the first style might be justified if 'if' statements were implemented as a kind of function call. Then I could stop objecting to it.
Does anyone know of a programming language where an if statement is implemented as a function call, where the argument is a single boolean expression?
EDIT: I realise the blocks following the if() are problematic, and the way I expressed my question was probably too naive, but I'm encouraged by the answers so far.
tcl is one language which implements if as a regular in built function/command which takes two parameters ; condition and the code block to execute
if {$vbl == 1} { puts "vbl is one" }
http://tmml.sourceforge.net/doc/tcl/if.html
In fact, all language constructs in tcl (for loop , while loop etc.) are implemented as commands/functions.
It's impossible for it to have a single argument since it has to decide which code path to follow, which would have to be done outside of said function. It would need at least two arguments, but three would allow an "else" condition.
Lisp's if has exactly the same syntax as any other macro in the language (it's not quite exactly a function, but the difference is minimal): (if cond then else)
Both the 'then' and 'else' clauses are left unevaluated unless the condition selects them.
In Smalltalk, an if statement is kind of a function call -- sort of, in (of course) a completely object oriented way, so it's really a method not a free function. I'm not sure how it would affect your thinking on syntax though, since the syntax is completely different, looking like:
someBoolean
ifTrue: [ do_something ]
ifFalse: [ do_something_else ]
Given that this doesn't contain any parentheses at all, you can probably interpret it as proving whatever you wanted to believe. :-)
If the if function is to be a regular function, then it can't just take the condition, it needs as its parameters the block of code to run depending on whether the condition evaluates to true or not.
A prototype for a function like that in C++ might be something along the lines of
void custom_if(bool cond, void (*block)());
This function can either call the block function, or not, depending on cond.
In some functional languages things are much easier. In Haskell, a simple function like:
if' True a _ = a
if' _ _ b = b
allows you to write code like this:
if' (1 == 1)
(putStrLn "Here")
(putStrLn "There")
which will always print Here.
I don't know of any languages where if(condition) is implemented as a regular function call, but Perl implements try { } catch { } etc.. {} as function calls.
I'm rewriting a series of PHP functions to a container class. Many of these functions do a bit of processing, but in the end, just echo content to STDOUT.
My question is: should I have a return value within these functions? Is there a "best practice" as far as this is concerned?
In systems that report errors primarily through exceptions, don't return a return value if there isn't a natural one.
In systems that use return values to indicate errors, it's useful to have all functions return the error code. That way, a user can simply assume that every single function returns an error code and develop a pattern to check them that they follow everywhere. Even if the function can never fail right now, return a success code. That way if a future change makes it possible to have an error, users will already be checking errors instead of implicitly silently ignoring them (and getting really confused why the system is behaving oddly).
Can the processing fail? If so, should the caller know about that? If either of these is no, then I don't see value in a return. However, if the processing can fail, and that can make a difference to the caller, then I'd suggest returning a status or error code.
Do not return a value if there is no value to return. If you have some value you need to convey to the caller, then return it but that doesn't sound like the case in this instance.
I will often "return: true;" in these cases, as it provides a way to check that the function worked. Not sure about best practice though.
Note that in C/C++, the output functions (including printf()) return the number of bytes written, or -1 if this fails. It may be worth investigating this further to see why it's been done like this. I confess that
I'm not sure that writing to stdout could practically fail (unless you actively close your STDOUT stream)
I've never seen anyone collect this value, let alone do anything with it.
Note that this is distinct from writing to file streams - I'm not counting stream redirection in the shell.
To do the "correct" thing, if the point of the method is only to print the data, then it shouldn't return anything.
In practice, I often find that having such functions return the text that they've just printed can often be useful (sometimes you also want to send an error message via email or feed it to some other function).
In the end, the choice is yours. I'd say it depends on how much of a "purist" you are about such things.
You should just:
return;
In my opinion the SRP (single responsibility principle) is applicable for methods/functions as well, and not only for objects. One method should do one thing, if it outputs data it shouldn't do any data processing - if it doesn't do processing it shouldn't return data.
There is no need to return anything, or indeed to have a return statement. It's effectively a void function, and it's comprehensible enough that these have no return value. Putting in a 'return;' solely to have a return statement is noise for the sake of pedantry.