Hacker News new | past | comments | ask | show | jobs | submit login

Which is funny because I could never get anyone, when I first started programming in C and everyone was raving about how great 'object oriented programming' was, to tell me what 'an object' actually was. When I started learning C++ I was somewhat disappointed to find out an object was just a struct with some functions attached.

(It's kind of like when people told me about "user defined data types" and I couldn't wrap my head around how you could create a new data type with all its associated syntax. Then when I learned that they were just bundles of existing data types, though 'oh is that all?')




> I was somewhat disappointed to find out an object was just a struct with some functions attached

> when I learned that they were just bundles of existing data types, though 'oh is that all?'

Uh-huh. When I learned how everything just translates to 0s and 1s in the end, I was also super "disappointed". Higher-level constructs and abstractions are new compositions of lower-level building blocks? How.. plain!


And all those zero and ones are still translated into electrons. Decomposing abstractions is often not very useful.


And who says electrons exist as physical objects. They're just a mathematical abstraction physicists use to predict the results of experiments.


Then you will see it is not the bit that flips, it is only yourself.


They should put that in the 101 textbooks, so we won't waste decades writing billions of LoC!


The irony being that the spoon was CGI and hence composed entirely of bit flips.


Think about the difference between an int and a string, or a string and a function pointer. Now think about the difference between an int and a pair of ints. See?


I love OO - but C++s objects are so bad that most of the time I just end up using functions-where-the-struct-is-the-first-argument, C style. If I'm feeling particularly energetic I might use the PIMPL idiom. But naiive use of C++ objects is absolutely painful for me.

All language constructs can be broken down into simpler ones, at the end of the day. We might talk about how subroutines are just overrated assembler macros. C++ isn't very clean so the fact that these fancy schmancy objects are just structs + function pointers is very obvious. But when done cleanly, I'd argue that an object is more powerful than the sum of its parts.


"Actually I made up the term "object-oriented", and I can tell you I did not have C++ in mind" - Alan Kay


Good thing then that Stroustrup didn't have Smaltalk in mind when he designed the C++ object model. He based it on Simula which predates Smaltalk.


> I just end up using functions-where-the-struct-is-the-first-argument, C style.

I've been saying this for a while: of all C++/Java-style OOP we're mostly saving uniform function call syntax (cf. go, rust, nim, D and a bit C++17) !


But when done cleanly, I'd argue that an object is more powerful than the sum of its parts.

I think I agree with your assessment of C++. What languages do you feel deal cleanly with objects so they exceed the sum of the parts?


Honestly pretty much all of them if C++ is your reference point. Java, C#, Scala, Ruby, Ocaml...


I've seen objects recreated in Scheme and Clojure. They are really much more common than most FP people appreciate, just look for noun-ish naming conventions in your abstractions.


It's controversial for some people. OO is that horrible verbose enterprise code with all the mutable state. And if you suggest that certain features or patterns approximate OO they get very defensive.

There are certain famous FP language implementers that should probably read what Guy Steele wrote in the topic, because listening to their talks I strongly get the impression they haven't.


One could also just use a synonym of object, like "entity." "Hey...we aren't using objects here, we are using entities!" (Facepalm)

I saw Guy's growing a language talk before, but I don't think he's ever chimed in on this debate before. Most people at his level simply except the world without much bias, and are comfortable using object and functional styles when necessary.


C++s objects are so bad that most of the time I just end up using functions-where-the-struct-is-the-first-argument, C style

Can you explain more in depth why exactly? Is it because of e.g. http://stackoverflow.com/questions/5989734/effective-c-item-...? Or just not liking the syntax? Or private members?


High-school-me bounced off several Java and C++ books with their stupid "sally wants to buy flowers and john's flower shop" explanations of objects were before finally realizing, while using an OO PHP library, what was actually going on. Felt like people'd been deliberately obtuse to keep me from learning. "It's just structs with functions attached and a couple reall-easy-to-explain sugary features on top" would have been much better.


> Felt like people'd been deliberately obtuse to keep me from learning.

When I get that feeling, what's really happening 99% of the time is that the person trying to explain actually has no idea what they're talking about, but doesn't want to admit it.

If you understand a concept well enough, you can explain it simply and succinctly (barring things like really esoteric maths/physics, but nothing in computing is that difficult in my experience).


I will be forever grateful that an appendix to one of the Turbo Pascal manuals described exactly how objects were laid out in memory (including function pointers).


Turbo Pascal's manuals came with a separate volume dedicated solely to OOP. It's one of the best technical manuals I've ever read. Beautifully typeset, too [1]. Borland's technical documentation was really, really good at that time.

