Object-oriented Eureka! moment

Fair warning: This is going to be a long one, with some musings about how to approach the idea of introducing objects. It’s based around my personal experiences teaching myself Processing and observations in the wider Processiverse (Yes, I’m coining that term). As for a desired outcome, I’m not sure. Just initiating a discussion would be a good start.

I’ll also frame everything by saying that I’m thinking more about artists and designers venturing into creative coding, as opposed to people who are on a CS track. I’m thinking mainly in terms of visual output and not data manipulation.

(Also, I’m not sure about what category this post fits in best. Mods, do your thing.)

///

I’ve forever been intrigued by object-oriented programming, for three main reasons:

  1. It’s so darn powerful and unlocks a whole new level in my coding capabilities.
  2. It’s this massive complexity spike which sneaks up on you after you’ve put down some coding foundations. The spike feels completely disproportional to what people learn up to that point and from my own observations can be a real reason why one might completely lose interest in pursuing creative coding any further.
  3. I’ve yet to find an educational resource which manages to effectively prime a pupils brain to voluntarily put in effort to learn more about objects.

My thoughts revolve around points 2 and 3.

As a representative example I’m using the Objects tutorial from the Processing website. Let me state that far more than half of the things I know about and can do with code is thanks to Dan. But I’m convinced this tutorial is still missing a vital point.

It teaches you all the correct things about the concept behind a class/object, it’s building blocks and how you might transfer your previous code into object form.

But it fails to answer the question “Why put in the effort?”.

Put yourself into the shoes of a beginner/intermediate coder.

They have understood variables, basic datatypes, fought with arrays, created a custom function, steered the flow within a sketch, drawn smiley faces onto the screen.

And now the instructor tells them that objects are this powerful thing that will unlock their next level. And then a ton of foreign concepts rain down onto this pupil. “Blueprint”? “Cookie cutter”? Class? Object? Constructor? Fields? Functions are now methods? set? get? Even distant whispers of Inheritance and Polymorphism.

To the pupil it feels like they have to put in effort to write more code, FOR THE SKETCH TO DO THE EXACT SAME THING afterwards.

So why write more complex lines of code with no obvious advantage to it? That Objects tutorial, as most others, are guilty of this. They demand that the pupil trusts that the upfront effort will produce a payout sometime down the line.

I’m here to propose that we can incorporate part of that payout right at the start of an OOP jounrney.

Let’s take this baseline sketch from the tutorial:

color c = color(0);
float x = 0;
float y = 100;
float speed = 1;

void setup() {
  size(200,200);
}

void draw() {
  background(255);
  move();
  display();
}

void move() {
  x = x + speed;
  if (x > width) {
    x = 0;
  }
}

void display() {
  fill(c);
  rect(x,y,30,10);
}

Now instead of the tutor starting to introduce the concept of an object and refactoring the code, he gives the following task: “Rewrite the sketch to have two cars move on screen”.

After some thinking and code wrestling, the pupil will come up with this:


// car1 variables
color c1 = color(0);
float x1 = 0;
float y1 = 100;
float speed1 = 1;

// car2 variables
color c2 = color(125);
float x2 = 0;
float y2 = 50;
float speed2 = 1.5;

void setup() {
  size(200,200);
}

void draw() {
  background(255);
  
  // draw car1
  move1();
  display1();
  
  // draw car2
  move2();
  display2();
}

void move1() {
  x1 = x1 + speed1;
  if (x1 > width) {
    x1 = 0;
  }
}

void move2() {
  x2 = x2 + speed2;
  if (x2 > width) {
    x2 = 0;
  }
}

void display1() {
  fill(c1);
  rect(x1,y1,30,10);
}

void display2() {
  fill(c2);
  rect(x2,y2,30,10);
}

This is not a good solution, but a solution the pupil will be able to come up with and understand based on their coding level.

“Right”, says the tutor, “now make it three cars”. The pupil, smart as they are, have already identified the pattern. So they copy all relevant parts and add a ‘3’ into all the correct places. The sketch is becoming slightly unwieldy, but it works.

“Neat” goes the tutor ”and in the next step…”, “we draw four cars!” interrupts the pupil giddily.

“No”, says the tutor. “Make it one thousand cars”.

This is the moment the pupil falls off their chair, because it’s fully apparent that this is a ridiculous ask. Their way of thinking about code structure has reached an obvious limit and being a typical pupil, they will beg for a solution that requires way less effort to implement.

