0%

Some thoughts on programming languages

I wrote my first line of C++ code about fifteen years ago. Yeah, the first programming language I learned was C++. I learned C++ from a book on data structure and algorithms, which was also a university textbook, but now I don’t think it’s a good book, lol. And I also bought a book written by the father of C++, The C++ Programming Language, but I couldn’t understand the book. The book was too difficult for me, especially later chapters on how to design classes. But then I wrote a OGRE’s 3D editor in C++ and MFC. Of course, I referenced other people’s code. I also mainly use C++ in competitive programming.

The second language I learned was Java. In my first job, I did some work on a game server, so I had to learn Java. Java heavily relies on object-oriented thinking to solve all problems, which leads to complex designs, even though in a tiny project. People always write code for the sake of following design patterns. For example, many write the following code

1
2
3
4
5
6
7
class Student { ... }

class StudentManager {
static StudentManager Instance;
void AddStudent(Student stu) { ... }
void DelStudent(Student stu) { ... }
}

Is it a good design? I don’t think so. To be precise, I don’t think it’s a good habit to write managers for any class without thinking about it. The next language I learned was Node Javascript, which I used to build a website. I don’t want to talk much about it. In fact, I think it’s shit. Fortunately, I’ve forgotten both languages.

The fourth language I’ve learned is Python. Python is a good language and has helped me a lot! It makes you be able to program some useful tools quickly.

The last languge I learned was C#. Although I mostly use it in Unity, but I think C# is the best language. First of all, you don’t need to care about memory management, and C# is a pure object-oriented programming language, but it only supports single inheritance, which results in at leats 50% less bad things related to design patterns in C#. Secondly, Visual Studio provides a powerful programming environment. This’s extremely important! Without a powerful IDE, you can’t easily complete a big project. That’s why I don’t like Node Javscript and all similar languages like typescript. By the way, typescript is the first language in Cocos Studio. Yeah, Cocos studio is also a famous game engine, but I think that the biggest factor limiting its development is that it chose typescript as its first language!

In contrast, C++ is not purely object-oriented, which always leads to some bad design! For example, I used to write code like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Params { 
public:
int foo;
int bar;
}

class B {
public:
virtual void GetParams(Params &a) = 0;
void Solve() {
Params a;
GetParams(a);
// do some things about foo and bar
if(a.foo == 0 && a.bar == 0) {
// Success!
}
}
}

class C1 : public B {
void GetParams(Params &a) {
a.foo = ...
a.bar = ...
}
}

class C2 : pulic B {
void GetParams(Params &a) {
a.foo = ...
a.bar = ...
}
}

But when I wrote that code again in C#, I found a better design!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Params {
public:
virtual bool check() = 0;
}

class B {
public:
virtual Params* GetParams() = 0;
void Solve() {
Params *a = GetInitParams();
// do some things about A
if(a->check()) {
// Success!
}
delete a;
}
}

class MyParams : public Params {
public:
int foo, bar;
bool check() {
if(bar)
return true;
return false;
}
}

class C1 : public B {
public:
Params* GetInitParams() {
MyParams *params = new MyParams();
return params;
}
}

class C2 : public B {
Params* GetInitParams() {
MyParams *params = new MyParams();
return params;
}
}

So Why did I get a good design in C#? And Why did I get a bad design in C++?

C++ is based on C, and thus everything is treated as data, even though sometimes it should be treated as an object. For example,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A {
public:
int foo;
}
A a = {1};
A b = {2};
a = b; // now, a.foo is 2!

It works well!

class Student {
public:
string name;
int age;
}
Student a = {'Mike', 10};
Student b = {'Daniel', 25};
a = b; // now, a.age is 25!

Now, the variable A should be treated as an object, becasue we already treated it as an concrete student in our mind! So does A=B make sense? In other words, assigning B to A causes the data of A to be changed is silly! A=B should be taken to mean that A now represents another concrete student, not the data in B! Otherwise, the problem below will occur!

1
2
3
4
5
6
7
8
9
10
11
12
13
class State {
virtual void OnUpdate() = 0;
}

class StateIdle : public State {
void OnUpdate() { ... }
}

class StateRun : public State {
void OnUpdate() { ... }
}
StateIdle b;
State a = b; // Compiler error!

Now, the variable b is an object of StateIdle. From the code above, assigning B to A should cause the data of A to be changed. But now we get an compiler error, because the variable a is not a data class, but an abstract object! As a result, the use of “class” creates a huge amount of confusion. Sometimes it’s a set of data and we can a=b as we like, but sometimes it’s an abstract object and we can’t a=b.

To repeat, the root cause of bad design is that C++ treats everything as data, even though, essentially, a class should be treated as an abstract object! If a variable is used as an abstract object, it can only hold a reference to a set of data, not simply a set of data. As a result, all classes must be used as follows

1
2
3
4
5
6
7
Student *a = new Student();
Student *b = new Student();
a = b;

StateIdle *s1 = new StateIdle();
StateRun *s2 = new StateRun();
State *s = s1;

But unfortunately, C++ allows programmer to use classes as a set of data, and the keyword class is just an alias for the keyword struct.

As a result, C++ is not my favourite language, and I even consider C++ to be rubbish in a way! So, C is my favorite language. C forces you to think about problems without being object-oriented, which is also the nature of computer, everything is data. Yeah, STL is a good stuff, so I like C with STL! In an object-oriented programming language, everything should be treated as a reference. So, the object-oriented in C++ is not really object-oriented!