[1] ftp://bitsavers.informatik.uni-stuttgart.de/pdf/borland/turbo_pascal/Turbo_Pascal_Version_5.5_Object-Oriented_Programming_Guide_1989.pdf


Looks like what I was remembering as being an appendix was actually the last chapter of that volume: "Inside Turbo Pascal"


> Felt like people'd been deliberately obtuse to keep me from learning.

Well, that's one way to put it. What's really going on is they are trying to describe an abstraction from a user's perspective. So you could say the point of abstraction is to be "deliberately obtuse" in a productive and healthy way.

It's also common for people to try and fail to abstract things. Bad abstraction can be a net negative. It's likely that was what happened here.

And, to agree with you, OOP as a taxonomy of physical objects is both a pervasive and a bad idea. The point of classes and objects is to group data and functionality together. The things you do with a "Rose" may or may not look like the things you do with a "Cactus". Forcing them into the same hierarchy of behaviors because they are both "Plants" is injecting extra requirements into the system.


Yeah, honestly, I think I didn't "get it" until I read about vtables and the use of ecx as the "this" pointer while learning reverse engineering.

I think I struggle to learn a lot of functional programming concepts now because it's even more distant and abstract explanations.


I think I struggle to learn a lot of functional programming concepts now because it's even more distant and abstract explanations.

I've come across this a lot. Some people (like you perhaps) view computing in terms of machines, and others in terms of mathematics and formalism. (I'm lazy and lack principle, so I will go with whatever interpretation is easiest.) FWIW, I've met at least one incredibly smart person from both camps.

If you're into compilers at all, you might appreciate this[1] - how the "machine tribe" and "lambda tribe" view the same thing.

[1] https://wingolog.org/archives/2011/07/12/static-single-assig...


I understand the feeling, but object inheritance goes a bit beyond this model, doesn't it?

You could have, through some convention, the inheritance tree encoded into structs, but that's true of every language feature really. At no point do mots language feature stop being "structs + functions", because that encodes data + code.


My experience with inference-based programming does deviate some from that model. Data is scattered throughout a knowledge base in individual data points & statements, and only the current ephemeral binding set is the organizational glue that gathers the data together for operation.

Structs and OO by contrast could be considered as premature composition. ;-)


Inheritance = nested structs


Well, it's nested structs whether you like it or not. There are pros (no messing with private state in new and untested ways) and cons (you get all the private state even if you only need the one boolean) associated.


What if you needed to use complex numbers, and your language only supports ints and floats? Is the library or class used to implement the complex data type just a bundle of existing types?


Well, yeah. Usually somewhere in there it'll have

    class Complex {
        double real;
        double imaginary;
    }
Or similar. Maybe template it so you can have a Complex<double> instead. It's still fundamentally a combination of existing types.


That doesn't change the usefulness of being able to create new data types from existing ones. With operator overloading or operators as methods, you can treat user your new data types as primitives.

That's very convenient when you want your complex numbers to work just like ints and floats.


I didn't mean to say it's not useful, just that it's much simpler than actually defining a new primitive type, which is how I originally interpreted the term.


Yes. There aren't to my knowledge any CPUs with special instructions for complex numbers, they're implemented as wrappers ontop of the standard stuff.


If we're talking about CPUs, then structures and functions are just bundles of existing bit patterns and machine instructions.

Reducing things to just their primitives ignores how useful abstractions are for humans. Not everyone thinks it's a good use of their time to reinvent classes & objects or closures with structures and function pointers. Thus why those abstractions are part of so many programming languages (to answer the expressed bafflement one level above my initial reply).

Some C or assembly fans act like abstractions should end at that level, for some strange reason.


I didn't say anything about it not being a useful abstraction, just that it is essentially just an abstraction.


ARM has special instructions for complex numbers[1]. Modern CPU architectures usually have vector instructions which should cover most common complex number operations as well.

[1] Look for the instructions prefixed with FC = Floating-point Complex

https://developer.arm.com/docs/dui0801/latest/a64-simd-vecto...


> There aren't to my knowledge any CPUs with special instructions for complex numbers

There are lots of processors out there besides CPUs. You could even design a new processor or program an FPGA to do complex math. Fast Fourier transforms deal with imaginary math, for example. You can do those in a number of ways, including on a CPU or GPU, but it's not unheard of for companies to use either custom hardware or programmable hardware to meet performance needs.


Intel CPUs have specific vector instructions specifically meant to accelerate operations on complex numbers (ADDSUBPS for example).


> Then when I learned that they were just bundles of existing data types, though 'oh is that all?'

You don't have to use existing data types when defining your own if you really don't want to. It's not 'just' that, it's about setting up your own behavior.


Well, to be fair, "objects" as originally envisioned were not like C++ implemented it.

The guy that invented OOP is on record as saying that.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: