0

To my understanding, C does not have the concept of objects, then how can Python be implemented in C to support something that C can not? How is the concept of "Object" modeled in C? What is internally used?

Edit : Reading through the comments, I am interested in this specific implementation of Python which "uses" C to make the whole thing work. More specifically how is a python "object" represented in C.

As an example in comments, something like a Banking System can use "Classes" to model it, like so how can C model the Python concept of Object.

Christophe
  • 74,672
  • 10
  • 115
  • 187
Alice
  • 39
  • 5
  • If this is not the correct place to post, I will remove the question and post it on the appropriate site, let me know – Alice May 23 '21 at 08:58
  • 3
    Python isn't written in C. Python is a programming language, a programming language is an abstract mathematical idea. [It is written in English](https://python.org/dev/peps/). – Jörg W Mittag May 23 '21 at 09:35
  • 9
    Python doesn't have the concept of bank accounts, then how can a banking system be written in Python? – Jörg W Mittag May 23 '21 at 09:39
  • @JörgWMittag I fail to understand how the link you gave answers my question, while I do find the "It is written in English" snarky, I appreciate you taking time to comment on this – Alice May 23 '21 at 09:51
  • How was the compiler for the first object oriented language written? – James McLeod May 23 '21 at 09:51
  • 1
    @JamesMcLeod I am now convinced this is a broad question to be answered and I will remove this question soon – Alice May 23 '21 at 09:55
  • 1
    @JörgWMittag to answer your question on banking system, I would probably tell I would use "classes" to model the system, the point behind my question was what is internally used, and your comment was rather pointless to me, or its just that I do not have enough understanding of the concept, which I have mentioned in the question but was edited out – Alice May 23 '21 at 10:00
  • Does this answer your question? [Why is Python written in C and not in C++?](https://softwareengineering.stackexchange.com/questions/20988/why-is-python-written-in-c-and-not-in-c) – Christophe May 23 '21 at 10:05
  • 1
    Again, Python is a *programming language*. It is an abstract mathematical idea. There is no such thing as "internally". There is a document, written in English, which specifies what an object is and how it should behave. That is the closest thing to "internals" you will get for *any* programming language. – Jörg W Mittag May 23 '21 at 10:07
  • 2
    @JörgWMittag Interestingly, a couple of years ago, you just answered very similar questions, without playing with the words (see proposed duplicate). – Christophe May 23 '21 at 10:07
  • 1
    @Christophe: That question is not about the *programming language* Python, but about the *implementation* CPython (which sometimes confusingly is also called "Python"). A programming language and a programming language implementation are two completely different things, on two completely different levels of abstraction. – Jörg W Mittag May 23 '21 at 10:09
  • thanks for the link @Christophe that answers some of my questions, though it does not exactly explain how Python objects are used or modeled in C, and yes, by write I mean whatever it is the correct terminology for "making a computer language" which apparently was something the other user did use in their earlier answer – Alice May 23 '21 at 10:10
  • @Alice Welcome on Se ! your question if perfectly founded and legitimate. I nevertheless propose to close it in view of an existing very similar question. Btw, I‘d suggest to slightly change the wording following Jörg’s founded remark, to make a difference between the language itself and its implementations by popular environments, interpreters, compilers and transpilers. (I.e some implementation may use C, but it‘s conceivable to have also C#, java, js or even python implementations as well) ;-) – Christophe May 23 '21 at 10:15
  • 1
    @Alice if the other answer does not fully address your question, I‘d the suggest to edit it to make clear what specific part you‘re interested in (yes, you told in the comments, but most readers vote/answer after having read the question without necessarily going through all the comments). – Christophe May 23 '21 at 10:19
  • @Christophe thank you for explaining where I went wrong, I believe the new edit will suffice? – Alice May 23 '21 at 10:19
  • 2
    @JörgWMittag Yes I know. I do not disagree with your point (see how I talked about your remark with Alice for advice). Most of the people make intuitively the difference between a language specification and an implementation, but are not necessarily used to express ot clearly in the wording ;-) – Christophe May 23 '21 at 10:21
  • 1
    An object is just a piece of memory. Python may be seen as a syntactic sugar around the memory management. – Shadows In Rain May 23 '21 at 10:30
  • How can Photoshop, which supports cropping, be implemented in a programming language that does not support cropping? – JoelFan May 26 '21 at 06:16
  • Idk if I really understand your concern. A python class is just a hash map with some syntax sugars. – Tâmer Cuba May 28 '21 at 14:00
  • 1
    @JoelFan a different user has already commented what you said but with a different scenario, my question is "how is a python "object" represented in C", which was answered by a different user in the answer section – Alice May 30 '21 at 04:28

2 Answers2

14

Higher level abstractions are routinely implemented with lower level building blocks.

For example, C higher level language constructs are themselves implemented with lower level assembler instructions. And the same applies to object orientation, which is often implemented with non-object oriented techniques.

Objects are made of data and behavior. C does not know objects, but it knows data structures and functions:

  • To implement "methods" that would operate on data structures in C, to emulate basic object orientation, you can define C functions that take a pointer to the data structure as one of their argument (usually the first). Of course, doing this manually is not practical, and you can easily forget to call the method to initialise an object that was just allocated. But if you have a compiler, it's easy to make sure that this is done systematically. It's also easy for to transform a call such as a.do_something(b,c,d) into do_something(a,b,c,d).

  • To implement methods that change depending on some condition, in C you can use function pointers. A function pointers can point to any function that have a given "signature" (i.e. return type and argument with types). This allows to implement some dynamic dispatching such as what is needed for polymorphism. It is then easy to enrich the inital data structure with some function pointers. Or to enrich it with a pointer to another datastructure that holds the name and function pointer of each relevant method corresponding to a guiven class

  • If the language implemented allows functions/methods with variable number of arguments, you could opt for reduced number of arguments in C, such as the pointer to the data structure holding the object's data, a pointer to a list of arguments.

  • If the language implemented allows for dynamic typing, all method arguments discussed so far would simply be a data structure that holds information about the type of the data, and the data itself, i.e. in C a pair of pointers to different structures).

  • If you need to allow inheritance and multiple inheritance, it gets tricky, but you would work either on generating a composed data structures, or organise the data structure with some pointers that point to a parent object, along with the code to properly access the data following the chain.

  • And for every other language construct, there is probably already a solution. Because ultimately, the thing will run on a microprocessor with very low-level elementary machine instructions.

