Is there a way to make the compiler copy-paste entire methods for performance? [duplicate] - performance

How do you do "inline functions" in C#? I don't think I understand the concept. Are they like anonymous methods? Like lambda functions?
Note: The answers almost entirely deal with the ability to inline functions, i.e. "a manual or compiler optimization that replaces a function call site with the body of the callee." If you are interested in anonymous (a.k.a. lambda) functions, see #jalf's answer or What is this 'Lambda' everyone keeps speaking of?.

Finally in .NET 4.5, the CLR allows one to hint/suggest1 method inlining using MethodImplOptions.AggressiveInlining value. It is also available in the Mono's trunk (committed today).
// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices;
...
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)
1. Previously "force" was used here. I'll try to clarify the term. As in the comments and the documentation, The method should be inlined if possible. Especially considering Mono (which is open), there are some mono-specific technical limitations considering inlining or more general one (like virtual functions). Overall, yes, this is a hint to compiler, but I guess that is what was asked for.

Inline methods are simply a compiler optimization where the code of a function is rolled into the caller.
There's no mechanism by which to do this in C#, and they're to be used sparingly in languages where they are supported -- if you don't know why they should be used somewhere, they shouldn't be.
Edit: To clarify, there are two major reasons they need to be used sparingly:
It's easy to make massive binaries by using inline in cases where it's not necessary
The compiler tends to know better than you do when something should, from a performance standpoint, be inlined
It's best to leave things alone and let the compiler do its work, then profile and figure out if inline is the best solution for you. Of course, some things just make sense to be inlined (mathematical operators particularly), but letting the compiler handle it is typically the best practice.

Update: Per konrad.kruczynski's answer, the following is true for versions of .NET up to and including 4.0.
You can use the MethodImplAttribute class to prevent a method from being inlined...
[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
// ...
}
...but there is no way to do the opposite and force it to be inlined.

You're mixing up two separate concepts. Function inlining is a compiler optimization which has no impact on the semantics. A function behaves the same whether it's inlined or not.
On the other hand, lambda functions are purely a semantic concept. There is no requirement on how they should be implemented or executed, as long as they follow the behavior set out in the language spec. They can be inlined if the JIT compiler feels like it, or not if it doesn't.
There is no inline keyword in C#, because it's an optimization that can usually be left to the compiler, especially in JIT'ed languages. The JIT compiler has access to runtime statistics which enables it to decide what to inline much more efficiently than you can when writing the code. A function will be inlined if the compiler decides to, and there's nothing you can do about it either way. :)

Cody has it right, but I want to provide an example of what an inline function is.
Let's say you have this code:
private void OutputItem(string x)
{
Console.WriteLine(x);
//maybe encapsulate additional logic to decide
// whether to also write the message to Trace or a log file
}
public IList<string> BuildListAndOutput(IEnumerable<string> x)
{ // let's pretend IEnumerable<T>.ToList() doesn't exist for the moment
IList<string> result = new List<string>();
foreach(string y in x)
{
result.Add(y);
OutputItem(y);
}
return result;
}
The compilerJust-In-Time optimizer could choose to alter the code to avoid repeatedly placing a call to OutputItem() on the stack, so that it would be as if you had written the code like this instead:
public IList<string> BuildListAndOutput(IEnumerable<string> x)
{
IList<string> result = new List<string>();
foreach(string y in x)
{
result.Add(y);
// full OutputItem() implementation is placed here
Console.WriteLine(y);
}
return result;
}
In this case, we would say the OutputItem() function was inlined. Note that it might do this even if the OutputItem() is called from other places as well.
Edited to show a scenario more-likely to be inlined.

Do you mean inline functions in the C++ sense? In which the contents of a normal function are automatically copied inline into the callsite? The end effect being that no function call actually happens when calling a function.
Example:
inline int Add(int left, int right) { return left + right; }
If so then no, there is no C# equivalent to this.
Or Do you mean functions that are declared within another function? If so then yes, C# supports this via anonymous methods or lambda expressions.
Example:
static void Example() {
Func<int,int,int> add = (x,y) => x + y;
var result = add(4,6); // 10
}

