Stuff I don't like with object oriented programming...

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Stuff I don't like with object oriented programming...
by on (#116118)
Object Oriented programming is great when it comes to dealing with relatively complex datasets and structure as it makes it easy to keep organized and write clean code with less lines.

HOWEVER, there is several things that are really f*** up and in all OO languages I've learn (C++, Java and Javascript so far), and I'm surprised nobody fixed this.

1) Constructors.

In at least 90% of the cases it will look like this :
Code:
constructor(string name, int age, string address, boolean male)
{
  this.name = name;
  this.age = age;
  this.address = address;
  this.male = male;
}

Honestly I feel so dumb every time I have to write something like this. Why can't this be done automatically ?
Like if you could do :
Code:
Person = new person(name = 'John', age = '99', address = 'somewhere', male = 'true');

and it would automatically call the constructor with correct parameters. In addition, you could change the order and it won't screw things up.


2) calling methods related to an object is poorly worded

It's common to do things like this :
Code:
  String str = "Hello guys what's up ?";
  [...]
  str = str.substring(3, 4);


Why didn't anyone invent a .= operator so you could just write
Code:
  str .= substring(3, 4);

This would look way cleaner. In this case it's allright because "str" is a short name, but if you do this with a complex name with already several "." in them (which is a common thing to do), it'll really make things more readable, as in :

Code:
   group.person.get(i).name .= substring(3, 4);


3) Getters and setters

Those are not compulsory thanks god but apparently for some obscure reason they have been included in "good practice" by computer science teachers, so you'll encounter them as soon as you'll have to deal with someone else's code. What's the point, honneslty ? Why write :
Code:
  person.get(name)

When you could instead do :
Code:
   person.name


Personally I'd say it's not good practice...

4) Function can only return one thing

It's not restricted to OO but to high level languages in general. For some reason computer scientists used to decide that two kinds of subroutines exists, "procedures" which doesn't return anything, and "function" which returns a value.

What if I want to return multiple things ? Well the answer is : "You should make an object with those two values and return it". In other words "go to hell, declare a new class and a new constructor just for this, at least 10-15 lines of code, when it could be done in 1 if the language was better made".

So sorry for complaining here but I have to share my anger with someone.
Re: Stuff I don't like with object oriented programming...
by on (#116120)
Getters/setters exist for the sake of encapsulation. Doing it the way you suggest would mean that all encapsulated data items in a class are public and thus accessible to *anyone* at *any* time. What if you wanted to change the way "name" is accessed such that when it's set you also store a CRC of it? Easy to do if you have a setName() method, because that will be the only way "name" could be set by anyone that is using your class. If you've got users of your class all over the place and they all access "name" directly that's a pain in the ass to update.

With regard to the suggested .= operator...I have no idea what you think is better about that? Clearly str = str.substring() means "string str is assigned the substring of itself". What does str .= substr() mean? "string str has the method substr called on itself and the result assigned to itself?" Seems to me the first method is way more clear. It is not equivalent to any of the other shortcut operators...those are mathematical shortcuts [num *= 5].

Again with constructors it may be the case that 90% of them benignly assign data values directly from what they're passed. But you're ignoring the fact that constructors can also do more complicated things with the information they're passed. Assuming that all constructors do the former and thus could somehow be simplified by having the compiler do it automatically would just lead to programmers confusion. If you *write* the constructor for the object you *know* the object is constructed the way you intended. If you rely on the compiler to do it for you you're likely to want to blame the compiler for "doing it wrong".

I guess I see your function returns argument as the only valid point. But then again you can return whatever the hell you want from any function by simply passing values by reference in the parameter list. 8-)
Re: Stuff I don't like with object oriented programming...
by on (#116121)
Seems to me you are learning OO languages without having a solid background of OO concepts. That is like learning a whole bunch of words of French, German, Spanish, etc., but not learning anything about how sentences are formed in those languages. I'd suggest reading a good OO methodology book and not so much focusing on the semantics of any given language.
Re: Stuff I don't like with object oriented programming...
by on (#116122)
1) I kind of agree, but:
Quote:
Like if you could do :
Code:
Person = new person(name = 'John', age = '99', address = 'somewhere', male = 'true');

This would be really annoying because you would have to
a) Know variable names to create an object
b) Write more text every time you create oan bject
c) Change all constructor calls if you change variable name or usage in the class
I would prefer simple object constructor calls over long constructor code.

