See SyntacticallyTransparentRefactorings.
(This thought arose in a newsgroup conversation with AndreiAlexandrescu.)
Languages like CeePlusPlus and JavaLanguage distinguish syntactically between member functions and free functions.
E.g.
class Number { private: int data; public: Number addMember(const Number& that) const { Number ret; ret.data = this->data + that.data; return ret; } friend Number addFree( const Number& left, const Number& right ); } Number addFree( const Number& left, const Number& right ) { Number ret; ret.data = left.data + right.data; return ret; }These two functions are pretty much equivalent, except for syntax:
Number N1, N2, N3; N1 = N2.addMember(N3); N1 = addFree(N2,N3);There are some C++ language specific issues involving conversions.
Most importantly, however, the member function has access to all private data of the class, whereas the free function may be implemented using private data (via friend) or by using public accessors. The free function may be DENIED access to private data.
(ExtremeProgrammers may not be so sure about the usefulness of PrivateData? - it impedes refactoring - but if you buy into private, not having privae is bad.)
If you wish to preserve syntax across refactorings that make things public and private, you should start off with FreeFunctions?. But that's almost as painful as using setters/getters everywhere.
MemberFunctions? can be denied access to implementation details by using the pimpl, PrivateImplementation?, pattern.
Moral: languages should not distinguish members and free functions syntactically. FreeFunctions? can be defined as members (or friends.)
This is an implementation issued for the ObserverPatternInCeePlusPlus.