Yes Exactly, the only distinction is the fact it returns a value.
Simplification (not using expressions):
List<T>.ForEach Takes an action, it doesn't expect a return result.
So an Action<T> delegate would suffice.. say:
List<T>.ForEach(param => Console.WriteLine(param));
is the same as saying:
List<T>.ForEach(delegate(T param) { Console.WriteLine(param); });
the difference is that the param type and delegate decleration are inferred by usage and the braces aren't required on a simple inline method.
Where as
List<T>.Where Takes a function, expecting a result.
So an Function<T, bool> would be expected:
List<T>.Where(param => param.Value == SomeExpectedComparison);
which is the same as:
List<T>.Where(delegate(T param) { return param.Value == SomeExpectedComparison; });
You can also declare these methods inline and asign them to variables IE:
Action myAction = () => Console.WriteLine("I'm doing something Nifty!");
myAction();
or
Function<object, string> myFunction = theObject => theObject.ToString();
string myString = myFunction(someObject);
I hope this helps.

The statement "its best to leave these things alone and let the compiler do the work.." (Cody Brocious) is complete rubish. I have been programming high performance game code for 20 years, and I have yet to come across a compiler that is 'smart enough' to know which code should be inlined (functions) or not. It would be useful to have a "inline" statement in c#, truth is that the compiler just doesnt have all the information it needs to determine which function should be always inlined or not without the "inline" hint. Sure if the function is small (accessor) then it might be automatically inlined, but what if it is a few lines of code? Nonesense, the compiler has no way of knowing, you cant just leave that up to the compiler for optimized code (beyond algorithims).

There are occasions where I do wish to force code to be in-lined.
For example if I have a complex routine where there are a large number of decisions made within a highly iterative block and those decisions result in similar but slightly differing actions to be carried out. Consider for example, a complex (non DB driven) sort comparer where the sorting algorythm sorts the elements according to a number of different unrelated criteria such as one might do if they were sorting words according to gramatical as well as semantic criteria for a fast language recognition system. I would tend to write helper functions to handle those actions in order to maintain the readability and modularity of the source code.
I know that those helper functions should be in-lined because that is the way that the code would be written if it never had to be understood by a human. I would certainly want to ensure in this case that there were no function calling overhead.

I know this question is about C#. However, you can write inline functions in .NET with F#. see: Use of `inline` in F#

No, there is no such construct in C#, but the .NET JIT compiler could decide to do inline function calls on JIT time. But i actually don't know if it is really doing such optimizations.
(I think it should :-))

In case your assemblies will be ngen-ed, you might want to take a look at TargetedPatchingOptOut. This will help ngen decide whether to inline methods. MSDN reference
It is still only a declarative hint to optimize though, not an imperative command.

Lambda expressions are inline functions! I think, that C# doesn`t have a extra attribute like inline or something like that!

Related

In C++, how can one predict if move or copy semantics would be invoked?

Given the latitude that a C++ compiler has in instantiating temporary objects, and in invoking mechanisms like return value optimization etc., it is not always clear by looking at some code if move or copy semantics will be invoked (or how many).
It almost feels as if these primitives exist for incidental optimizations. That is, you may or may not get them. It seems like it's difficult to design any kind of resource management strategy that leverages moves, when it is hard to control the invocation of moves themselves.
Is there a way to predict clearly (and simply) where and how many copies and moves might occur in some code? Ideally, one would not need to be an expert in compiler internals to be able to do this.
It seems like it's difficult to design any kind of resource management strategy that leverages moves, when it is hard to control the invocation of moves themselves.
I would contradict here. Leveraging move semantics when designing a resource handling class should be done independently of how or when copy- or move-construction occurs in the client code. Once move-ctor/assignment is there, client code can be designed to leverage the existence of these special member functions.
Is there a way to predict clearly (and simply) where and how many copies and moves might occur in some code?
A bit hard to tell what simply means here, but this is how I understand it:
Given that a class has no move ctor/assignment operator, you will always get a copy. This is trivial, but important to keep in mind when working with e.g. classes in a legacy code that have user defined destructors and/or copy-ctor/assignment, because the compiler doesn't generate move ctors/assignment in this case.
Return value optimization. The question is tagged C++11, so you don't have guaranteed copy elision for initialization with prvalues brought by C++17. However, it is fair to assume that identical mechanism are already implemented by your compiler. Hence,
struct A {};
A func() { return A{}; }
can be assumed to construct the instance of A to which the function return value is bound on the calling side in place. This causes neither move nor copy construction. The same behavior can optimistically be assumed if the returned object has a name, as long as func() has no branching that renders NRVO impossible.
As an exception from this guideline, function return values that are also function parameters do not qualify for return value optimization. Hence, move/forward them to prevent copy in case A is move-constructible:
A func(A& a) { return std::move(a); }
The object created by the return value of func(A&) will hence be move-constructed.
Function parameters do not reveal per se how they behave, it depends on the type and its special member functions. Given
void f1(A a1) { A a2{std::move(a1)}; };
void f2(A& a1) { /* Same as above. */ };
void f1(A&& a1) { /* Again, same. */ };
the instances a2 are move-constructed if A has a move ctor, otherwise, it's copy.
There is a lot to discover beyond the exemplary cases above, I am neither capable of going into more detail, nor would this fit into the desired simplicity of an answer. Also, the scenario is different when you don't know the types you are dealing with, e.g. in function or class templates. In this case, a good read on how to deal with the related uncertainty of whether copies or moves are made is Item 29 in Eff. Modern C++ ("Assume that move operations are not present, not cheap, and not used").