Now the tutor goes: “What if I told you, there’s a way you can build your code, in which you can easily change the number of the cars, to anything you want? It just requires some setup first. Let me show you".

The tutor presents an OOP sketch with a “numCars” variable set to 3. Then changes the variable to 1000. Then to 10000. And it just works, only by changing one single value. The best part: The whole sketch is way shorter than what the pupil had in mind as a solution.

This is also the point where the Object tutorial enters that conversation and introduces all the details about this still complex, but obviously mighty concept of an object. With the main difference, that the pupil will now be operating with a clear proof on the power of adding that initial complexity.

///

Yeah, that’s it. Sorry for making it ramble-y. Looking forward to any feedback and counters.

6 Likes

Besides the “official” tutorials, this old “forum” FAQ has some technical articles for common problems that beginners may encounter in Processing: frequently-asked-questions

A simpler way to think about OOP in general is that arrays or lists are a way to make the same variable store multiple values: from-several-variables-to-arrays

And classes and structs are a neat way to turn multiple related arrays into 1 single array: from-several-arrays-to-classes

And methods are just functions that are specialized in dealing w/ the properties or fields of a class.

4 Likes

I’m absolutely getting a kick out of the fact that PhiLho’s and my chain of reasoning both use the exact same “1, 2, 3, many” structure. Tells me that I’m not completely off. With the tiny difference that PhiLho’s tutorial is several magnitudes more detailed, educationally sound, and content-dense than my wild thought-puddle.

So now we have this resource, an article from 2014 in a forum that’s been replaced. It’s good that I can point learners to that resource when I see them struggling. I just wish that this content or general approach is more wide-spread and surface-able.

2 Likes

Yes…

object oriented programming…

It’s useful, but when I watch myself using it, I only use it to a certain extend.

For example in a Pong Game I would use it for player and ball but not for the Game logic or the program logic (states of the program).

I tried having a class for each state of the program. But then you need an additional class for all shared data that are used by the different classes together. That’s fine but it’s a bit abstract.

But I feel classes only take you this far when it comes to more complex programs. We need more tools there!

You can structure the code additionally by using tabs.

2 Likes

What do these programming languages have in common?
C
Visual Basic
Pascal
PHP
JavaScript
They all started as modular programming languages but were later upgraded to include OO programming features. I think that shows the usefulness of the Object Orientation paradigm.

As many of you have probably guessed I have a CS background which helps me get the most out of OOP. In fact all of my Processing libraries and tools were designed and created on the principles of OO, including canvasGUI my first JavaScript library.

Using OO is not just about using new programming syntax it changes how you think, approach, design and create your program. This is the biggest challenge to non CS users.

Finally I must say that despite my programming skills I have no artistic talent whatsoever and I stare in awe at some of the most incredibly beautiful displays produced by other Processing users. :+1:

5 Likes

There’s certainly different ways to utilize OOP. I’m squarely with @Chrisir on this one. If I have a visual elements – a Mover, Agent, Particle, Path, etc. – I wrap it up into a class. Anything else, like the logical structure of a sketch, I do the “non-OOP” way.

I recently built a larger sketch leaning heavily into ChatGTP and when I prompted it to “clean up and restructure” my code, it introduced a Config class. And a Controller and a Scene1. This felt very mature, coding-wise. And then ChatGPT immediately forgot about these structural changes and ignored anything about it moving forward, even when being reminded. On my own, I did expand on the Config class and also thought about having additional scenes. And then I realised that this was massive overhead for what I was trying to achieve, with no immediate benefit. I eventually got rid of Config and went back to good old globals. And I got rid of Controller and Scene, with no replacement.

I understand that those structures have their place. But I also need to keep reminding myself that what I’m building with Processing just needs to be good enough to run and produce a visual output. The sketch being held together by digital duct tape, so to speak. I’ll also readily admit that when using OO, my practices are severely lacking. Anybody with a background in CS would shake their head sadly at my code.

All the CS virtues for good code – robustness, security, maintainability, scalability, testability, extensibility, modularity, etc. – don’t play any relevant part when I write a sketch. Even performance considerations are mostly moot, thanks to an overabundance of processing power. I do ignore this because I’m building neat-looking prototypes, bringing my visual ideas to live. I’m not building system-vital, data-crunching, corporate applications that get deployed in the real world. And I never intend to. That’s what the experts are for.

I fear I’m sounding somewhat flippant here. I’m just scaling my effort (and care) because I know what my sketches are. And what they aren’t.

3 Likes

That’s exactly where Java is most used for. :coffee:

2 Likes