This was suggested in the development of C++, and Stroustrup discusses it in his "Design and Evolution of C++", pages 153 and following. The proposal was well-formed, and drew on prior experience with Ada. It wasn't adopted.
The biggest reason was that nobody wanted to encourage functions with large numbers of parameters. Each additional feature in a language costs something, and there was no desire to add a feature to make it easier to write bad programs.
It also raised questions of what the canonical parameter names were, particularly in the usual header and code file convention. Some organizations had longer and more descriptive parameter names in the .h file, and shorter and easier to type names in the .cpp file (substitute file suffixes as desired). Requiring that these be the same would be an additional cost on compilation, and getting names mixed up between source files could cause subtle bugs.
It can also be handled by using objects rather than function calls. Instead of a GetWindow call with a dozen parameters, create a Window class with a dozen private variables, and add setters as necessary. By chaining the setters, it's possible to write something like my_window.SetColor(green).SetBorder(true).SetBorderSize(3);
. It's also possible to have different functions with different defaults that call the function that actually does the work.
If you're just worried about the documentation effect of contentFetcher.DownloadNote(note, manual : true);
, you can always write something like contentFetcher.DownloadNote(note, /* manual */ true);
, so it's not even very helpful in documentation.
Due to the way that Objective-C objects work, const
gives up being an enforcement and starts being a notation for the programmer. Consider this program:
int f(const int x) {
return ++x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
int x = 3;
NSLog(@"%d", f(x));
}
return 0;
}
That actually won't compile here (I'm using clang): the compiler can detect the attempt to modify the primitive C type and emits an error. But now compare it with this program:
NSMutableString *f2(const NSMutableString * const x) {
[x appendString: @" world!"];
return x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
NSMutableString *x = [@"Hello" mutableCopy];
NSLog(@"%@", f2(x));
}
return 0;
}
Even though the function is passed a constant pointer to a constant object, it's still possible to mutate the object.
In object-oriented programming, the best way to enforce the constant nature of an object is to make that object immutable - i.e. don't provide any methods that can change its state. Imagine that the function above took an NSString
argument instead of NSMutableString
, and that I'd passed the literal @"Hello"
instead of a mutable copy. There is now, reasonably speaking, no chance of mutating the passed-in object[*]. Objective-C doesn't have any way of enforcing that though, unlike const
or final
object references in other OO languages.
For comparison, const
works entirely differently in C++. If I get a const
reference to a C++ object, I'm only allowed to call const
member functions on that object. These functions preserve the const
-ness of the object, either by not making any changes or by only modifying member variables that have explicitly been marked mutable
by the class designer. So imagine that I had some type MutableString
in C++ that's equivalent to NSMutableString
in Objective-C. The equivalent of my example above would look something like:
MutableString& f3(const MutableString& x) {
x.appendString(" world!");
return x;
}
This definitely won't compile: in addition to appendString()
not being a const
operation, the function removes the const
qualifier from the type reference which requires a const_cast
.
[*]I expect there is some contorted way of doing it, but now we're into the realms of one programmer trying to sabotage another by doing "clever" things.
Best Answer
Readability is a valid reason to learn to use whitespace:
Located over there the parameters won't get confused with the body of the function. By locating them on a different line you won't have to reposition them when you change the name of
myFunction
to something more descriptive. Not changing the parameters position when they haven't changed is something source control diff tool users will appreciate.const
means something. Don't throw it out just because you're out of space and ideas. Readability is king but breaking things in it's name is just giving up.