Cleaning Functions containing if statements

I hope that this is the right place to ask (if not please tell me). I am currently trying to create a game while following Robert C. Martins book "Clean Code" in an effort to improve the readability of my code. I am not totally happy with how many of my functions work however, as more often than not I will need to check various variables before I execute a command. For example:
private void checkScoreAndIncreaseDifficulty() {
if(eater.getScore()%400==0){
world.increaseDifficulty();
}
According to the book I am following functions should only do one thing, but when an "if" statement is involved the functions purpose (to me) seems to naturally increase. The name of the above function is checkScoreAndIncreaseDifficulty which is quite clearly two things but I cannot think of how to reduce it. I feel the solution is very simple but it just is not coming to me. Any advice would be appreciated.
Names of functions are supposed to describe what the function does,not how achieves something. So naming checkScoreAndIncreaseDifficulty is wrong imo. It should be something similar to IncreaseDifficulty. Moreover if you do not feel that names of your code elements do not give enough insight on what the function / class/ variable does, you can always comment your code. :)
Also, the "correct" place to write your conditional statement depends entirely on your application : if difficulty will increase only if the user satisfies some condition, then that condition should be included in the function that increases difficulty. If the difficulty might be increased by other means, then the function should only execute actions that increase difficulty and leave the decision whether to increase difficulty or not to the caller.
I don't see any way to make this method cleaner than it is. It checks the score, and then hands of the increaseDifficulty to another method. What more can you ask?
I think there's also a risk in trying to make methods as minimal as they can possibly be. At some point, you need to dig through a dozen methods and functions spread through your entire codebase in order to understand what a single method or function does. That's no good either.
As far as I'm concerned, your code hits the sweet spot. The cumbersome name is indeed an issue, but not a serious one, and easy enough to fix, if you really want to.
Why don't you use two separate functions(you can do it also with only first function) like this:
private bool isScoreEnough() {
if(eater.getScore()%400==0)
return true;
}
private void increaseDifficulty(){
world.increaseDifficulty();
}
and in your program:
if(isScoreEnough())
increaseDifficulty();
You are setting difficulty level in the function. Depending on score you increase/decrease the difficulty level. That is perfectly fine - as long as the function does the job of determining and setting difficulty level only. Function name has scope for improvement:
private void setDifficultyLevel() {
if (eater.getScore()%400 == 0) {
world.increaseDifficulty();
}
}
Obviously you won't find much code without any if statement, programs have to make decisions based on state, input or whatever. Avoiding if statements at all is also not the key message of "Clean Code". What you should avoid are for example endless if-else constructs if one class does the work of three logical cases - you should have three classes then.
Your method is already pretty short, but if you want to apply one of Martin's principles (a good name spares comments etc.) even further you could use something like:
if (scoreRequiresIncreaseInDifficulty()) {
increaseDifficulaty();
}
and then implement the two methods. However, I don't think this makes much sense in your case unless you will need the same calls multiple times and want to maintain the flexibility to change when the score requires a more difficult game in a single place.
You want to increase difficulty every 400 score points gathered by the eater, right?
So, you would need the eater to allow subscribing for score changes:
interface Eater {
void addScoreChangedListener(ScoreChangedListener listener);
}
interface ScoreChangedListener {
public void onScoreChanged(Score previousScore, Score newScore);
}
The implementation of Eater would hold a list of all score change listeners and invoke the onScoreChanged on each of them when the score changes. See the Observer pattern.
And then when bootstrapping your game:
Eater eater = ....
eater.addScorechangedListener(new DifficultyAdjustScoreChangeListener());
And you are done!
The implementation of DifficultyAdjustScoreChangeListener need to have the if, though, but that's ok:
class DifficultyAdjustScoreChangeListener implements ScoreChangedListener {
public void onScoreChanged(Score previousScore, Score newScore) {
if (newScore.value() % 400 == 0) {
world.increaseDifficulty();
}
}
}