2) It seems that your problem isn't the language, but the class interface.
You can always create your own class inherited from the string that has function
Code:
 str.substring_store_self(3, 4)


3) Getters and setters prevent the direct modification of object variables. Sometimes you don't just want to set variable value, but also do something else in the constructor.
For example you can have multiple overloaded setters for the same property that take different types or different anmount of parameters.

4) In some languages it's very easy to return multiple values. For example in python you return values in a tuple:
Code:
def foo(): return (1, 'bar', 0.0434)
i, s, f = foo()


If such feature is not available you can always use pointers or references. I don't think it really makes a difference
Code:
float foo(int *i, const char **s)
{
  *i = 1;
  *s = "bar";
  return 0.0434;
}

int main()
{
  int i;
  const char *s;
  float f = foo(&i, &s);
  return 0;
}
Re: Stuff I don't like with object oriented programming...
by on (#116123)
C# made it look like this:

var person = new Person() { name = "Fred", age = -1 };
Re: Stuff I don't like with object oriented programming...
by on (#116124)
Quote:
Like if you could do :
Code:
Person = new person(name = 'John', age = '99', address = 'somewhere', male = 'true');

and it would automatically call the constructor with correct parameters. In addition, you could change the order and it won't screw things up.


Some languages have automatic initialization of object members. For example, in Scala you could do this:

Code:
class Person(var name: String, age: Int, address: String, male: Boolean) {
    def present() = println(name + " is " + age + " years old and lives at " + address)
}

val donald = new Person("Donald Duck", 79, "1113 Quack Street, Duckburg", true)
donald.present()


Go also has this kind of functionality, and I believe Dart does as well (and probably some other languages).

Quote:
4) Function can only return one thing

The Go language lets you specify multiple return values, each with their own type. For example, you could do this:

Code:
type Person struct {
    FirstName string
    LastName string
    Age int
}

   
func (person *Person) GetInfo() (fullName string, age int) {
    fullName = strings.Join([]string{person.FirstName, person.LastName}, " ")
    age = person.Age
    return
}


func main() {
    donald := &Person{"Donald", "Duck", 79}
    name, age := donald.GetInfo()
    fmt.Printf("%s is %d years old\n", name, age)
   
    age += 1
    name, _ = donald.GetInfo()  // Ignore the 2nd return value
    fmt.Printf("%s is now %d years old!\n", name, age)
}

In many other languages you can return multiple values using a tuple/struct/list.
Re: Stuff I don't like with object oriented programming...
by on (#116128)
Constructors and setters allow the class to ensure that the values passed to them are sane and throw an exception if not. Getters allow the class to change from a value being stored in a field to it being computed or retrieved from some other service.

In statically typed languages such as C++, the operator you call .= would work only for "factory" methods, meaning a method of a class that returns a new object of the same class. Apart from operations on immutable strings, those don't occur often enough to warrant a syntactic sugar.

Python allows named arguments to constructors and other methods as well as returning a tuple (small dynamically typed array) of values.
Re: Stuff I don't like with object oriented programming...
by on (#116132)
1. I think writing the trivial constructor in one place is better than having to write a=1, b=2, c=3 etc. for every single instance of the object. I'm more concerned with the thing I have to write many times (instances) than the thing I have to write only once (constructor).

Consider these forms of initialization:
Bob x = Bob(1,2,3);
vs.
Bob x = Bob(a=1,b=2,c=3);
vs.
Bob x;
x.a=1;
x.b=2;
x.c=3;


There are some languages where a class is basically implemented as a dictionary of members (JavaScript, Python, etc.) where the kind of initialization you mention might be a common way to do things.

By the way, there are some interesting alternatives to named parameters available in C++: http://www.parashift.com/c++-faq/named-parameter-idiom.html

Generally, if I want to initialize a class several different ways, I'm happy to write a constructor for each of those methods so that my code can be explicit about what gets a default value, etc. If you want an all-named-parameter init that means everything should have a default value (or be safe to leave uninitialized). Sometimes when I have multple constructors, I will create a protected/private Init member function that does the actual construction work, so that the various constructors can just call Init with various default parameters, and various things passed as arguments.

3. You can make writing getters and setters slightly trivial in C++ by writing a few macros for it, like you could make at READ_WRITE(int,x) that declares the variable and creates consistently named inline get and set functions for it.

Other languages have built in shorthand for getters and setters, like C#.

4. In C++ there a couple of easy ways to return multiple values:
Code:
std::tuple<int,char,char> myfunc()
{
   return std::tuple<int,char,char>(1,2,3);
}

or
Code:
struct T { int a; char b; char c; };
T myfunc2()
{
   T r = {1,2,3};
   return r;
}


Alternatively T could be defined as: class T { public: int a; char b; char c; };. The only difference between a class and a struct is that structs default to public.

Some other languages have slightly more succinct built in features for it (e.g. Python tuples).
Re: Stuff I don't like with object oriented programming...
by on (#116133)
rainwarrior wrote:
4. In C++ there a couple of easy ways to return multiple values:
Code:
std::tuple<int,char,char> myfunc()
{
   return std::tuple<int,char,char>(1,2,3);
}

Ah, C++11 (aka C++0x), that's why I hadn't heard about std::tuple it until now, I've wanted it for ages.
Re: Stuff I don't like with object oriented programming...
by on (#116134)
Oh, sorry I didn't realize that was C++11. It's been available in MSVC since 2008 (without C++11 extensions enabled) so I thought it was just C++. The standard C++ library does have the pair template at least, which can be used for two return values. Otherwise you need the structure declaration, I suppose.

The other thing I forgot to mention is that C99 actually had a designated initializer paradigm for structures:
Code:
struct D { int a; int b; int c; };
struct D d { .a=1, .b=2, .c=3 };


Unfortunately this is one of those C99 features that Microsoft never cared to implement, so I've never been able to use it professionally.
Re: Stuff I don't like with object oriented programming...
by on (#116135)
ε-δ wrote:
1) I kind of agree, but:
Quote:
Like if you could do :
Code:
Person = new person(name = 'John', age = '99', address = 'somewhere', male = 'true');

This would be really annoying because you would have to
a) Know variable names to create an object
b) Write more text every time you create oan bject
c) Change all constructor calls if you change variable name or usage in the class
I would prefer simple object constructor calls over long constructor code.


Going to agree that this is annoying and wordy, but *also* going to point out that this is basically how Objective-C works:
Code:

// Here is my function:

-(void)doAFunction:(int)intParam1 intParameterTwo:(int)insideFunctionName theName:(NSString*)shootMeNow
{
  NSLog(@"Here are two numbers: %d %d",intParam1,insideFunctionName);
  NSLog(@"Such long wordy names like that aren't really uncommon in Obective-C world, %@.",shootMeNow);
}

// Here is how I'd use it
[self doAFunction:0 intParameterTwo:25 theName:@"Denzel"];
// This is also okay
[self doAFunction:13 theName:@"Marley" intParameterTwo:37 ];

// The output for both:
Here are two numbers, 0 25
Such long wordy names like that aren't really uncommon in Objective-C world, Denzel.

Here are two numbers, 13 37
Such long wordy names like that aren't really uncommon in Objective-C world, Marley.

the advantage is that you can do them in any order, but still... I'm much more of a fan of compact, neat code with sufficient comments than huge, verbose code with little to no comments.
Sorry, this has been on my mind - I've been doing a lot of Objective C at work. While we watch Xcode produce huge complicated binaries from this convoluted stuff and a simple game grows in tens of megabytes from big resources, I like to bring up the daily reminder that Super Mario Bros is less than 64KB...
Re: Stuff I don't like with object oriented programming...
by on (#116139)
OO is about explicit contracts between user and provider. Encapsulation is part of this, preventing the user from relying on implementation details. This allows the provider to change how it goes about providing, without breaking any user code. Constructors and accessors are both part of this, narrowing what the user can do to only what fits with the abstract model, rather than all the additional things that can be done with a particular implementation. If you've got lots of users, breaking their code is a significant problem. If they have full access to all your variables and internal functions, all bets are off when you change the implementation. But if your language enforces your decisions about what they are allowed to access, it's much easier. Developing a good sense of what needs to be accessible to others takes time. It will also always be inconvenient to some users in the short-term over having full access. If in a particular case the benefits this provides are greater than the costs, it naturally shouldn't be used.
Re: Stuff I don't like with object oriented programming...
by on (#116140)
About encapsulation, I perfectly get your point. This is great if you're writing a library.

HOWEVER if you're just writing something for yourself, no library, and nobody else is supposed to use your code without having full access to it (in which case he's in his right to modify it as his liking), then I see no point of having such strict encapsulation, other than "because it's good practice".

I hardly ever use private variables/functions or getters/setters, because, well, screw it, I don't think it's useful for what I'm doing. I see where they come from, but well it's not worth the trouble if you're not writing a library.

As for return multiple values I know there is many workarounds, and I use them. The most obvious is use of an object which contains fields that are your multiple return values, the other alternative is to modify the value of global variables as a return. Both have their pros and cons, and depending on the context I'll use one or the others.

Using global variables is no a very good practice, especially if it's just for this. It should normally be reserved for variables that represent the overall state of the program, stuff like that (so many CS teachers just says global variables are "evil" and shouldn't be ever used, but I'd say that it's because they really understood them...).

Using a custom class for "pair" or "tuplet" is somewhat elegant, BUT it's still much more writing :
Code:
function()
{
  [...]
  return new pair<something, something> (c, d);
}
(a, b) = function();

as opposed to
Code:
function()
{
  [...]
  return c, d;
}
Pair<something, something> = function();
a = pair.getFirst();
b = pair.getSecond();


And it's good to know Python supports multiple returns, I've never learnt python but it sounds like this language at least does something right I'd have liked to see in more languages :)


As for constructors :
Quote:
This would be really annoying because you would have to
a) Know variable names to create an object
b) Write more text every time you create oan bject
c) Change all constructor calls if you change variable name or usage in the class
I would prefer simple object constructor calls over long constructor code.