Christophe
  • 74,672
  • 10
  • 115
  • 187
  • 2
    your first line was all that I needed to relate with to understand, the rest of the answer is unfortunately above my understanding as of now, but I will surely return to this answer when I understand more about programming, many thanks for answering this whilst also pointing out in a nice manner in comments :) – Alice May 23 '21 at 10:51
  • 2
    This is an excellent answer. To my mind the only thing that isn't made clear to @Alice, is an example how an "object" is actually laid out in memory, including the vtables. Whereas OO languages tend to portray objects misleadingly as things that contain both fields and methods, in fact what exists are methods which operate on objects of the given *class* (i.e. the methods exist once in memory for each class), and then there are structures which represent each instantiated object, and which contain both the explicit fields of that instance, and contain... (1/2) – Steve May 23 '21 at 12:53
  • 2
    ...a further set of fields (which in OO languages are not visible or explicit) which are *pointers* to the class methods. The "object constructor" which is called once when each instance is created, contains logic (again, not visible or explicit in the OO language itself) which wires up these implicit instance fields, so that they point to the class methods. Every object goes through this hidden "wiring-up" process. (2/2) – Steve May 23 '21 at 12:53
  • 1
    @Steve thanks for this feedback and the suggestions. I hesitated to provide some more information about the memory layout, and. tables. I considered providing a link to the first article mentioned in [this answer on so](https://stackoverflow.com/a/30878954/3723423). But I thought that this might be too specific for C++ and not necessarily be transposable as such to python. And thank you also for pointing out that data+functions is necessarily simplified, as it does not take into account accessibility. [Object composition](https://en.m.wikipedia.org/wiki/Object_composition) is indeed… (1/2) – Christophe May 23 '21 at 13:14
  • 1
    @Steve … a little bit more subtle (and powerful). I used the data+function viewpoint mainly to address the low-level implementation considerations. But you‘re right: this implementation consideration should not mislead Alice to get fundamental OOP principles wrong – Christophe May 23 '21 at 13:19
  • thank you for the comments @Steve, also I now have enough rep to upvote this answer, hope that helps – Alice May 24 '21 at 01:08
  • @Steve What's interesting to me about Python in this context is that it exposes the reality of the data/logic separate that you are referring to by making the `self` parameter explicit as opposed to an implicit `this`. – JimmyJames May 27 '21 at 19:51
3

TL;DR: different level of abstractions. There is really no such thing as an object, there are just 1’s and 0’s and interpretations of them.

The CPU doesn’t know about objects, so the same question would apply for it: how can you you have a compiler for a language with objects, when the CPU it targets doesn’t know about objects? And the answer is the same, objects are an abstracts where data and functions are bound together by a convention/standard and it is this convention/standard that really defines an object. While the standard isn’t defined in C, C is able to create an implementation of this standard.

This is in fact how C++ and Obj-C were first created. C was a good choice for doing this, because of its cross platform support and hardware support. This made it possible to write a C++ compiler that not only ran on many different platforms, it also compiled for the many different platforms.

To go back to the CPU example, the CPU doesn’t even know about strings, it just knows about bytes, typically having a register size of 1, 2, 4 or 8 bytes. How can it deal with strings? Easy, it doesn’t. The compiler has a convention/standard that it imposes on itself. Strings in C are really just null terminated chunks of memory. In Python, a string is a variable sized structure that takes 49 to 80 bytes in memory PLUS the chunks of memory that is the “characters”. But all of this is totally irrelevant to the CPU. A python programs “strings” aren’t going to be C strings even though the program is compiled to C, because when the code is compiled to C it isn’t going to use the C conventions for strings when dealing with python strings, it will use python conventions, executed in C.

jmoreno
  • 10,640
  • 1
  • 31
  • 48
  • 3
    The first C++ compiler I used was CFront which translated C++ into C. Which was then compiled by the C compiler. That was before exceptions, which would be non-trivial to translate into plain C. – gnasher729 May 23 '21 at 18:38
  • thank you for this explanation, it helps a lot with my understanding – Alice May 24 '21 at 01:25