Using a for loop as a condition in an if statement

Is there a way to use a for loop as a condition? Something like this?
if((for(int x = 0; x < 5; x++){if(x == 2){return true;}return false;}) == true)
Edit:
Another example
if(for(int x = 0; x < 5; x++) == 2)
I just wanted to know if it could be done. I expect that Blagovest Buyukliev and marzapower answers are accurate, based on my question. Thank you SO for you helpful responses.
That wouldn't make much sense, as C-ish loops are just execution control structures. There's no type that you can say loops in general have.
From your examples, what it looks to me like you are asking for is the ability to add simple inline functions without having to actually go somewhere else and write down a full function with its own name and whatnot. These are called lambdas.
If you are using C, I'd suggest just making small functions (perhaps even macros - ick) that build and return the type you want.
If you are using C++ there is some stuff in the standard libary in <algorithm> and <functional> you might be interested in. For your given example, I think find_if() would do what you are looking for. Generally that stuff is more of a PITA to use than it is worth though. You have to create a full-blown predicate object to do it, which is way more code and work than just creating your one-line function would have been in the first place.
Boost adds lambda support to C++, and the next standard is supposed to add it properly to the language.
Most functional languages support lambdas, but they generally don't use C syntax like this.
It will probably depend on the language you are writing your code. Generally the for loops do not return a value, unless you include them within an anonymous function also commonly known as lambda function.
In ruby you could accomplish something like that this way:
res = lambda {|array| for i in array do return true if i == 2 end }.call(0..4)
but in Java you will never be able to do such a thing easily without defining a new method.
Update
Generally speaking procedural methods (like ruby, perl, python, lisp, etc.) will provide you with built-in methods for handling anonymous functions, while other languages like C, C++, Java, etc. do not have these characteristics.
By the way, it should be clear that a for loop is a construct in all the languages and not a function, so it should never return a value (like an integer or a boolean or whatever else) but only handle the flow of the code through the processor. Anonymous functions provide us with the ability of incapsulating simple control codes in an inline function.
No, since they are both statements. You need an expression into the if condition. Furthermore, the return statement returns the function in which it has been used.
Why would you do that anyway?
In most languages, no.
for is a statement, not an operator. Unlike operators, statements do not yield a result and cannot be nested into expressions. The condition of the if statement expects an expression that can be evaluated to a boolean value, not a statement.
In languages like Perl and Python you may want to look at the map operator.
This is not good style. Split it up. If you are trying for one-liners Java is the wrong language my friend.

Why isn't DRY considered a good thing for type declarations?