It is very annoying to have to know the order of often 5+ parameters anyways.
With "my" way of doing it, it's more writing in the main program, and you have to know the names of the variables instead of the order. In both cases it's necessary to refer to the constructor.

Also, every-time I write a constructor I feel like a mentally handicapped dumbass.

Finally something I'd say, is that it's also annoying how hard it is to get an exact deep copy of an object, without any reference copy, so that any changes to the new object doesn't affect the original one. Usually you have to do this by hand, because the language doesn't support it.
Re: Stuff I don't like with object oriented programming...
by on (#116141)
As a programmer, I find myself spending a lot more time thinking than coding. For this reason, I've never really thought little syntax details like this were very important. I would say that assembly is the most verbose by far, followed by Java, and then maybe C++ with OOP. Python or C can be relatively terse.

Of the verbose languages, only assembly actually bothers me. It's not really the verbosity of assembly, though, it's the lack of tools to ensure code correctness. It's a lot of typing, yes, but the problem is that it's error prone. The only thing that's checked at assembly time is correct syntax, and that's beyond trivial to fix. Logical errors, type errors, etc. are much harder to diagnose in assembly than any other language.

The only times in my professional or recreational coding experience that I thought typing was a significant bottleneck was in these two situations:

1. Refactoring code. Here there is no thinking about the algorithm or anything like that to be done, I'm literally just processing text. Understanding regex can help a lot in these situations, but there's always stuff that can't be automated very well.

2. Copying/boilerplating stuff in a rush to meet a deadline. I generally consider it the wrong way to structure my code when I'm copy-pasting a lot, but there are situations due to poor existing structure, etc. where it's going to be the quickest way to get something done in the short term.

Other than these two cases, language verbosity has never been much of an issue to me. Maybe if I was a much slower typist...? I dunno.
Re: Stuff I don't like with object oriented programming...
by on (#116142)
The problem is not the typing speed, but rather that I want my code to be clear so I understand what I was doing when I come back into it 1 year (or more) later.

In this regard, assembly is terrible, even if you are very generous with comments.
Re: Stuff I don't like with object oriented programming...
by on (#116143)
Bregalad wrote:
If you're just writing something for yourself, no library, and nobody else is supposed to use your code without having full access to it (in which case he's in his right to modify it as his liking), then I see no point of having such strict encapsulation, other than "because it's good practice".


If you don't use it, are you complaining about somebody else's private code?

Bregalad wrote:
And it's good to know Python supports multiple returns, I've never learnt python but it sounds like this language at least does something right I'd have liked to see in more languages :)


The reason Python has such a simplified syntax for multiple returns is because it has no type safety. So, the difference looks like:

Code:
def myfunc:
    return (1,2)

(a, b) = myfunc();


Code:
struct MyfuncT { int a; char b; };
struct MyfuncT myfunc()
{
    MyfuncT r = {1,2};
    return r;
}

struct MyfuncT m = myfunc();


Code:
pair<int,char> myfunc()
{
    return pair<int,char>(1,2);
}

pair<int,char> p = myfunc();


So, unless you're counting braces as extra lines, the C++ version is the same number of lines as the python version, really. (The C version has two extra lines.) The extra verbosity is really just about specifying types explicitly for every variable. If you prefer not to have to specify types, it comes with the huge caveat that type errors are now a runtime error, and not a compile time error. This is one of the big reasons I do not like to use Python for some types of projects.

Bregalad wrote:
Finally something I'd say, is that it's also annoying how hard it is to get an exact deep copy of an object, without any reference copy, so that any changes to the new object doesn't affect the original one. Usually you have to do this by hand, because the language doesn't support it.


I'm not aware of any language where a true deep copy is a simple problem. Garbage collected languages make it a little easier. The complexity and relative unsafety of C++ makes it a little harder (though plenty of people use "smart pointer" implementations in C++ to make it easier).
Re: Stuff I don't like with object oriented programming...
by on (#116144)
rainwarrior wrote:
Other than these two cases, language verbosity has never been much of an issue to me. Maybe if I was a much slower typist...? I dunno.

The verbosity can also be combated with a good editor. That said, personally I'm a little bit disappointed in the current state of code editors, I think none of them (that I've tried) are as good as they potentially could be.
Re: Stuff I don't like with object oriented programming...
by on (#116150)
Also I think with C++11 you have some type inference ability, so you could do this at the end of the C++ example instead:
Code:
auto p = myfunc();


Whether or not you want to defeat the explicit type safety with an auto inference is a judgement call, though. Sometimes you want to make sure if that return type changes that you will change the code that uses it as well.
Re: Stuff I don't like with object oriented programming...
by on (#116151)
rainwarrior wrote:
The reason Python has such a simplified syntax for multiple returns is because it has no type safety.

This looks like type safety to me:
Code:
>>> print(1 + '2')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

There's a difference between "strong" and "weak" typing on the one hand and "static" and "dynamic" typing on the other. What you're seeing is that Python has a top type (object), and all other types are subtypes of object, and all variables have type object. Java likewise has a quasi-top type (java.lang.Object), used internally by the implementations of Java collections, but primitive numerics need to be "boxed" into objects first. This boxing happens automatically since JDK 1.5 but incurs some runtime overhead.

Quote:
I'm not aware of any language where a true deep copy is a simple problem.

Any language that supports serializing (or pickling or marshalling) an object allows deep-copying the object even from one process to another.
Re: Stuff I don't like with object oriented programming...
by on (#116156)
I was referring to its lack of compile-time type safety, which I think I clarified below that statement. Yes, it will fail if your types are incorrect at runtime, at least it's polite enough to do that!

Every time I've used serialization/pickling/etc. there's been a whole lot of rules to follow for all the objects you need to serialize. If you follow all the rules (or for simple cases where you're not breaking any rules anyway), yes it's much easier to implement in Python (e.g. more or less built-in) than C++ (usually requires some overhead code in every single class). If you don't follow all the rules and then want to implement it later, unravelling it can be a pain. More of a pain in C++.
Re: Stuff I don't like with object oriented programming...
by on (#116158)
Did you consider Haskell? In Haskell you can easily return a tuple (and you can easily ignore one so you can pattern match on (x, _), for example), and values can be copied and passed around whatever you want. Field names can be used as functions which read the corresponding field, although you can also make classes which allow many types to share sets of operations and mathematical laws (such as being a number, a functor, a monad, a monoid, etc). There are a lot of other things you can do with it too.

Having macros would also help with many of the things you mention, and with other things, too. Haskell does have Template Haskell, although they aren't quite real macros.

Note that I have wanted the .= operator that you have described, too, in things such as JavaScript.
Re: Stuff I don't like with object oriented programming...
by on (#116162)
rainwarrior wrote:
I was referring to its lack of compile-time type safety, which I think I clarified below that statement. Yes, it will fail if your types are incorrect at runtime, at least it's polite enough to do that!

Perhaps what I was getting at is that PHP doesn't even do that; it's overly eager to convert things to numbers or to strings in ways that have led to security problems. JavaScript in a function that doesn't "use strict" is just as bad.
Re: Stuff I don't like with object oriented programming...
by on (#116163)
Quote:
So, unless you're counting braces as extra lines, the C++ version is the same number of lines as the python version, really. (The C version has two extra lines.) The extra verbosity is really just about specifying types explicitly for every variable. If you prefer not to have to specify types, it comes with the huge caveat that type errors are now a runtime error, and not a compile time error. This is one of the big reasons I do not like to use Python for some types of projects.

I don't count braces as extra lines, however, you forgot that I don't want the results of my function to be in an unusable Pair variable, but I want in it two variables. Which means two extra lines of code to extract individual values from the Pair (and that both in C and C++).
Re: Stuff I don't like with object oriented programming...
by on (#116180)
In that case, the advantage of Python and PHP is that unlike C++, they have a sugar for assigning multiple variables out of a compound.
Code:
// C++11
#include <utility>  // for std::pair
#include <cstdio>   // for std::printf
std::pair<int,char> myfunc() {
    return std::pair<int,char>(1,2);
}
int main(void) {
    auto p = myfunc();
    int a = p.first;
    char b = p.second;
    std::printf("a is %d and b is %d\n", a, b);
    return 0;
}

# Python 2.7
def myfunc():
    return (1, 2)

a, b = myfunc()
print "a is %d and b is %d" % (a, b)

// PHP 5.3
<?php
function myfunc() {
    return array(1, 2);
}
list($a, $b) = myfunc();
echo "a is $a and b is $b\n";
Re: Stuff I don't like with object oriented programming...
by on (#116185)
Again on tuples...
Instead of:
Code:
std::tuple<int,char,char> myfunc()
{
   return std::tuple<int,char,char>(1,2,3);
}


you can write for a bit less of verbosity:
Code:
std::tuple<int,char,char> myfunc()
{
   return std::make_tuple(1,2,3);
}

Don't worry about temporaries, as everything is moved when it is possible.

(Unfortunately, the "{ }" syntax appears not to work, which would be alot nicer)
Re: Stuff I don't like with object oriented programming...
by on (#116189)
But what types does std::make_tuple use? How does it know to make char instead of int? Or is one implicit conversion happening?
Re: Stuff I don't like with object oriented programming...
by on (#116193)
Oh, also I forgot the very common C/C++ paradigms of passing by reference/pointer for multiple "return" values. This I think is used in practice much more than the struct/pair/tuple methods. I've seen it in a zillion places, and used it lots. Dunno why it slipped my mind early. Example off the top of my head: MSVC's fopen_s function. Microsoft even added an "out" keyword for this when they designed C#.

Code:
int myfunc(char& b_out)
{
    b_out = 2;
    return 1;
}


Code:
int myfunc(char* b_out)
{
    if (b_out != NULL) *b_out = 2; // can test for NULL for an "optional" return value
    return 1;
}


There are valid reasons to choose & vs * for some particular cases, though they are often interchangeable techniques.
Re: Stuff I don't like with object oriented programming...
by on (#116194)
Keeping true to my KISS principle roots -- re: subject line:

Almost of it.

That is all from me on the subject.
Re: Stuff I don't like with object oriented programming...
by on (#116198)
koitsu wrote:
Keeping true to my KISS principle roots -- re: subject line:

Almost of it.

That is all from me on the subject.


I do think people tend to overdo it. Clean interfaces and implementation hiding does not require classes, and not everything needs to be in its own tiny nested namespace when there's zero risk of ambiguity and name collisions in practice. Even hardcore C++ fans (if those exist :P) often seem to prefer C-style libraries.

I usually don't bother with classes unless I need to create multiple instances. A function pointer can be as clean or cleaner than a class hierarchy for simple generic code too, as long as you document where it's set.
Re: Stuff I don't like with object oriented programming...
by on (#116199)
tepples wrote:
But what types does std::make_tuple use? How does it know to make char instead of int? Or is one implicit conversion happening?
Yes, a tuple can be converted into another one if the types of the rhs can be converted to the types of the lhs.

On the topic of OO, I find too many people using getter/setter for every attributes in classes; also, I prefer:
Code:
...
      double radius() const;
      void radius(double r);
...
much more than
Code:
...
      double getRadius() const;
      void setRadius(double r);
...

which is more typing and more verbose for nothing. Because of my preference in the naming of getters/setters, as a convention I put trailing underscores in attribute names, so they don't clash with method names.
Re: Stuff I don't like with object oriented programming...
by on (#116200)
While I'm feeling ranty, I think people tend to overdo accessors too, at least for purely internal code. :P

Sometimes the risk of something not staying a direct member variable with a predictable type is so miniscule that fuglying up the code with a ton of get_x() or whatever everywhere just isn't worth it. For languages that can translate .x into an accessor call it's kinda moot though...
Re: Stuff I don't like with object oriented programming...
by on (#116202)
Bregalad wrote:
About encapsulation, I perfectly get your point. This is great if you're writing a library.

HOWEVER if you're just writing something for yourself, no library, and nobody else is supposed to use your code without having full access to it (in which case he's in his right to modify it as his liking), then I see no point of having such strict encapsulation, other than "because it's good practice".


Encapsulation to me is just a fancy way of saying abstraction. You usually don't want every part of your system knowing about and relying on the precise internals of all the other parts, since it quickly gets overwhelming and makes changing internals or swapping out parts messy. Instead you partition your program into logical components that communicate via abstract interfaces. That just seems like a good idea in general though, and not really specific to OOP. There's many ways those interfaces could be defined.

In a way C++ classes sometimes expose more internals than other approaches would (though they're declared private), since every compilation unit that uses the class needs the full definition (unless it's just for a pointer or reference or the like). :P
Re: Stuff I don't like with object oriented programming...
by on (#116204)
Jarhmander wrote:
tepples wrote:
But what types does std::make_tuple use? How does it know to make char instead of int? Or is one implicit conversion happening?
Yes, a tuple can be converted into another one if the types of the rhs can be converted to the types of the lhs.

On the topic of OO, I find too many people using getter/setter for every attributes in classes; also, I prefer:
Code:
...
      double radius() const;
      void radius(double r);
...
much more than
Code:
...
      double getRadius() const;
      void setRadius(double r);
...

which is more typing and more verbose for nothing. Because of my preference in the naming of getters/setters, as a convention I put trailing underscores in attribute names, so they don't clash with method names.

Qt uses something inbetween: radius() for getting and setRadius() for setting. I tend to prefer this style because it reads better than (e.g.) foo.radius( 5 ). I also think int bar = foo.radius() * 10; reads better than int bar = foo.getRadius() * 10;

I think there's a small problem with languages that allow hiding the getters and setters (like C#), it's the fact that user no longer knows whether he's accessing a variable (fast) or invoking a method (potentially slow). Of course in a perfect world the possible slowness would be documented, and of course other languages like C++ suffer from the same problem if getter and setter methods are used everywhere and documentation is lacking.
Re: Stuff I don't like with object oriented programming...
by on (#116207)
thefox wrote:
I think there's a small problem with languages that allow hiding the getters and setters (like C#), it's the fact that user no longer knows whether he's accessing a variable (fast) or invoking a method (potentially slow).

Some people coming from C aren't big fans of C++'s operator overloading sugar for the same reason. They're used to operators being fairly fast (except possibly integer division and float arithmetic on embedded CPUs). See C++ FQA Lite's page about abuse of operator overloading. Anyway, a standard nomenclature for public getters and setters allows IDEs to do some reasoning about an object's properties. Java, for example, has long had the "bean" concept.

Quote:
Of course in a perfect world the possible slowness would be documented

I feel a Huey Lewis and the News song coming on. In the real world, even C#'s counterpart to memory leaks isn't conspicuously documented.
Re: Stuff I don't like with object oriented programming...
by on (#116215)
Quote:
HOWEVER if you're just writing something for yourself, no library, and nobody else is supposed to use your code without having full access to it (in which case he's in his right to modify it as his liking), then I see no point of having such strict encapsulation, other than "because it's good practice".

Agreed that doing something only "because it's correct" is a poor practice. Everything has costs and benefits and when the costs outweigh them, it's not worth using. Plenty of people use OO as a rule rather than a tool among others.

Even if you are your own user, though, hiding things is useful. When I write things I want to depend as little as possible on other things of mine I'm using, because later I may want to improve them without breaking my other stuff. Rather than merely documenting what I can depend on, OO languages allow expression in code and enforcement by the compiler.
Re: Stuff I don't like with object oriented programming...
by on (#116242)
thefox wrote:
I think there's a small problem with languages that allow hiding the getters and setters (like C#), it's the fact that user no longer knows whether he's accessing a variable (fast) or invoking a method (potentially slow). Of course in a perfect world the possible slowness would be documented, and of course other languages like C++ suffer from the same problem if getter and setter methods are used everywhere and documentation is lacking.


I think I've seen this kind of hiding in MFC. Accessing CFileDialog::m_pOFN "data member" causes a function call. I haven't traced it yet but I imagine it is some kind of #define trickery. Whatever it is, I certainly :roll: when I discovered it.