Live data from Hacker News

Object-oriented design patterns in C and kernel development

oshub.org

81–90 of 224 posts

Re: Object-oriented design patterns in C and kernel development

#81
post #68

Earlier quoted context omitted.

Object oriented programming implies certain contracts that the compiler enforces that are not enforced with data abstraction. Given that object oriented programming and data abstraction two live side by side in C++, we can spot the differences between member functions that have contracts enforced, and members function pointers that do not. Member functions have an implicit this pointer, and in a derived class, can ca…

So you can opt out or in to syntactic sugar, that makes C++ an interesting and useful language, but how you implement OOP, doesn't really affect if it is OOP.

By this logic, C is an objective oriented language. It is widely held to not be. That is why there were two separate approaches to extend it to make it object oriented, C++ and Objective-C.

Re: Object-oriented design patterns in C and kernel development

#82

Earlier quoted context omitted.

Agreed, one of the biggest design mistakes in the OOP syntax of C++ (and Java, for that matter) was not making `this` mandatory when referring to instance members.

C++ and Java went for the "objects as static closures" route, where it doesn't make any sense to have a `this`. Or, they made them superficially look like static closures, which in hindsight was probably not the best idea. Anyway, Java lets you use explicit `this`, I don't recall whether C++ makes it into a footgun or not.

Both languages let you use explicit `this` but don’t mandate it. The “static closure” approach is great. I don’t like having to explicitly pass `this` as a parameter to every method call as in the OP (or worse, the confusing Python approach of forcing `self` to be explicitly written in every non-static method signature but having it be implicitly passed during method calls).

What I don’t like is being able to reference instance members without `this`, e.g.

   void foo() {
      int x = bar + 1; // should be illegal: it can be hard to distinguish if `bar` is a local variable versus an instance member
      int y = this->bar + 1; // disambiguation is good
   }

Re: Object-oriented design patterns in C and kernel development

#83
post #65

Earlier quoted context omitted.

Member function pointers and member functions in C++ are two different things. Member function pointers are not OOP. They are data abstraction. The entire point of OOP is to make contracts with the compiler that forcibly tie certain things together that are not tied together with data abstraction. Member functions are subject to inheritance and polymorphism. Member function pointers are not. Changing the type of your…

Yeah, but the compiler implements these by adding vtables, propagating vtables values across inheritance hierarchies, adding another parameter. You claim when the compiler does this, it's OOP, but when I do it, it's not?

The entire point of OOP in every OOP language that I have ever used has been to have the language try to constrain what you can do by pushing restrictions on syntactic sugar involving objects, inheritance and encapsulation, so I would say yes. The marketing claims that people will be more productive at programming by using these.

Re: Object-oriented design patterns in C and kernel development

#84
post #77

Earlier quoted context omitted.

I don't quite agree, especially because the implicit this not only saves you from explicitly typing it, but also because by having actual methods you don't need to add the struct suffix to every function. mystruct_dosmth(s); mystruct_dosmthelse(s); vs s->dosmth(); s->dosmthelse();

My problem with implicit this is more, that you can access member variables, without it being explicit, i.e. about the callee, not about the caller. For the function naming, nothing stops you from doing the same in C: static dosmth (struct * s); s->dosmth = dosmth; That doesn't stop you from mentioning s twice. While it is redundant in the common case, it isn't in every case like I wrote elsewhere. Also this is easil…

This is not the same, you introduced dynamic function resolution (i.e.a function pointer tied to a specific instance), we are talking about static function resolution (purely based on the declared type).

Re: Object-oriented design patterns in C and kernel development

#85
post #81

Earlier quoted context omitted.

So you can opt out or in to syntactic sugar, that makes C++ an interesting and useful language, but how you implement OOP, doesn't really affect if it is OOP.

By this logic, C is an objective oriented language. It is widely held to not be. That is why there were two separate approaches to extend it to make it object oriented, C++ and Objective-C.

You can implement OOP in C as you can in any language, the article is an example of this. C is not an OOP language in any way, it doesn't have any syntactic features for it and use the term "object" for something different.

Re: Object-oriented design patterns in C and kernel development

#86
post #83

Earlier quoted context omitted.

Yeah, but the compiler implements these by adding vtables, propagating vtables values across inheritance hierarchies, adding another parameter. You claim when the compiler does this, it's OOP, but when I do it, it's not?

The entire point of OOP in every OOP language that I have ever used has been to have the language try to constrain what you can do by pushing restrictions on syntactic sugar involving objects, inheritance and encapsulation, so I would say yes. The marketing claims that people will be more productive at programming by using these.

Yes, you need to have that to have an OOP language. OOP is object-oriented _Programming_, it's about how you program, not what features the language has.

Re: Object-oriented design patterns in C and kernel development

#87
post #61

Earlier quoted context omitted.

> This technique predates object oriented programming. I would rather say that OOP is a formalization of predating patterns and paradigma.

OOP cannot be a formalization of what predated it because the predating patterns support things that OOP explicitly disallows, like instantiation with unimplemented functions. That is extremely useful when you want to implement an optional function, or mutually exclusive functions such that you pick which is optional. This should be the case in the Linux VFS with ->read() and ->read_iter(). Also, ASTs were formalized…

OOP does not disallow instantiation with unimplemented functions, it's just an artefact of implementation in some languages.

Re: Object-oriented design patterns in C and kernel development

#88
post #84

Earlier quoted context omitted.

My problem with implicit this is more, that you can access member variables, without it being explicit, i.e. about the callee, not about the caller. For the function naming, nothing stops you from doing the same in C: static dosmth (struct * s); s->dosmth = dosmth; That doesn't stop you from mentioning s twice. While it is redundant in the common case, it isn't in every case like I wrote elsewhere. Also this is easil…

This is not the same, you introduced dynamic function resolution (i.e.a function pointer tied to a specific instance), we are talking about static function resolution (purely based on the declared type).

True, if you don't trust the compiler to optimize that, then you must live with the C naming.

Re: Object-oriented design patterns in C and kernel development

#89
post #65

Earlier quoted context omitted.

Member function pointers and member functions in C++ are two different things. Member function pointers are not OOP. They are data abstraction. The entire point of OOP is to make contracts with the compiler that forcibly tie certain things together that are not tied together with data abstraction. Member functions are subject to inheritance and polymorphism. Member function pointers are not. Changing the type of your…

Yeah, but the compiler implements these by adding vtables, propagating vtables values across inheritance hierarchies, adding another parameter. You claim when the compiler does this, it's OOP, but when I do it, it's not?

Ìf you do it, it can still be OOP, its just not in an OO language. People have trouble separating using a paradigm and using a language focused on the paradigm, for some reason.

Re: Object-oriented design patterns in C and kernel development

#90

Earlier quoted context omitted.

Agreed, one of the biggest design mistakes in the OOP syntax of C++ (and Java, for that matter) was not making `this` mandatory when referring to instance members.

C++ and Java went for the "objects as static closures" route, where it doesn't make any sense to have a `this`. Or, they made them superficially look like static closures, which in hindsight was probably not the best idea. Anyway, Java lets you use explicit `this`, I don't recall whether C++ makes it into a footgun or not.

this in C++ is just a regular pointer, it has no special footguns, just the typical ones you have with pointers in general
Post reply on HN