It seems like people who would never dare cut and paste code have no problem specifying the type of something over and over and over. Why isn't it emphasized as a good practice that type information should be declared once and only once so as to cause as little ripple effect as possible throughout the source code if the type of something is modified? For example, using pseudocode that borrows from C# and D:
MyClass<MyGenericArg> foo = new MyClass<MyGenericArg>(ctorArg);
void fun(MyClass<MyGenericArg> arg) {
gun(arg);
}
void gun(MyClass<MyGenericArg> arg) {
// do stuff.
}
Vs.
var foo = new MyClass<MyGenericArg>(ctorArg);
void fun(T)(T arg) {
gun(arg);
}
void gun(T)(T arg) {
// do stuff.
}
It seems like the second one is a lot less brittle if you change the name of MyClass, or change the type of MyGenericArg, or otherwise decide to change the type of foo.
I don't think you're going to find a lot of disagreement with your argument that the latter example is "better" for the programmer. A lot of language design features are there because they're better for the compiler implementer!
See Scala for one reification of your idea.
Other languages (such as the ML family) take type inference much further, and create a whole style of programming where the type is enormously important, much more so than in the C-like languages. (See The Little MLer for a gentle introduction.)
It isn't considered a bad thing at all. In fact, C# maintainers are already moving a bit towards reducing the tiring boilerplate with the var keyword, where
MyContainer<MyType> cont = new MyContainer<MyType>();
is exactly equivalent to
var cont = new MyContainer<MyType>();
Although you will see many people who will argue against var usage, which kind of shows that many people is not familiar with strong typed languages with type inference; type inference is mistaken for dynamic/soft typing.
Repetition may lead to more readable code, and sometimes may be required in the general case. I've always seen the focus of DRY being more about duplicating logic than repeating literal text. Technically, you can eliminate 'var' and 'void' from your bottom code as well. Not to mention you indicate scope with indentation, why repeat yourself with braces?
Repetition can also have practical benefits: parsing by a program is easier by keeping the 'void', for example.
(However, I still strongly agree with you on prefering "var name = new Type()" over "Type name = new Type()".)
It's a bad thing. This very topic was mentioned in Google's Go language Techtalk.
Albert Einstein said, "Everything should be made as simple as possible, but not one bit simpler."
Your complaint makes no sense in the case of a dynamically typed language, so you must intend this to refer to statically typed languages. In that case, your replacement example implicitly uses Generics (aka Template Classes), which means that any time that fun or gun is used, a new definition based upon the type of the argument. That could result in dozens of extra methods, regardless of the intent of the programmer. In particular, you're throwing away the benefit of compiler-checked type-safety for a runtime error.
If your goal was to simply pass through the argument without checking its type, then the correct type would be Object not T.
Type declarations are intended to make the programmer's life simpler, by catching errors at compile-time, instead of failing at runtime. If you have an overly complex type definition, then you probably don't understand your data. In your example, I would have suggested adding fun and gun to MyClass, instead of defining them separately. If fun and gun don't apply to all possible template types, then they should be defined in an explicit subclass, not as separate functions that take a templated class argument.
Generics exist as a way to wrap behavior around more specific objects. List, Queue, Stack, these are fine reasons for Generics, but at the end of the day, the only thing you should be doing with a bare Generic is creating an instance of it, and calling methods on it. If you really feel the need to do more than that with a Generic, then you probably need to embed your Generic class as an instance object in a wrapper class, one that defines the behaviors you need. You do this for the same reason that you embed primitives into a class: because by themselves, numbers and strings do not convey semantic information about their contents.
Example:
What semantic information does List convey? Just that you're working with multiple triples of integers. On the other hand, List, where a color has 3 integers (red, blue, green) with bounded values (0-255) conveys the intent that you're working with multiple Colors, but provides no hint as to whether the List is ordered, allows duplicates, or any other information about the Colors. Finally a Palette can add those semantics for you: a Palette has a name, contains multiple Colors, but no duplicates, and order isn't important.
This has gotten a bit far afield from the original question, but what it means to me is that DRY (Don't Repeat Yourself) means specifying information once, but that specification should be as precise as is necessary.

Are booleans as method arguments unacceptable? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
A colleague of mine states that booleans as method arguments are not acceptable. They shall be replaced by enumerations. At first I did not see any benefit, but he gave me an example.
What's easier to understand?
file.writeData( data, true );
Or
enum WriteMode {
Append,
Overwrite
};
file.writeData( data, Append );
Now I got it! ;-)
This is definitely an example where an enumeration as second parameter makes the code much more readable.
So, what's your opinion on this topic?
Boolean's represent "yes/no" choices. If you want to represent a "yes/no", then use a boolean, it should be self-explanatory.
But if it's a choice between two options, neither of which is clearly yes or no, then an enum can sometimes be more readable.
Enums also allow for future modifications, where you now want a third choice (or more).
Use the one that best models your problem. In the example you give, the enum is a better choice. However, there would be other times when a boolean is better. Which makes more sense to you:
lock.setIsLocked(True);
or
enum LockState { Locked, Unlocked };
lock.setLockState(Locked);
In this case, I might choose the boolean option since I think it's quite clear and unambiguous, and I'm pretty sure my lock is not going to have more than two states. Still, the second choice is valid, but unnecessarily complicated, IMHO.
To me, neither using boolean nor enumeration is a good approach. Robert C. Martin captures this very clearly in his Clean Code Tip #12: Eliminate Boolean Arguments:
Boolean arguments loudly declare that the function does more than one thing. They are confusing and should be eliminated.
If a method does more than one thing, you should rather write two different methods, for example in your case: file.append(data) and file.overwrite(data).
Using an enumeration doesn't make things clearer. It doesn't change anything, it's still a flag argument.
Remember the question Adlai Stevenson posed to ambassador Zorin at the U.N. during the cuban missile crisis?
"You are in the courtroom of world
opinion right now, and you can answer
yes or no. You have denied that [the missiles]
exist, and I want to know whether I
have understood you correctly.... I am
prepared to wait for my answer until
hell freezes over, if that's your
decision."
If the flag you have in your method is of such a nature that you can pin it down to a binary decision, and that decision will never turn into a three-way or n-way decision, go for boolean. Indications: your flag is called isXXX.
Don't make it boolean in case of something that is a mode switch. There is always one more mode than you thought of when writing the method in the first place.
The one-more-mode dilemma has e.g. haunted Unix, where the possible permission modes a file or directory can have today result in weird double meanings of modes depending on file type, ownership etc.
There are two reasons I've run into this being a bad thing:
Because some people will write methods like:
ProcessBatch(true, false, false, true, false, false, true);
This is obviously bad because it's too easy to mix up parameters, and you have no idea by looking at it what you're specifying. Just one bool isn't too bad though.
Because controlling program flow by a simple yes/no branch might mean you have two entirely different functions that are wrapped up into one in an awkard way. For instance:
public void Write(bool toOptical);
Really, this should be two methods
public void WriteOptical();
public void WriteMagnetic();
because the code in these might be entirely different; they might have to do all sorts of different error handling and validation, or maybe even have to format the outgoing data differently. You can't tell that just by using Write() or even Write(Enum.Optical) (though of course you could have either of those methods just call internal methods WriteOptical/Mag if you want).
I guess it just depends. I wouldn't make too big of a deal about it except for #1.
I think you almost answered this yourself, I think the end aim is to make the code more readable, and in this case the enum did that, IMO its always best to look at the end aim rather than blanket rules, maybe think of it more as a guideline i.e. enums are often more readable in code than generic bools, ints etc but there will always be exceptions to the rule.
Enums are better but I wouldn't call boolean params as "unacceptable". Sometimes it's just easier to throw one little boolean in and move on (think private methods etc.)
Booleans may be OK in languages that have named parameters, like Python and Objective-C, since the name can explain what the parameter does:
file.writeData(data, overwrite=true)
or:
[file writeData:data overwrite:YES]
Enums have a definite benefit, but you should't just go replacing all your booleans with enums. There are many places where true/false is actually the best way to represent what is going on.
However, using them as method arguments is a bit suspect, simply because you can't see without digging into things what they are supposed to do, as they let you see what the true/false actually means
[Edit for the current state in 2022]
In modern C#, or other languages that support this, the nicest way to do it is with named arguments:
var worker = new BackgroundWorker(workerReportsProgress: true);
If your language doesn't allow for named arguments, then you may find properties to be a reasonable solution as well
[Original Answer from 2008 left for posterity]
Properties (especially with C#3 object initializers) or keyword arguments (a la ruby or python) are a much better way to go where you'd otherwise use a boolean argument.
C# example:
var worker = new BackgroundWorker { WorkerReportsProgress = true };
Ruby example
validates_presence_of :name, :allow_nil => true
Python example
connect_to_database( persistent=true )
The only thing I can think of where a boolean method argument is the right thing to do is in java, where you don't have either properties or keyword arguments. This is one of the reasons I hate java :-(
I would not agree that it is a good rule. Obviously, Enum makes for a better explicit or verbose code at some instances, but as a rule it seems way over reaching.
First let me take your example:
The programmers responsibility (and ability) to write good code is not really jeopardized by having a Boolean parameter. In your example the programmer could have written just as verbose code by writing:
dim append as boolean = true
file.writeData( data, append );
or I prefer more general
dim shouldAppend as boolean = true
file.writeData( data, shouldAppend );
Second:
The Enum example you gave is only "better" because you are passing a CONST. Most likely in most application at least some if not most of the time parameters that are passed to functions are VARIABLES. in which case my second example (giving variables with good names) is much better and Enum would have given you little benefits.
While it is true that in many cases enums are more readable and more extensible than booleans, an absolute rule that "booleans are not acceptable" is daft. It is inflexible and counter-productive - it does not leave room for human judgement. They're a fundamental built in type in most languages because they're useful - consider applying it to other built-in-types: saying for instance "never use an int as a parameter" would just be crazy.
This rule is just a question of style, not of potential for bugs or runtime performance. A better rule would be "prefer enums to booleans for reasons of readability".
Look at the .Net framework. Booleans are used as parameters on quite a few methods. The .Net API is not perfect, but I don't think that the use of boolean as parameters is a big problem. The tooltip always gives you the name of the parameter, and you can build this kind of guidance too - fill in your XML comments on the method parameters, they will come up in the tooltip.
I should also add that there is a case when you should clearly refactor booleans to an enumeration - when you have two or more booleans on your class, or in your method params, and not all states are valid (e.g. it's not valid to have them both set true).
For instance, if your class has properties like
public bool IsFoo
public bool IsBar
And it's an error to have both of them true at the same time, what you've actually got is three valid states, better expressed as something like:
enum FooBarType { IsFoo, IsBar, IsNeither };
Some rules that your colleague might be better adhering to are:
Don't be dogmatic with your design.
Choose what fits most appropriately for the users of your code.
Don't try to bash star-shaped pegs into every hole just because you like the shape this month!
A Boolean would only be acceptable if you do not intend to extend the functionality of the framework. The Enum is preferred because you can extend the enum and not break previous implementations of the function call.
The other advantage of the Enum is that is easier to read.
If the method asks a question such as:
KeepWritingData (DataAvailable());
where
bool DataAvailable()
{
return true; //data is ALWAYS available!
}
void KeepWritingData (bool keepGoing)
{
if (keepGoing)
{
...
}
}
boolean method arguments seem to make absolutely perfect sense.
It depends on the method. If the method does something that is very obviously a true/false thing then it is fine, e.g. below [though not I am not saying this is the best design for this method, it's just an example of where the usage is obvious].
CommentService.SetApprovalStatus(commentId, false);
However in most cases, such as the example you mention, it is better to use an enumeration. There are many examples in the .NET Framework itself where this convention is not followed, but that is because they introduced this design guideline fairly late on in the cycle.
It does make things a bit more explicit, but does start to massively extend the complexity of your interfaces - in a sheer boolean choice such as appending/overwriting it seems like overkill. If you need to add a further option (which I can't think of in this case), you can always perform a refactor (depending on the language)
Enums can certainly make the code more readable. There are still a few things to watch out for (in .net at least)
Because the underlying storage of an enum is an int, the default value will be zero, so you should make sure that 0 is a sensible default. (E.g. structs have all fields set to zero when created, so there's no way to specify a default other than 0. If you don't have a 0 value, you can't even test the enum without casting to int, which would be bad style.)
If your enum's are private to your code (never exposed publicly) then you can stop reading here.
If your enums are published in any way to external code and/or are saved outside of the program, consider numbering them explicitly. The compiler automatically numbers them from 0, but if you rearrange your enums without giving them values you can end up with defects.
I can legally write
WriteMode illegalButWorks = (WriteMode)1000000;
file.Write( data, illegalButWorks );
To combat this, any code that consumes an enum that you can't be certain of (e.g. public API) needs to check if the enum is valid. You do this via
if (!Enum.IsDefined(typeof(WriteMode), userValue))
throw new ArgumentException("userValue");
The only caveat of Enum.IsDefined is that it uses reflection and is slower. It also suffers a versioning issue. If you need to check the enum value often, you would be better off the following:
public static bool CheckWriteModeEnumValue(WriteMode writeMode)
{
switch( writeMode )
{
case WriteMode.Append:
case WriteMode.OverWrite:
break;
default:
Debug.Assert(false, "The WriteMode '" + writeMode + "' is not valid.");
return false;
}
return true;
}
The versioning issue is that old code may only know how to handle the 2 enums you have. If you add a third value, Enum.IsDefined will be true, but the old code can't necessarily handle it. Whoops.
There's even more fun you can do with [Flags] enums, and the validation code for that is slightly different.
I'll also note that for portability, you should use call ToString() on the enum, and use Enum.Parse() when reading them back in. Both ToString() and Enum.Parse() can handle [Flags] enum's as well, so there's no reason not to use them. Mind you, it's yet another pitfall, because now you can't even change the name of the enum without possibly breaking code.
So, sometimes you need to weigh all of the above in when you ask yourself Can I get away with just an bool?
IMHO it seems like an enum would be the obvious choice for any situation where more than two options are possible. But there definitely ARE situations where a boolean is all you need. In that case I would say that using an enum where a bool would work would be an example of using 7 words when 4 will do.
Booleans make sense when you have an obvious toggle which can only be one of two things (i.e. the state of a light bulb, on or off). Other than that, it's good to write it in such a way that it's obvious what you're passing - e.g. disk writes - unbuffered, line-buffered, or synchronous - should be passed as such. Even if you don't want to allow synchronous writes now (and so you're limited to two options), it's worth considering making them more verbose for the purposes of knowing what they do at first glance.
That said, you can also use False and True (boolean 0 and 1) and then if you need more values later, expand the function out to support user-defined values (say, 2 and 3), and your old 0/1 values will port over nicely, so your code ought not to break.
Sometimes it's just simpler to model different behaviour with overloads. To continue from your example would be:
file.appendData( data );
file.overwriteData( data );
This approach degrades if you have multiple parameters, each allowing a fixed set of options. For example, a method that opens a file might have several permutations of file mode (open/create), file access (read/write), sharing mode (none/read/write). The total number of configurations is equal to the Cartesian products of the individual options. Naturally in such cases multiple overloads are not appropriate.
Enums can, in some cases make code more readable, although validating the exact enum value in some languages (C# for example) can be difficult.
Often a boolean parameter is appended to the list of parameters as a new overload. One example in .NET is:
Enum.Parse(str);
Enum.Parse(str, true); // ignore case
The latter overload became available in a later version of the .NET framework than the first.
If you know that there will only ever be two choices, a boolean might be fine. Enums are extensible in a way that won't break old code, although old libraries might not support new enum values so versioning cannot be completely disregarded.
EDIT
In newer versions of C# it's possible to use named arguments which, IMO, can make calling code clearer in the same way that enums can. Using the same example as above:
Enum.Parse(str, ignoreCase: true);
Where I do agree that Enums are good way to go, in methods where you have 2 options (and just two options you can have readability without enum.)
e.g.
public void writeData(Stream data, boolean is_overwrite)
Love the Enums, but boolean is useful too.
This is a late entry on an old post, and it's so far down the page that nobody will ever read it, but since nobody has said it already....
An inline comment goes a long way to solving the unexpected bool problem. The original example is particularly heinous: imagine trying to name the variable in the function declearation! It'd be something like
void writeData( DataObject data, bool use_append_mode );
But, for the sake of example, let's say that's the declaration. Then, for an otherwise unexplained boolean argument, I put the variable name in an inline comment. Compare
file.writeData( data, true );
with
file.writeData( data, true /* use_append_mode */);
It really depends on the exact nature of the argument. If it is not a yes/no or true/false then a enum makes it more readable. But with an enum you need to check the argument or have acceptable default behaviour since undefined values of the underlying type can be passed.
The use of enums instead of booleans in your example does help make the method call more readable. However, this is a substitute for my favorite wish item in C#, named arguments in method calls. This syntax:
var v = CallMethod(pData = data, pFileMode = WriteMode, pIsDirty = true);
would be perfectly readable, and you could then do what a programmer should do, which is choose the most appropriate type for each parameter in the method without regard to how it looks in the IDE.
C# 3.0 allows named arguments in constructors. I don't know why they can't do this with methods as well.
Booleans values true/false only. So it is not clear what it represent. Enum can have meaningful name, e.g OVERWRITE, APPEND, etc. So enums are better.

Resources